2019-04-19 18:48:37 +00:00
using System ;
2019-04-26 15:14:20 +00:00
using System.Linq ;
using System.Runtime.Serialization ;
2019-04-19 18:48:37 +00:00
using System.Threading.Tasks ;
using Dapper ;
using Discord.Commands ;
2019-04-21 13:33:22 +00:00
namespace PluralKit.Bot.Commands
2019-04-19 18:48:37 +00:00
{
[Group("system")]
public class SystemCommands : ContextParameterModuleBase < PKSystem >
{
public override string Prefix = > "system" ;
2019-04-27 14:30:34 +00:00
public override string ContextNoun = > "system" ;
2019-04-19 18:48:37 +00:00
public SystemStore Systems { get ; set ; }
public MemberStore Members { get ; set ; }
2019-04-21 13:33:22 +00:00
public EmbedService EmbedService { get ; set ; }
2019-04-19 18:48:37 +00:00
2019-04-21 13:33:22 +00:00
[Command]
2019-04-26 15:14:20 +00:00
public async Task Query ( PKSystem system = null ) {
2019-04-21 13:33:22 +00:00
if ( system = = null ) system = Context . SenderSystem ;
2019-04-29 17:43:09 +00:00
if ( system = = null ) throw Errors . NotOwnSystemError ;
2019-04-21 13:33:22 +00:00
2019-04-25 16:50:07 +00:00
await Context . Channel . SendMessageAsync ( embed : await EmbedService . CreateSystemEmbed ( system ) ) ;
2019-04-21 13:33:22 +00:00
}
2019-04-19 18:48:37 +00:00
[Command("new")]
2019-04-29 15:44:20 +00:00
[Remarks("system new <name>")]
2019-04-26 15:14:20 +00:00
public async Task New ( [ Remainder ] string systemName = null )
2019-04-19 18:48:37 +00:00
{
2019-04-29 17:43:09 +00:00
if ( ContextEntity ! = null ) throw Errors . NotOwnSystemError ;
2019-05-11 21:56:56 +00:00
if ( Context . SenderSystem ! = null ) throw Errors . ExistingSystemError ;
2019-04-19 18:48:37 +00:00
var system = await Systems . Create ( systemName ) ;
2019-04-21 13:33:22 +00:00
await Systems . Link ( system , Context . User . Id ) ;
2019-04-27 14:30:34 +00:00
await Context . Channel . SendMessageAsync ( $"{Emojis.Success} Your system has been created. Type `pk;system` to view it, and type `pk;help` for more information about commands you can use now." ) ;
2019-04-19 18:48:37 +00:00
}
[Command("name")]
2019-04-29 15:44:20 +00:00
[Remarks("system name <name>")]
2019-04-29 17:43:09 +00:00
[MustHaveSystem]
2019-04-26 15:14:20 +00:00
public async Task Name ( [ Remainder ] string newSystemName = null ) {
2019-04-29 18:28:53 +00:00
if ( newSystemName ! = null & & newSystemName . Length > Limits . MaxSystemNameLength ) throw Errors . SystemNameTooLongError ( newSystemName . Length ) ;
2019-04-19 18:48:37 +00:00
Context . SenderSystem . Name = newSystemName ;
await Systems . Save ( Context . SenderSystem ) ;
2019-04-26 15:14:20 +00:00
await Context . Channel . SendMessageAsync ( $"{Emojis.Success} System name {(newSystemName != null ? " changed " : " cleared ")}." ) ;
2019-04-19 18:48:37 +00:00
}
[Command("description")]
2019-04-29 15:44:20 +00:00
[Remarks("system description <description>")]
2019-04-29 17:43:09 +00:00
[MustHaveSystem]
2019-04-26 15:14:20 +00:00
public async Task Description ( [ Remainder ] string newDescription = null ) {
2019-04-29 18:28:53 +00:00
if ( newDescription ! = null & & newDescription . Length > Limits . MaxDescriptionLength ) throw Errors . DescriptionTooLongError ( newDescription . Length ) ;
2019-04-19 18:48:37 +00:00
Context . SenderSystem . Description = newDescription ;
await Systems . Save ( Context . SenderSystem ) ;
2019-04-26 15:14:20 +00:00
await Context . Channel . SendMessageAsync ( $"{Emojis.Success} System description {(newDescription != null ? " changed " : " cleared ")}." ) ;
2019-04-19 18:48:37 +00:00
}
[Command("tag")]
2019-04-29 15:44:20 +00:00
[Remarks("system tag <tag>")]
2019-04-29 17:43:09 +00:00
[MustHaveSystem]
2019-04-26 15:14:20 +00:00
public async Task Tag ( [ Remainder ] string newTag = null ) {
2019-04-29 18:28:53 +00:00
if ( newTag . Length > Limits . MaxSystemTagLength ) throw Errors . SystemNameTooLongError ( newTag . Length ) ;
2019-04-19 18:48:37 +00:00
Context . SenderSystem . Tag = newTag ;
2019-04-26 15:14:20 +00:00
// Check unproxyable messages *after* changing the tag (so it's seen in the method) but *before* we save to DB (so we can cancel)
2019-04-19 18:48:37 +00:00
var unproxyableMembers = await Members . GetUnproxyableMembers ( Context . SenderSystem ) ;
2019-04-26 15:14:20 +00:00
if ( unproxyableMembers . Count > 0 ) {
var msg = await Context . Channel . SendMessageAsync ( $"{Emojis.Warn} Changing your system tag to '{newTag}' will result in the following members being unproxyable, since the tag would bring their name over 32 characters:\n**{string.Join(" , ", unproxyableMembers.Select((m) => m.Name))}**\nDo you want to continue anyway?" ) ;
2019-04-27 14:30:34 +00:00
if ( ! await Context . PromptYesNo ( msg ) ) throw new PKError ( "Tag change cancelled." ) ;
2019-04-26 15:14:20 +00:00
}
2019-04-19 18:48:37 +00:00
await Systems . Save ( Context . SenderSystem ) ;
2019-04-26 15:14:20 +00:00
await Context . Channel . SendMessageAsync ( $"{Emojis.Success} System tag {(newTag != null ? " changed " : " cleared ")}." ) ;
2019-04-19 18:48:37 +00:00
}
2019-04-26 16:15:25 +00:00
[Command("delete")]
2019-04-29 15:44:20 +00:00
[Remarks("system delete")]
2019-04-29 17:43:09 +00:00
[MustHaveSystem]
2019-04-26 16:15:25 +00:00
public async Task Delete ( ) {
var msg = await Context . Channel . SendMessageAsync ( $"{Emojis.Warn} Are you sure you want to delete your system? If so, reply to this message with your system's ID (`{Context.SenderSystem.Hid}`).\n**Note: this action is permanent.**" ) ;
var reply = await Context . AwaitMessage ( Context . Channel , Context . User , timeout : TimeSpan . FromMinutes ( 1 ) ) ;
if ( reply . Content ! = Context . SenderSystem . Hid ) throw new PKError ( $"System deletion cancelled. Note that you must reply with your system ID (`{Context.SenderSystem.Hid}`) *verbatim*." ) ;
await Systems . Delete ( Context . SenderSystem ) ;
await Context . Channel . SendMessageAsync ( $"{Emojis.Success} System deleted." ) ;
}
2019-04-29 15:42:09 +00:00
[Group("list")]
public class SystemListCommands : ModuleBase < PKCommandContext > {
public MemberStore Members { get ; set ; }
[Command]
2019-04-29 15:44:20 +00:00
[Remarks("system [system] list ")]
2019-04-29 15:42:09 +00:00
public async Task MemberShortList ( ) {
var system = Context . GetContextEntity < PKSystem > ( ) ? ? Context . SenderSystem ;
2019-04-29 17:43:09 +00:00
if ( system = = null ) throw Errors . NoSystemError ;
2019-04-29 15:42:09 +00:00
var members = await Members . GetBySystem ( system ) ;
var embedTitle = system . Name ! = null ? $"Members of {system.Name} (`{system.Hid}`)" : $"Members of `{system.Hid}`" ;
await Context . Paginate < PKMember > (
2019-04-29 17:44:17 +00:00
members . OrderBy ( m = > m . Name ) . ToList ( ) ,
2019-04-29 15:42:09 +00:00
25 ,
embedTitle ,
2019-04-29 17:52:07 +00:00
( eb , ms ) = > eb . Description = string . Join ( "\n" , ms . Select ( ( m ) = > {
if ( m . HasProxyTags ) return $"[`{m.Hid}`] **{m.Name}** *({m.ProxyString})*" ;
return $"[`{m.Hid}`] **{m.Name}**" ;
} ) )
2019-04-29 15:42:09 +00:00
) ;
}
[Command("full")]
[Alias("big", "details", "long")]
2019-04-29 15:44:20 +00:00
[Remarks("system [system] list full ")]
2019-04-29 15:42:09 +00:00
public async Task MemberLongList ( ) {
var system = Context . GetContextEntity < PKSystem > ( ) ? ? Context . SenderSystem ;
2019-04-29 17:43:09 +00:00
if ( system = = null ) throw Errors . NoSystemError ;
2019-04-29 15:42:09 +00:00
var members = await Members . GetBySystem ( system ) ;
var embedTitle = system . Name ! = null ? $"Members of {system.Name} (`{system.Hid}`)" : $"Members of `{system.Hid}`" ;
await Context . Paginate < PKMember > (
2019-04-29 17:44:17 +00:00
members . OrderBy ( m = > m . Name ) . ToList ( ) ,
2019-04-29 15:42:09 +00:00
10 ,
embedTitle ,
( eb , ms ) = > {
2019-04-29 17:52:07 +00:00
foreach ( var m in ms ) {
var profile = $"**ID**: {m.Hid}" ;
if ( m . Pronouns ! = null ) profile + = $"\n**Pronouns**: {m.Pronouns}" ;
if ( m . Birthday ! = null ) profile + = $"\n**Birthdate**: {m.BirthdayString}" ;
if ( m . Prefix ! = null | | m . Suffix ! = null ) profile + = $"\n**Proxy tags**: {m.ProxyString}" ;
if ( m . Description ! = null ) profile + = $"\n\n{m.Description}" ;
eb . AddField ( m . Name , profile ) ;
2019-04-29 15:42:09 +00:00
}
}
) ;
}
}
2019-04-19 18:48:37 +00:00
public override async Task < PKSystem > ReadContextParameterAsync ( string value )
{
var res = await new PKSystemTypeReader ( ) . ReadAsync ( Context , value , _services ) ;
return res . IsSuccess ? res . BestMatch as PKSystem : null ;
}
}
}