2019-10-05 05:41:00 +00:00
using System.Linq ;
using System.Threading.Tasks ;
2020-04-24 19:50:28 +00:00
using DSharpPlus ;
2020-05-02 13:33:05 +00:00
using DSharpPlus.Exceptions ;
2019-10-05 05:41:00 +00:00
2020-07-18 10:58:18 +00:00
using Humanizer ;
2020-02-12 14:16:19 +00:00
using PluralKit.Core ;
2019-10-05 05:41:00 +00:00
2020-02-12 14:16:19 +00:00
namespace PluralKit.Bot
2019-10-05 05:41:00 +00:00
{
public class CommandTree
{
2019-11-02 23:29:11 +00:00
public static Command SystemInfo = new Command ( "system" , "system [system]" , "Looks up information about a system" ) ;
public static Command SystemNew = new Command ( "system new" , "system new [name]" , "Creates a new system" ) ;
public static Command SystemRename = new Command ( "system name" , "system rename [name]" , "Renames your system" ) ;
public static Command SystemDesc = new Command ( "system description" , "system description [description]" , "Changes your system's description" ) ;
public static Command SystemTag = new Command ( "system tag" , "system tag [tag]" , "Changes your system's tag" ) ;
2020-07-07 21:41:51 +00:00
public static Command SystemAvatar = new Command ( "system icon" , "system icon [url|@mention]" , "Changes your system's icon" ) ;
2019-11-02 23:29:11 +00:00
public static Command SystemDelete = new Command ( "system delete" , "system delete" , "Deletes your system" ) ;
public static Command SystemTimezone = new Command ( "system timezone" , "system timezone [timezone]" , "Changes your system's time zone" ) ;
2019-12-22 13:15:56 +00:00
public static Command SystemProxy = new Command ( "system proxy" , "system proxy [on|off]" , "Enables or disables message proxying in a specific server" ) ;
2019-11-02 23:29:11 +00:00
public static Command SystemList = new Command ( "system list" , "system [system] list [full]" , "Lists a system's members" ) ;
2020-02-13 15:49:45 +00:00
public static Command SystemFind = new Command ( "system find" , "system [system] find [full] <search term>" , "Searches a system's members given a search term" ) ;
2019-11-02 23:29:11 +00:00
public static Command SystemFronter = new Command ( "system fronter" , "system [system] fronter" , "Shows a system's fronter(s)" ) ;
public static Command SystemFrontHistory = new Command ( "system fronthistory" , "system [system] fronthistory" , "Shows a system's front history" ) ;
public static Command SystemFrontPercent = new Command ( "system frontpercent" , "system [system] frontpercent [timespan]" , "Shows a system's front breakdown" ) ;
2020-03-21 13:04:41 +00:00
public static Command SystemPing = new Command ( "system ping" , "system ping <enable|disable>" , "Changes your system's ping preferences" ) ;
2020-06-17 19:31:39 +00:00
public static Command SystemPrivacy = new Command ( "system privacy" , "system privacy <description|members|fronter|fronthistory|all> <public|private>" , "Changes your system's privacy settings" ) ;
2020-01-23 20:20:22 +00:00
public static Command Autoproxy = new Command ( "autoproxy" , "autoproxy [off|front|latch|member]" , "Sets your system's autoproxy mode for this server" ) ;
2019-11-02 23:29:11 +00:00
public static Command MemberInfo = new Command ( "member" , "member <member>" , "Looks up information about a member" ) ;
public static Command MemberNew = new Command ( "member new" , "member new <name>" , "Creates a new member" ) ;
public static Command MemberRename = new Command ( "member rename" , "member <member> rename <new name>" , "Renames a member" ) ;
public static Command MemberDesc = new Command ( "member description" , "member <member> description [description]" , "Changes a member's description" ) ;
public static Command MemberPronouns = new Command ( "member pronouns" , "member <member> pronouns [pronouns]" , "Changes a member's pronouns" ) ;
public static Command MemberColor = new Command ( "member color" , "member <member> color [color]" , "Changes a member's color" ) ;
public static Command MemberBirthday = new Command ( "member birthday" , "member <member> birthday [birthday]" , "Changes a member's birthday" ) ;
public static Command MemberProxy = new Command ( "member proxy" , "member <member> proxy [add|remove] [example proxy]" , "Changes, adds, or removes a member's proxy tags" ) ;
public static Command MemberDelete = new Command ( "member delete" , "member <member> delete" , "Deletes a member" ) ;
2020-03-04 17:28:13 +00:00
public static Command MemberAvatar = new Command ( "member avatar" , "member <member> avatar [url|@mention]" , "Changes a member's avatar" ) ;
public static Command MemberServerAvatar = new Command ( "member serveravatar" , "member <member> serveravatar [url|@mention]" , "Changes a member's avatar in the current server" ) ;
2019-11-02 23:29:11 +00:00
public static Command MemberDisplayName = new Command ( "member displayname" , "member <member> displayname [display name]" , "Changes a member's display name" ) ;
2019-12-26 19:39:47 +00:00
public static Command MemberServerName = new Command ( "member servername" , "member <member> servername [server name]" , "Changes a member's display name in the current server" ) ;
2019-11-02 23:29:11 +00:00
public static Command MemberKeepProxy = new Command ( "member keepproxy" , "member <member> keepproxy [on|off]" , "Sets whether to include a member's proxy tags when proxying" ) ;
2020-03-04 17:28:13 +00:00
public static Command MemberRandom = new Command ( "random" , "random" , "Looks up a random member from your system" ) ;
2020-06-17 19:51:40 +00:00
public static Command MemberPrivacy = new Command ( "member privacy" , "member <member> privacy <name|description|birthday|pronouns|metadata|visibility|all> <public|private>" , "Changes a members's privacy settings" ) ;
2020-06-29 21:51:12 +00:00
public static Command GroupInfo = new Command ( "group" , "group <name>" , "Looks up information about a group" ) ;
public static Command GroupNew = new Command ( "group new" , "group new <name>" , "Creates a new group" ) ;
2020-07-06 17:50:39 +00:00
public static Command GroupList = new Command ( "group list" , "group list" , "Lists all groups in this system" ) ;
2020-07-07 17:34:23 +00:00
public static Command GroupMemberList = new Command ( "group members" , "group <group> list" , "Lists all members in a group" ) ;
2020-08-27 19:28:54 +00:00
public static Command GroupRename = new Command ( "group rename" , "group <group> rename <new name>" , "Renames a group" ) ;
2020-08-20 19:43:17 +00:00
public static Command GroupDisplayName = new Command ( "group displayname" , "group <member> displayname [display name]" , "Changes a group's display name" ) ;
2020-07-06 17:50:39 +00:00
public static Command GroupDesc = new Command ( "group description" , "group <group> description [description]" , "Changes a group's description" ) ;
2020-07-07 13:28:53 +00:00
public static Command GroupAdd = new Command ( "group add" , "group <group> add <member> [member 2] [member 3...]" , "Adds one or more members to a group" ) ;
public static Command GroupRemove = new Command ( "group remove" , "group <group> remove <member> [member 2] [member 3...]" , "Removes one or more members from a group" ) ;
2020-07-18 11:53:02 +00:00
public static Command GroupPrivacy = new Command ( "group privacy" , "group <group> privacy <description|icon|visibility|all> <public|private>" , "Changes a group's privacy settings" ) ;
2020-08-08 12:56:34 +00:00
public static Command GroupDelete = new Command ( "group delete" , "group <group> delete" , "Deletes a group" ) ;
2020-08-08 13:09:42 +00:00
public static Command GroupIcon = new Command ( "group icon" , "group <group> icon [url|@mention]" , "Changes a group's icon" ) ;
2019-11-02 23:29:11 +00:00
public static Command Switch = new Command ( "switch" , "switch <member> [member 2] [member 3...]" , "Registers a switch" ) ;
public static Command SwitchOut = new Command ( "switch out" , "switch out" , "Registers a switch with no members" ) ;
public static Command SwitchMove = new Command ( "switch move" , "switch move <date/time>" , "Moves the latest switch in time" ) ;
public static Command SwitchDelete = new Command ( "switch delete" , "switch delete [all]" , "Deletes the latest switch (or them all)" ) ;
public static Command Link = new Command ( "link" , "link <account>" , "Links your system to another account" ) ;
public static Command Unlink = new Command ( "unlink" , "unlink [account]" , "Unlinks your system from an account" ) ;
public static Command TokenGet = new Command ( "token" , "token" , "Gets your system's API token" ) ;
public static Command TokenRefresh = new Command ( "token refresh" , "token refresh" , "Resets your system's API token" ) ;
public static Command Import = new Command ( "import" , "import [fileurl]" , "Imports system information from a data file" ) ;
public static Command Export = new Command ( "export" , "export" , "Exports system information to a data file" ) ;
public static Command Help = new Command ( "help" , "help" , "Shows help information about PluralKit" ) ;
2020-05-08 00:01:57 +00:00
public static Command Explain = new Command ( "explain" , "explain" , "Explains the basics of systems and proxying" ) ;
2019-11-02 23:29:11 +00:00
public static Command Message = new Command ( "message" , "message <id|link>" , "Looks up a proxied message" ) ;
2019-11-03 18:15:50 +00:00
public static Command LogChannel = new Command ( "log channel" , "log channel <channel>" , "Designates a channel to post proxied messages to" ) ;
public static Command LogEnable = new Command ( "log enable" , "log enable all|<channel> [channel 2] [channel 3...]" , "Enables message logging in certain channels" ) ;
public static Command LogDisable = new Command ( "log disable" , "log disable all|<channel> [channel 2] [channel 3...]" , "Disables message logging in certain channels" ) ;
2020-02-14 23:12:03 +00:00
public static Command LogClean = new Command ( "logclean" , "logclean [on|off]" , "Toggles whether to clean up other bots' log channels" ) ;
2020-07-05 10:54:27 +00:00
public static Command BlacklistShow = new Command ( "blacklist show" , "blacklist show" , "Displays the current proxy blacklist" ) ;
2019-11-03 18:15:50 +00:00
public static Command BlacklistAdd = new Command ( "blacklist add" , "blacklist add all|<channel> [channel 2] [channel 3...]" , "Adds certain channels to the proxy blacklist" ) ;
public static Command BlacklistRemove = new Command ( "blacklist remove" , "blacklist remove all|<channel> [channel 2] [channel 3...]" , "Removes certain channels from the proxy blacklist" ) ;
2019-11-02 23:29:11 +00:00
public static Command Invite = new Command ( "invite" , "invite" , "Gets a link to invite PluralKit to other servers" ) ;
public static Command PermCheck = new Command ( "permcheck" , "permcheck <guild>" , "Checks whether a server's permission setup is correct" ) ;
public static Command [ ] SystemCommands = {
SystemInfo , SystemNew , SystemRename , SystemTag , SystemDesc , SystemAvatar , SystemDelete , SystemTimezone ,
2020-03-04 17:28:13 +00:00
SystemList , SystemFronter , SystemFrontHistory , SystemFrontPercent , SystemPrivacy , SystemProxy
2019-11-02 23:29:11 +00:00
} ;
public static Command [ ] MemberCommands = {
2019-12-26 19:39:47 +00:00
MemberInfo , MemberNew , MemberRename , MemberDisplayName , MemberServerName , MemberDesc , MemberPronouns ,
2020-06-17 19:31:39 +00:00
MemberColor , MemberBirthday , MemberProxy , MemberKeepProxy , MemberDelete , MemberAvatar , MemberServerAvatar , MemberPrivacy ,
2020-03-04 17:28:13 +00:00
MemberRandom
2019-11-02 23:29:11 +00:00
} ;
2020-08-16 10:10:54 +00:00
public static Command [ ] GroupCommands =
{
GroupInfo , GroupList , GroupNew , GroupAdd , GroupRemove , GroupMemberList , GroupRename , GroupDesc ,
GroupIcon , GroupPrivacy , GroupDelete
} ;
public static Command [ ] GroupCommandsTargeted =
{
GroupInfo , GroupAdd , GroupRemove , GroupMemberList , GroupRename , GroupDesc , GroupIcon , GroupPrivacy ,
GroupDelete
} ;
2019-11-02 23:29:11 +00:00
public static Command [ ] SwitchCommands = { Switch , SwitchOut , SwitchMove , SwitchDelete } ;
2019-11-03 18:15:50 +00:00
public static Command [ ] LogCommands = { LogChannel , LogEnable , LogDisable } ;
2019-10-05 05:41:00 +00:00
2020-02-01 14:00:36 +00:00
private DiscordShardedClient _client ;
2019-10-05 05:41:00 +00:00
2020-02-01 14:00:36 +00:00
public CommandTree ( DiscordShardedClient client )
2019-10-05 05:41:00 +00:00
{
2020-04-24 19:50:28 +00:00
2019-10-05 05:41:00 +00:00
_client = client ;
}
public Task ExecuteCommand ( Context ctx )
{
if ( ctx . Match ( "system" , "s" ) )
return HandleSystemCommand ( ctx ) ;
if ( ctx . Match ( "member" , "m" ) )
return HandleMemberCommand ( ctx ) ;
2020-06-29 21:51:12 +00:00
if ( ctx . Match ( "group" , "g" ) )
return HandleGroupCommand ( ctx ) ;
2019-10-05 05:41:00 +00:00
if ( ctx . Match ( "switch" , "sw" ) )
return HandleSwitchCommand ( ctx ) ;
2020-01-23 20:20:22 +00:00
if ( ctx . Match ( "ap" , "autoproxy" , "auto" ) )
2020-02-01 12:03:02 +00:00
return ctx . Execute < Autoproxy > ( Autoproxy , m = > m . AutoproxyRoot ( ctx ) ) ;
2020-02-13 15:49:45 +00:00
if ( ctx . Match ( "list" , "l" , "members" ) )
return ctx . Execute < SystemList > ( SystemList , m = > m . MemberList ( ctx , ctx . System ) ) ;
if ( ctx . Match ( "f" , "find" , "search" , "query" , "fd" ) )
2020-06-04 11:21:47 +00:00
return ctx . Execute < SystemList > ( SystemFind , m = > m . MemberList ( ctx , ctx . System ) ) ;
2019-10-05 05:41:00 +00:00
if ( ctx . Match ( "link" ) )
2020-02-01 12:03:02 +00:00
return ctx . Execute < SystemLink > ( Link , m = > m . LinkSystem ( ctx ) ) ;
2019-10-05 05:41:00 +00:00
if ( ctx . Match ( "unlink" ) )
2020-02-01 12:03:02 +00:00
return ctx . Execute < SystemLink > ( Unlink , m = > m . UnlinkAccount ( ctx ) ) ;
2019-10-05 05:41:00 +00:00
if ( ctx . Match ( "token" ) )
if ( ctx . Match ( "refresh" , "renew" , "invalidate" , "reroll" , "regen" ) )
2020-02-01 12:03:02 +00:00
return ctx . Execute < Token > ( TokenRefresh , m = > m . RefreshToken ( ctx ) ) ;
2019-10-05 05:41:00 +00:00
else
2020-02-01 12:03:02 +00:00
return ctx . Execute < Token > ( TokenGet , m = > m . GetToken ( ctx ) ) ;
2019-10-05 05:41:00 +00:00
if ( ctx . Match ( "import" ) )
2020-02-01 12:03:02 +00:00
return ctx . Execute < ImportExport > ( Import , m = > m . Import ( ctx ) ) ;
2019-10-05 05:41:00 +00:00
if ( ctx . Match ( "export" ) )
2020-02-01 12:03:02 +00:00
return ctx . Execute < ImportExport > ( Export , m = > m . Export ( ctx ) ) ;
2019-10-05 05:41:00 +00:00
if ( ctx . Match ( "help" ) )
if ( ctx . Match ( "commands" ) )
2019-11-02 23:29:11 +00:00
return ctx . Reply ( "For the list of commands, see the website: <https://pluralkit.me/commands>" ) ;
2019-10-05 05:41:00 +00:00
else if ( ctx . Match ( "proxy" ) )
2019-11-02 23:29:11 +00:00
return ctx . Reply ( "The proxy help page has been moved! See the website: https://pluralkit.me/guide#proxying" ) ;
2020-02-01 12:03:02 +00:00
else return ctx . Execute < Help > ( Help , m = > m . HelpRoot ( ctx ) ) ;
2020-05-08 00:01:57 +00:00
if ( ctx . Match ( "explain" ) )
return ctx . Execute < Help > ( Explain , m = > m . Explain ( ctx ) ) ;
2019-10-05 05:41:00 +00:00
if ( ctx . Match ( "commands" ) )
2019-11-02 23:29:11 +00:00
return ctx . Reply ( "For the list of commands, see the website: <https://pluralkit.me/commands>" ) ;
2019-10-05 05:41:00 +00:00
if ( ctx . Match ( "message" , "msg" ) )
2020-02-01 12:03:02 +00:00
return ctx . Execute < Misc > ( Message , m = > m . GetMessage ( ctx ) ) ;
2019-10-05 05:41:00 +00:00
if ( ctx . Match ( "log" ) )
2019-11-03 18:15:50 +00:00
if ( ctx . Match ( "channel" ) )
2020-02-01 12:03:02 +00:00
return ctx . Execute < ServerConfig > ( LogChannel , m = > m . SetLogChannel ( ctx ) ) ;
2019-11-03 18:15:50 +00:00
else if ( ctx . Match ( "enable" , "on" ) )
2020-02-01 12:03:02 +00:00
return ctx . Execute < ServerConfig > ( LogEnable , m = > m . SetLogEnabled ( ctx , true ) ) ;
2019-11-03 18:15:50 +00:00
else if ( ctx . Match ( "disable" , "off" ) )
2020-02-01 12:03:02 +00:00
return ctx . Execute < ServerConfig > ( LogDisable , m = > m . SetLogEnabled ( ctx , false ) ) ;
2019-11-03 18:15:50 +00:00
else return PrintCommandExpectedError ( ctx , LogCommands ) ;
2020-02-14 23:12:03 +00:00
if ( ctx . Match ( "logclean" ) )
return ctx . Execute < ServerConfig > ( LogClean , m = > m . SetLogCleanup ( ctx ) ) ;
2019-11-03 18:15:50 +00:00
if ( ctx . Match ( "blacklist" , "bl" ) )
if ( ctx . Match ( "enable" , "on" , "add" , "deny" ) )
2020-02-01 12:03:02 +00:00
return ctx . Execute < ServerConfig > ( BlacklistAdd , m = > m . SetBlacklisted ( ctx , true ) ) ;
2019-11-03 18:15:50 +00:00
else if ( ctx . Match ( "disable" , "off" , "remove" , "allow" ) )
2020-02-01 12:03:02 +00:00
return ctx . Execute < ServerConfig > ( BlacklistRemove , m = > m . SetBlacklisted ( ctx , false ) ) ;
2020-07-05 10:54:27 +00:00
else if ( ctx . Match ( "list" , "show" ) )
return ctx . Execute < ServerConfig > ( BlacklistShow , m = > m . ShowBlacklisted ( ctx ) ) ;
else return PrintCommandExpectedError ( ctx , BlacklistAdd , BlacklistRemove , BlacklistShow ) ;
2019-12-28 11:12:22 +00:00
if ( ctx . Match ( "proxy" , "enable" , "disable" ) )
2020-02-01 12:03:02 +00:00
return ctx . Execute < SystemEdit > ( SystemProxy , m = > m . SystemProxy ( ctx ) ) ;
if ( ctx . Match ( "invite" ) ) return ctx . Execute < Misc > ( Invite , m = > m . Invite ( ctx ) ) ;
if ( ctx . Match ( "mn" ) ) return ctx . Execute < Fun > ( null , m = > m . Mn ( ctx ) ) ;
if ( ctx . Match ( "fire" ) ) return ctx . Execute < Fun > ( null , m = > m . Fire ( ctx ) ) ;
if ( ctx . Match ( "thunder" ) ) return ctx . Execute < Fun > ( null , m = > m . Thunder ( ctx ) ) ;
if ( ctx . Match ( "freeze" ) ) return ctx . Execute < Fun > ( null , m = > m . Freeze ( ctx ) ) ;
if ( ctx . Match ( "starstorm" ) ) return ctx . Execute < Fun > ( null , m = > m . Starstorm ( ctx ) ) ;
if ( ctx . Match ( "flash" ) ) return ctx . Execute < Fun > ( null , m = > m . Flash ( ctx ) ) ;
if ( ctx . Match ( "stats" ) ) return ctx . Execute < Misc > ( null , m = > m . Stats ( ctx ) ) ;
2019-10-05 05:41:00 +00:00
if ( ctx . Match ( "permcheck" ) )
2020-02-01 12:03:02 +00:00
return ctx . Execute < Misc > ( PermCheck , m = > m . PermCheckGuild ( ctx ) ) ;
2020-01-08 20:33:14 +00:00
if ( ctx . Match ( "random" , "r" ) )
2020-02-01 12:03:02 +00:00
return ctx . Execute < Member > ( MemberRandom , m = > m . MemberRandom ( ctx ) ) ;
2019-10-05 05:41:00 +00:00
2020-10-18 05:18:52 +00:00
// remove compiler warning
return ctx . Reply (
2020-08-25 20:44:52 +00:00
$"{Emojis.Error} Unknown command {ctx.PeekArgument().AsCode()}. For a list of possible commands, see <https://pluralkit.me/commands>." ) ;
2019-10-05 05:41:00 +00:00
}
private async Task HandleSystemCommand ( Context ctx )
{
// If we have no parameters, default to self-target
if ( ! ctx . HasNext ( ) )
2020-02-01 12:03:02 +00:00
await ctx . Execute < System > ( SystemInfo , m = > m . Query ( ctx , ctx . System ) ) ;
2019-10-05 05:41:00 +00:00
// First, we match own-system-only commands (ie. no target system parameter)
2020-07-28 21:57:26 +00:00
else if ( ctx . Match ( "new" , "create" , "make" , "add" , "register" , "init" , "n" ) )
2020-02-01 12:03:02 +00:00
await ctx . Execute < System > ( SystemNew , m = > m . New ( ctx ) ) ;
2019-10-05 05:41:00 +00:00
else if ( ctx . Match ( "name" , "rename" , "changename" ) )
2020-02-01 12:03:02 +00:00
await ctx . Execute < SystemEdit > ( SystemRename , m = > m . Name ( ctx ) ) ;
2019-10-05 05:41:00 +00:00
else if ( ctx . Match ( "tag" ) )
2020-02-01 12:03:02 +00:00
await ctx . Execute < SystemEdit > ( SystemTag , m = > m . Tag ( ctx ) ) ;
2019-10-05 05:41:00 +00:00
else if ( ctx . Match ( "description" , "desc" , "bio" ) )
2020-02-01 12:03:02 +00:00
await ctx . Execute < SystemEdit > ( SystemDesc , m = > m . Description ( ctx ) ) ;
2019-10-05 05:41:00 +00:00
else if ( ctx . Match ( "avatar" , "picture" , "icon" , "image" , "pic" , "pfp" ) )
2020-02-01 12:03:02 +00:00
await ctx . Execute < SystemEdit > ( SystemAvatar , m = > m . Avatar ( ctx ) ) ;
2019-10-05 05:41:00 +00:00
else if ( ctx . Match ( "delete" , "remove" , "destroy" , "erase" , "yeet" ) )
2020-02-01 12:03:02 +00:00
await ctx . Execute < SystemEdit > ( SystemDelete , m = > m . Delete ( ctx ) ) ;
2019-10-05 05:41:00 +00:00
else if ( ctx . Match ( "timezone" , "tz" ) )
2020-02-01 12:03:02 +00:00
await ctx . Execute < SystemEdit > ( SystemTimezone , m = > m . SystemTimezone ( ctx ) ) ;
2019-12-22 13:15:56 +00:00
else if ( ctx . Match ( "proxy" ) )
2020-02-01 12:03:02 +00:00
await ctx . Execute < SystemEdit > ( SystemProxy , m = > m . SystemProxy ( ctx ) ) ;
2019-10-05 05:41:00 +00:00
else if ( ctx . Match ( "list" , "l" , "members" ) )
2020-02-13 15:35:50 +00:00
await ctx . Execute < SystemList > ( SystemList , m = > m . MemberList ( ctx , ctx . System ) ) ;
2020-02-13 15:49:45 +00:00
else if ( ctx . Match ( "find" , "search" , "query" , "fd" , "s" ) )
2020-06-04 11:21:47 +00:00
await ctx . Execute < SystemList > ( SystemFind , m = > m . MemberList ( ctx , ctx . System ) ) ;
2019-10-05 05:41:00 +00:00
else if ( ctx . Match ( "f" , "front" , "fronter" , "fronters" ) )
{
if ( ctx . Match ( "h" , "history" ) )
2020-02-01 12:03:02 +00:00
await ctx . Execute < SystemFront > ( SystemFrontHistory , m = > m . SystemFrontHistory ( ctx , ctx . System ) ) ;
2019-10-05 05:41:00 +00:00
else if ( ctx . Match ( "p" , "percent" , "%" ) )
2020-02-01 12:03:02 +00:00
await ctx . Execute < SystemFront > ( SystemFrontPercent , m = > m . SystemFrontPercent ( ctx , ctx . System ) ) ;
2019-10-05 05:41:00 +00:00
else
2020-02-01 12:03:02 +00:00
await ctx . Execute < SystemFront > ( SystemFronter , m = > m . SystemFronter ( ctx , ctx . System ) ) ;
2019-10-05 05:41:00 +00:00
}
else if ( ctx . Match ( "fh" , "fronthistory" , "history" , "switches" ) )
2020-02-01 12:03:02 +00:00
await ctx . Execute < SystemFront > ( SystemFrontHistory , m = > m . SystemFrontHistory ( ctx , ctx . System ) ) ;
2019-10-05 05:41:00 +00:00
else if ( ctx . Match ( "fp" , "frontpercent" , "front%" , "frontbreakdown" ) )
2020-02-01 12:03:02 +00:00
await ctx . Execute < SystemFront > ( SystemFrontPercent , m = > m . SystemFrontPercent ( ctx , ctx . System ) ) ;
2020-01-11 15:49:20 +00:00
else if ( ctx . Match ( "privacy" ) )
2020-02-01 12:03:02 +00:00
await ctx . Execute < SystemEdit > ( SystemPrivacy , m = > m . SystemPrivacy ( ctx ) ) ;
2020-03-21 13:04:41 +00:00
else if ( ctx . Match ( "ping" ) )
await ctx . Execute < SystemEdit > ( SystemPing , m = > m . SystemPing ( ctx ) ) ;
2019-11-02 23:29:11 +00:00
else if ( ctx . Match ( "commands" , "help" ) )
await PrintCommandList ( ctx , "systems" , SystemCommands ) ;
2020-08-26 20:01:42 +00:00
else if ( ctx . Match ( "groups" , "gs" , "g" ) )
2020-08-16 10:10:54 +00:00
await ctx . Execute < Groups > ( GroupList , g = > g . ListSystemGroups ( ctx , null ) ) ;
2019-10-05 05:41:00 +00:00
else if ( ! ctx . HasNext ( ) ) // Bare command
2020-02-01 12:03:02 +00:00
await ctx . Execute < System > ( SystemInfo , m = > m . Query ( ctx , ctx . System ) ) ;
2019-10-05 05:41:00 +00:00
else
await HandleSystemCommandTargeted ( ctx ) ;
}
private async Task HandleSystemCommandTargeted ( Context ctx )
{
// Commands that have a system target (eg. pk;system <system> fronthistory)
var target = await ctx . MatchSystem ( ) ;
if ( target = = null )
{
var list = CreatePotentialCommandList ( SystemInfo , SystemNew , SystemRename , SystemTag , SystemDesc , SystemAvatar , SystemDelete , SystemTimezone , SystemList , SystemFronter , SystemFrontHistory , SystemFrontPercent ) ;
await ctx . Reply (
$"{Emojis.Error} {await CreateSystemNotFoundError(ctx)}\n\nPerhaps you meant to use one of the following commands?\n{list}" ) ;
}
else if ( ctx . Match ( "list" , "l" , "members" ) )
2020-02-13 15:35:50 +00:00
await ctx . Execute < SystemList > ( SystemList , m = > m . MemberList ( ctx , target ) ) ;
2020-02-13 15:49:45 +00:00
else if ( ctx . Match ( "find" , "search" , "query" , "fd" , "s" ) )
2020-06-04 11:21:47 +00:00
await ctx . Execute < SystemList > ( SystemFind , m = > m . MemberList ( ctx , target ) ) ;
2019-10-05 05:41:00 +00:00
else if ( ctx . Match ( "f" , "front" , "fronter" , "fronters" ) )
{
if ( ctx . Match ( "h" , "history" ) )
2020-02-01 12:03:02 +00:00
await ctx . Execute < SystemFront > ( SystemFrontHistory , m = > m . SystemFrontHistory ( ctx , target ) ) ;
2019-10-05 05:41:00 +00:00
else if ( ctx . Match ( "p" , "percent" , "%" ) )
2020-02-01 12:03:02 +00:00
await ctx . Execute < SystemFront > ( SystemFrontPercent , m = > m . SystemFrontPercent ( ctx , target ) ) ;
2019-10-05 05:41:00 +00:00
else
2020-02-01 12:03:02 +00:00
await ctx . Execute < SystemFront > ( SystemFronter , m = > m . SystemFronter ( ctx , target ) ) ;
2019-10-05 05:41:00 +00:00
}
else if ( ctx . Match ( "fh" , "fronthistory" , "history" , "switches" ) )
2020-02-01 12:03:02 +00:00
await ctx . Execute < SystemFront > ( SystemFrontHistory , m = > m . SystemFrontHistory ( ctx , target ) ) ;
2019-10-05 05:41:00 +00:00
else if ( ctx . Match ( "fp" , "frontpercent" , "front%" , "frontbreakdown" ) )
2020-02-01 12:03:02 +00:00
await ctx . Execute < SystemFront > ( SystemFrontPercent , m = > m . SystemFrontPercent ( ctx , target ) ) ;
2019-10-05 05:41:00 +00:00
else if ( ctx . Match ( "info" , "view" , "show" ) )
2020-02-01 12:03:02 +00:00
await ctx . Execute < System > ( SystemInfo , m = > m . Query ( ctx , target ) ) ;
2020-08-16 10:10:54 +00:00
else if ( ctx . Match ( "groups" , "gs" ) )
await ctx . Execute < Groups > ( GroupList , g = > g . ListSystemGroups ( ctx , target ) ) ;
2019-10-05 05:41:00 +00:00
else if ( ! ctx . HasNext ( ) )
2020-02-01 12:03:02 +00:00
await ctx . Execute < System > ( SystemInfo , m = > m . Query ( ctx , target ) ) ;
2019-10-05 05:41:00 +00:00
else
await PrintCommandNotFoundError ( ctx , SystemList , SystemFronter , SystemFrontHistory , SystemFrontPercent ,
SystemInfo ) ;
}
private async Task HandleMemberCommand ( Context ctx )
{
if ( ctx . Match ( "new" , "n" , "add" , "create" , "register" ) )
2020-02-01 12:03:02 +00:00
await ctx . Execute < Member > ( MemberNew , m = > m . NewMember ( ctx ) ) ;
2020-06-14 16:56:35 +00:00
else if ( ctx . Match ( "list" ) )
await ctx . Execute < SystemList > ( SystemList , m = > m . MemberList ( ctx , ctx . System ) ) ;
2019-11-02 23:29:11 +00:00
else if ( ctx . Match ( "commands" , "help" ) )
await PrintCommandList ( ctx , "members" , MemberCommands ) ;
2019-10-05 05:41:00 +00:00
else if ( await ctx . MatchMember ( ) is PKMember target )
await HandleMemberCommandTargeted ( ctx , target ) ;
else if ( ! ctx . HasNext ( ) )
2019-12-26 19:39:47 +00:00
await PrintCommandExpectedError ( ctx , MemberNew , MemberInfo , MemberRename , MemberDisplayName , MemberServerName , MemberDesc , MemberPronouns ,
2019-10-05 05:41:00 +00:00
MemberColor , MemberBirthday , MemberProxy , MemberDelete , MemberAvatar ) ;
else
await ctx . Reply ( $"{Emojis.Error} {ctx.CreateMemberNotFoundError(ctx.PopArgument())}" ) ;
}
private async Task HandleMemberCommandTargeted ( Context ctx , PKMember target )
{
// Commands that have a member target (eg. pk;member <member> delete)
if ( ctx . Match ( "rename" , "name" , "changename" , "setname" ) )
2020-02-01 12:03:02 +00:00
await ctx . Execute < MemberEdit > ( MemberRename , m = > m . Name ( ctx , target ) ) ;
2019-10-05 05:41:00 +00:00
else if ( ctx . Match ( "description" , "info" , "bio" , "text" , "desc" ) )
2020-02-01 12:03:02 +00:00
await ctx . Execute < MemberEdit > ( MemberDesc , m = > m . Description ( ctx , target ) ) ;
2019-10-05 05:41:00 +00:00
else if ( ctx . Match ( "pronouns" , "pronoun" ) )
2020-02-01 12:03:02 +00:00
await ctx . Execute < MemberEdit > ( MemberPronouns , m = > m . Pronouns ( ctx , target ) ) ;
2019-10-05 05:41:00 +00:00
else if ( ctx . Match ( "color" , "colour" ) )
2020-02-01 12:03:02 +00:00
await ctx . Execute < MemberEdit > ( MemberColor , m = > m . Color ( ctx , target ) ) ;
2019-10-05 05:41:00 +00:00
else if ( ctx . Match ( "birthday" , "bday" , "birthdate" , "cakeday" , "bdate" ) )
2020-02-01 12:03:02 +00:00
await ctx . Execute < MemberEdit > ( MemberBirthday , m = > m . Birthday ( ctx , target ) ) ;
2019-10-05 05:41:00 +00:00
else if ( ctx . Match ( "proxy" , "tags" , "proxytags" , "brackets" ) )
2020-02-01 12:03:02 +00:00
await ctx . Execute < MemberProxy > ( MemberProxy , m = > m . Proxy ( ctx , target ) ) ;
2019-10-05 05:41:00 +00:00
else if ( ctx . Match ( "delete" , "remove" , "destroy" , "erase" , "yeet" ) )
2020-02-01 12:03:02 +00:00
await ctx . Execute < MemberEdit > ( MemberDelete , m = > m . Delete ( ctx , target ) ) ;
2019-10-05 05:41:00 +00:00
else if ( ctx . Match ( "avatar" , "profile" , "picture" , "icon" , "image" , "pfp" , "pic" ) )
2020-02-01 12:03:02 +00:00
await ctx . Execute < MemberAvatar > ( MemberAvatar , m = > m . Avatar ( ctx , target ) ) ;
2020-02-12 16:42:12 +00:00
else if ( ctx . Match ( "serveravatar" , "servericon" , "serverimage" , "serverpfp" , "serverpic" , "savatar" , "spic" , "guildavatar" , "guildpic" , "guildicon" , "sicon" ) )
await ctx . Execute < MemberAvatar > ( MemberServerAvatar , m = > m . ServerAvatar ( ctx , target ) ) ;
2020-06-23 07:59:39 +00:00
else if ( ctx . Match ( "displayname" , "dn" , "dname" , "nick" , "nickname" , "dispname" ) )
2020-02-01 12:03:02 +00:00
await ctx . Execute < MemberEdit > ( MemberDisplayName , m = > m . DisplayName ( ctx , target ) ) ;
2019-12-27 10:43:06 +00:00
else if ( ctx . Match ( "servername" , "sn" , "sname" , "snick" , "snickname" , "servernick" , "servernickname" , "serverdisplayname" , "guildname" , "guildnick" , "guildnickname" , "serverdn" ) )
2020-02-01 12:03:02 +00:00
await ctx . Execute < MemberEdit > ( MemberServerName , m = > m . ServerName ( ctx , target ) ) ;
2019-10-30 08:26:50 +00:00
else if ( ctx . Match ( "keepproxy" , "keeptags" , "showtags" ) )
2020-02-01 12:03:02 +00:00
await ctx . Execute < MemberEdit > ( MemberKeepProxy , m = > m . KeepProxy ( ctx , target ) ) ;
2020-02-07 21:20:40 +00:00
else if ( ctx . Match ( "privacy" ) )
await ctx . Execute < MemberEdit > ( MemberPrivacy , m = > m . Privacy ( ctx , target , null ) ) ;
2020-06-17 19:31:39 +00:00
else if ( ctx . Match ( "private" , "hidden" , "hide" ) )
2020-02-07 21:20:40 +00:00
await ctx . Execute < MemberEdit > ( MemberPrivacy , m = > m . Privacy ( ctx , target , PrivacyLevel . Private ) ) ;
2020-06-17 19:31:39 +00:00
else if ( ctx . Match ( "public" , "shown" , "show" ) )
2020-02-07 21:20:40 +00:00
await ctx . Execute < MemberEdit > ( MemberPrivacy , m = > m . Privacy ( ctx , target , PrivacyLevel . Public ) ) ;
2019-10-05 05:41:00 +00:00
else if ( ! ctx . HasNext ( ) ) // Bare command
2020-02-01 12:03:02 +00:00
await ctx . Execute < Member > ( MemberInfo , m = > m . ViewMember ( ctx , target ) ) ;
2019-10-05 05:41:00 +00:00
else
2019-12-26 19:39:47 +00:00
await PrintCommandNotFoundError ( ctx , MemberInfo , MemberRename , MemberDisplayName , MemberServerName , MemberDesc , MemberPronouns , MemberColor , MemberBirthday , MemberProxy , MemberDelete , MemberAvatar , SystemList ) ;
2019-10-05 05:41:00 +00:00
}
2020-06-29 21:51:12 +00:00
private async Task HandleGroupCommand ( Context ctx )
{
// Commands with no group argument
if ( ctx . Match ( "n" , "new" ) )
await ctx . Execute < Groups > ( GroupNew , g = > g . CreateGroup ( ctx ) ) ;
2020-07-06 17:50:39 +00:00
else if ( ctx . Match ( "list" , "l" ) )
await ctx . Execute < Groups > ( GroupList , g = > g . ListSystemGroups ( ctx , null ) ) ;
2020-08-16 10:10:54 +00:00
else if ( ctx . Match ( "commands" , "help" ) )
await PrintCommandList ( ctx , "groups" , GroupCommands ) ;
2020-07-06 17:50:39 +00:00
else if ( await ctx . MatchGroup ( ) is { } target )
2020-06-29 21:51:12 +00:00
{
// Commands with group argument
2020-07-06 17:50:39 +00:00
if ( ctx . Match ( "rename" , "name" , "changename" , "setname" ) )
await ctx . Execute < Groups > ( GroupRename , g = > g . RenameGroup ( ctx , target ) ) ;
2020-08-25 20:25:20 +00:00
else if ( ctx . Match ( "nick" , "dn" , "displayname" , "nickname" ) )
2020-08-20 19:43:17 +00:00
await ctx . Execute < Groups > ( GroupDisplayName , g = > g . GroupDisplayName ( ctx , target ) ) ;
2020-07-06 17:50:39 +00:00
else if ( ctx . Match ( "description" , "info" , "bio" , "text" , "desc" ) )
await ctx . Execute < Groups > ( GroupDesc , g = > g . GroupDescription ( ctx , target ) ) ;
2020-07-07 13:28:53 +00:00
else if ( ctx . Match ( "add" , "a" ) )
await ctx . Execute < Groups > ( GroupAdd , g = > g . AddRemoveMembers ( ctx , target , Groups . AddRemoveOperation . Add ) ) ;
else if ( ctx . Match ( "remove" , "rem" , "r" ) )
await ctx . Execute < Groups > ( GroupRemove , g = > g . AddRemoveMembers ( ctx , target , Groups . AddRemoveOperation . Remove ) ) ;
2020-07-07 17:34:23 +00:00
else if ( ctx . Match ( "members" , "list" , "ms" , "l" ) )
await ctx . Execute < Groups > ( GroupMemberList , g = > g . ListGroupMembers ( ctx , target ) ) ;
2020-07-18 11:53:02 +00:00
else if ( ctx . Match ( "privacy" ) )
await ctx . Execute < Groups > ( GroupPrivacy , g = > g . GroupPrivacy ( ctx , target , null ) ) ;
else if ( ctx . Match ( "public" , "pub" ) )
await ctx . Execute < Groups > ( GroupPrivacy , g = > g . GroupPrivacy ( ctx , target , PrivacyLevel . Public ) ) ;
else if ( ctx . Match ( "private" , "priv" ) )
await ctx . Execute < Groups > ( GroupPrivacy , g = > g . GroupPrivacy ( ctx , target , PrivacyLevel . Private ) ) ;
2020-08-08 12:56:34 +00:00
else if ( ctx . Match ( "delete" , "remove" , "destroy" , "erase" , "yeet" ) )
await ctx . Execute < Groups > ( GroupDelete , g = > g . DeleteGroup ( ctx , target ) ) ;
2020-08-08 13:09:42 +00:00
else if ( ctx . Match ( "avatar" , "picture" , "icon" , "image" , "pic" , "pfp" ) )
await ctx . Execute < Groups > ( GroupIcon , g = > g . GroupIcon ( ctx , target ) ) ;
2020-07-06 17:50:39 +00:00
else if ( ! ctx . HasNext ( ) )
await ctx . Execute < Groups > ( GroupInfo , g = > g . ShowGroupCard ( ctx , target ) ) ;
else
2020-08-16 10:10:54 +00:00
await PrintCommandNotFoundError ( ctx , GroupCommandsTargeted ) ;
2020-06-29 21:51:12 +00:00
}
2020-07-06 17:50:39 +00:00
else if ( ! ctx . HasNext ( ) )
2020-08-16 10:10:54 +00:00
await PrintCommandNotFoundError ( ctx , GroupCommands ) ;
2020-07-06 17:50:39 +00:00
else
await ctx . Reply ( $"{Emojis.Error} {ctx.CreateGroupNotFoundError(ctx.PopArgument())}" ) ;
2020-06-29 21:51:12 +00:00
}
2019-10-05 05:41:00 +00:00
private async Task HandleSwitchCommand ( Context ctx )
{
if ( ctx . Match ( "out" ) )
2020-02-01 12:03:02 +00:00
await ctx . Execute < Switch > ( SwitchOut , m = > m . SwitchOut ( ctx ) ) ;
2019-10-05 05:41:00 +00:00
else if ( ctx . Match ( "move" , "shift" , "offset" ) )
2020-02-01 12:03:02 +00:00
await ctx . Execute < Switch > ( SwitchMove , m = > m . SwitchMove ( ctx ) ) ;
2019-10-05 05:41:00 +00:00
else if ( ctx . Match ( "delete" , "remove" , "erase" , "cancel" , "yeet" ) )
2020-02-01 12:03:02 +00:00
await ctx . Execute < Switch > ( SwitchDelete , m = > m . SwitchDelete ( ctx ) ) ;
2019-11-02 23:29:11 +00:00
else if ( ctx . Match ( "commands" , "help" ) )
await PrintCommandList ( ctx , "switching" , SwitchCommands ) ;
2019-10-05 05:41:00 +00:00
else if ( ctx . HasNext ( ) ) // there are following arguments
2020-02-01 12:03:02 +00:00
await ctx . Execute < Switch > ( Switch , m = > m . SwitchDo ( ctx ) ) ;
2019-10-05 05:41:00 +00:00
else
await PrintCommandNotFoundError ( ctx , Switch , SwitchOut , SwitchMove , SwitchDelete , SystemFronter , SystemFrontHistory ) ;
}
private async Task PrintCommandNotFoundError ( Context ctx , params Command [ ] potentialCommands )
{
var commandListStr = CreatePotentialCommandList ( potentialCommands ) ;
await ctx . Reply (
2020-07-18 10:58:18 +00:00
$"{Emojis.Error} Unknown command `pk;{ctx.FullCommand().Truncate(100)}`. Perhaps you meant to use one of the following commands?\n{commandListStr}\n\nFor a full list of possible commands, see <https://pluralkit.me/commands>." ) ;
2019-10-05 05:41:00 +00:00
}
private async Task PrintCommandExpectedError ( Context ctx , params Command [ ] potentialCommands )
{
var commandListStr = CreatePotentialCommandList ( potentialCommands ) ;
await ctx . Reply (
$"{Emojis.Error} You need to pass a command. Perhaps you meant to use one of the following commands?\n{commandListStr}\n\nFor a full list of possible commands, see <https://pluralkit.me/commands>." ) ;
}
private static string CreatePotentialCommandList ( params Command [ ] potentialCommands )
{
2019-11-02 23:29:11 +00:00
return string . Join ( "\n" , potentialCommands . Select ( cmd = > $"- **pk;{cmd.Usage}** - *{cmd.Description}*" ) ) ;
}
private async Task PrintCommandList ( Context ctx , string subject , params Command [ ] commands )
{
var str = CreatePotentialCommandList ( commands ) ;
await ctx . Reply ( $"Here is a list of commands related to {subject}: \n{str}\nFor a full list of possible commands, see <https://pluralkit.me/commands>." ) ;
2019-10-05 05:41:00 +00:00
}
private async Task < string > CreateSystemNotFoundError ( Context ctx )
{
var input = ctx . PopArgument ( ) ;
if ( input . TryParseMention ( out var id ) )
{
// Try to resolve the user ID to find the associated account,
// so we can print their username.
2020-07-02 16:29:04 +00:00
var user = await ctx . Shard . GetUser ( id ) ;
if ( user ! = null )
2020-05-02 13:33:05 +00:00
return $"Account **{user.Username}#{user.Discriminator}** does not have a system registered." ;
2020-07-02 16:29:04 +00:00
else
2019-10-05 05:41:00 +00:00
return $"Account with ID `{id}` not found." ;
}
2020-08-25 20:44:52 +00:00
return $"System with ID {input.AsCode()} not found." ;
2019-10-05 05:41:00 +00:00
}
}
2020-03-21 13:04:41 +00:00
}