2020-02-12 14:16:19 +00:00
|
|
|
using PluralKit.Core;
|
2019-10-05 05:41:00 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
namespace PluralKit.Bot;
|
|
|
|
|
2021-11-27 03:04:04 +00:00
|
|
|
public partial class CommandTree
|
2019-10-05 05:41:00 +00:00
|
|
|
{
|
2021-11-27 02:10:56 +00:00
|
|
|
public Task ExecuteCommand(Context ctx)
|
|
|
|
{
|
|
|
|
if (ctx.Match("system", "s"))
|
|
|
|
return HandleSystemCommand(ctx);
|
|
|
|
if (ctx.Match("member", "m"))
|
|
|
|
return HandleMemberCommand(ctx);
|
|
|
|
if (ctx.Match("group", "g"))
|
|
|
|
return HandleGroupCommand(ctx);
|
|
|
|
if (ctx.Match("switch", "sw"))
|
|
|
|
return HandleSwitchCommand(ctx);
|
|
|
|
if (ctx.Match("commands", "cmd", "c"))
|
|
|
|
return CommandHelpRoot(ctx);
|
|
|
|
if (ctx.Match("ap", "autoproxy", "auto"))
|
|
|
|
return HandleAutoproxyCommand(ctx);
|
2021-11-30 02:35:21 +00:00
|
|
|
if (ctx.Match("config", "cfg"))
|
|
|
|
return HandleConfigCommand(ctx);
|
2021-11-27 02:10:56 +00:00
|
|
|
if (ctx.Match("list", "find", "members", "search", "query", "l", "f", "fd"))
|
|
|
|
return ctx.Execute<SystemList>(SystemList, m => m.MemberList(ctx, ctx.System));
|
|
|
|
if (ctx.Match("link"))
|
|
|
|
return ctx.Execute<SystemLink>(Link, m => m.LinkSystem(ctx));
|
|
|
|
if (ctx.Match("unlink"))
|
|
|
|
return ctx.Execute<SystemLink>(Unlink, m => m.UnlinkAccount(ctx));
|
|
|
|
if (ctx.Match("token"))
|
|
|
|
if (ctx.Match("refresh", "renew", "invalidate", "reroll", "regen"))
|
|
|
|
return ctx.Execute<Api>(TokenRefresh, m => m.RefreshToken(ctx));
|
2021-06-08 17:37:44 +00:00
|
|
|
else
|
2021-11-27 02:10:56 +00:00
|
|
|
return ctx.Execute<Api>(TokenGet, m => m.GetToken(ctx));
|
|
|
|
if (ctx.Match("import"))
|
|
|
|
return ctx.Execute<ImportExport>(Import, m => m.Import(ctx));
|
|
|
|
if (ctx.Match("export"))
|
|
|
|
return ctx.Execute<ImportExport>(Export, m => m.Export(ctx));
|
|
|
|
if (ctx.Match("help"))
|
|
|
|
if (ctx.Match("commands"))
|
|
|
|
return ctx.Reply("For the list of commands, see the website: <https://pluralkit.me/commands>");
|
|
|
|
else if (ctx.Match("proxy"))
|
|
|
|
return ctx.Reply(
|
|
|
|
"The proxy help page has been moved! See the website: https://pluralkit.me/guide#proxying");
|
|
|
|
else return ctx.Execute<Help>(Help, m => m.HelpRoot(ctx));
|
|
|
|
if (ctx.Match("explain"))
|
|
|
|
return ctx.Execute<Help>(Explain, m => m.Explain(ctx));
|
|
|
|
if (ctx.Match("message", "msg"))
|
|
|
|
return ctx.Execute<ProxiedMessage>(Message, m => m.GetMessage(ctx));
|
|
|
|
if (ctx.Match("edit", "e"))
|
|
|
|
return ctx.Execute<ProxiedMessage>(MessageEdit, m => m.EditMessage(ctx));
|
|
|
|
if (ctx.Match("log"))
|
|
|
|
if (ctx.Match("channel"))
|
|
|
|
return ctx.Execute<ServerConfig>(LogChannel, m => m.SetLogChannel(ctx));
|
|
|
|
else if (ctx.Match("enable", "on"))
|
|
|
|
return ctx.Execute<ServerConfig>(LogEnable, m => m.SetLogEnabled(ctx, true));
|
|
|
|
else if (ctx.Match("disable", "off"))
|
|
|
|
return ctx.Execute<ServerConfig>(LogDisable, m => m.SetLogEnabled(ctx, false));
|
|
|
|
else if (ctx.Match("commands"))
|
|
|
|
return PrintCommandList(ctx, "message logging", LogCommands);
|
|
|
|
else return PrintCommandExpectedError(ctx, LogCommands);
|
|
|
|
if (ctx.Match("logclean"))
|
|
|
|
return ctx.Execute<ServerConfig>(LogClean, m => m.SetLogCleanup(ctx));
|
|
|
|
if (ctx.Match("blacklist", "bl"))
|
|
|
|
if (ctx.Match("enable", "on", "add", "deny"))
|
|
|
|
return ctx.Execute<ServerConfig>(BlacklistAdd, m => m.SetBlacklisted(ctx, true));
|
|
|
|
else if (ctx.Match("disable", "off", "remove", "allow"))
|
|
|
|
return ctx.Execute<ServerConfig>(BlacklistRemove, m => m.SetBlacklisted(ctx, false));
|
|
|
|
else if (ctx.Match("list", "show"))
|
|
|
|
return ctx.Execute<ServerConfig>(BlacklistShow, m => m.ShowBlacklisted(ctx));
|
|
|
|
else if (ctx.Match("commands"))
|
|
|
|
return PrintCommandList(ctx, "channel blacklisting", BlacklistCommands);
|
|
|
|
else return PrintCommandExpectedError(ctx, BlacklistCommands);
|
|
|
|
if (ctx.Match("proxy"))
|
|
|
|
if (ctx.Match("debug"))
|
|
|
|
return ctx.Execute<Checks>(ProxyCheck, m => m.MessageProxyCheck(ctx));
|
|
|
|
else
|
|
|
|
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("error")) return ctx.Execute<Fun>(null, m => m.Error(ctx));
|
|
|
|
if (ctx.Match("stats")) return ctx.Execute<Misc>(null, m => m.Stats(ctx));
|
|
|
|
if (ctx.Match("permcheck"))
|
|
|
|
return ctx.Execute<Checks>(PermCheck, m => m.PermCheckGuild(ctx));
|
|
|
|
if (ctx.Match("proxycheck"))
|
|
|
|
return ctx.Execute<Checks>(ProxyCheck, m => m.MessageProxyCheck(ctx));
|
|
|
|
if (ctx.Match("debug"))
|
|
|
|
return HandleDebugCommand(ctx);
|
|
|
|
if (ctx.Match("admin"))
|
|
|
|
return HandleAdminCommand(ctx);
|
|
|
|
if (ctx.Match("random", "r"))
|
|
|
|
if (ctx.Match("group", "g") || ctx.MatchFlag("group", "g"))
|
|
|
|
return ctx.Execute<Random>(GroupRandom, r => r.Group(ctx));
|
|
|
|
else
|
|
|
|
return ctx.Execute<Random>(MemberRandom, m => m.Member(ctx));
|
2021-06-08 17:37:44 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
// remove compiler warning
|
|
|
|
return ctx.Reply(
|
|
|
|
$"{Emojis.Error} Unknown command {ctx.PeekArgument().AsCode()}. For a list of possible commands, see <https://pluralkit.me/commands>.");
|
|
|
|
}
|
|
|
|
|
|
|
|
private async Task HandleAdminCommand(Context ctx)
|
|
|
|
{
|
|
|
|
if (ctx.Match("usid", "updatesystemid"))
|
|
|
|
await ctx.Execute<Admin>(Admin, a => a.UpdateSystemId(ctx));
|
|
|
|
else if (ctx.Match("umid", "updatememberid"))
|
|
|
|
await ctx.Execute<Admin>(Admin, a => a.UpdateMemberId(ctx));
|
|
|
|
else if (ctx.Match("ugid", "updategroupid"))
|
|
|
|
await ctx.Execute<Admin>(Admin, a => a.UpdateGroupId(ctx));
|
|
|
|
else if (ctx.Match("uml", "updatememberlimit"))
|
|
|
|
await ctx.Execute<Admin>(Admin, a => a.SystemMemberLimit(ctx));
|
|
|
|
else if (ctx.Match("ugl", "updategrouplimit"))
|
|
|
|
await ctx.Execute<Admin>(Admin, a => a.SystemGroupLimit(ctx));
|
|
|
|
else
|
|
|
|
await ctx.Reply($"{Emojis.Error} Unknown command.");
|
|
|
|
}
|
|
|
|
|
|
|
|
private async Task HandleDebugCommand(Context ctx)
|
|
|
|
{
|
|
|
|
var availableCommandsStr = "Available debug targets: `permissions`, `proxying`";
|
|
|
|
|
|
|
|
if (ctx.Match("permissions", "perms", "permcheck"))
|
|
|
|
if (ctx.Match("channel", "ch"))
|
2021-09-13 08:21:03 +00:00
|
|
|
await ctx.Execute<Checks>(PermCheck, m => m.PermCheckChannel(ctx));
|
2021-08-04 01:06:14 +00:00
|
|
|
else
|
2021-11-27 02:10:56 +00:00
|
|
|
await ctx.Execute<Checks>(PermCheck, m => m.PermCheckGuild(ctx));
|
|
|
|
else if (ctx.Match("channel"))
|
|
|
|
await ctx.Execute<Checks>(PermCheck, m => m.PermCheckChannel(ctx));
|
|
|
|
else if (ctx.Match("proxy", "proxying", "proxycheck"))
|
|
|
|
await ctx.Execute<Checks>(ProxyCheck, m => m.MessageProxyCheck(ctx));
|
|
|
|
else if (!ctx.HasNext())
|
|
|
|
await ctx.Reply($"{Emojis.Error} You need to pass a command. {availableCommandsStr}");
|
|
|
|
else
|
|
|
|
await ctx.Reply(
|
|
|
|
$"{Emojis.Error} Unknown debug command {ctx.PeekArgument().AsCode()}. {availableCommandsStr}");
|
|
|
|
}
|
2021-08-04 01:06:14 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
private async Task HandleSystemCommand(Context ctx)
|
|
|
|
{
|
2021-12-05 22:21:31 +00:00
|
|
|
// these commands never take a system target
|
2021-11-27 02:10:56 +00:00
|
|
|
if (!ctx.HasNext())
|
|
|
|
await ctx.Execute<System>(SystemInfo, m => m.Query(ctx, ctx.System));
|
|
|
|
else if (ctx.Match("new", "create", "make", "add", "register", "init", "n"))
|
|
|
|
await ctx.Execute<System>(SystemNew, m => m.New(ctx));
|
2021-12-05 22:21:31 +00:00
|
|
|
else if (ctx.Match("commands", "help"))
|
|
|
|
await PrintCommandList(ctx, "systems", SystemCommands);
|
|
|
|
|
|
|
|
// these are deprecated (and not accessible by other users anyway), let's leave them out of new parsing
|
2021-11-27 02:10:56 +00:00
|
|
|
else if (ctx.Match("timezone", "tz"))
|
2021-11-30 02:35:21 +00:00
|
|
|
await ctx.Execute<Config>(ConfigTimezone, m => m.SystemTimezone(ctx), true);
|
2021-12-05 22:21:31 +00:00
|
|
|
else if (ctx.Match("ping"))
|
|
|
|
await ctx.Execute<Config>(ConfigPing, m => m.SystemPing(ctx), true);
|
|
|
|
|
|
|
|
// todo: these aren't deprecated but also shouldn't be here
|
|
|
|
else if (ctx.Match("webhook", "hook"))
|
|
|
|
await ctx.Execute<Api>(null, m => m.SystemWebhook(ctx));
|
2021-11-27 02:10:56 +00:00
|
|
|
else if (ctx.Match("proxy"))
|
|
|
|
await ctx.Execute<SystemEdit>(SystemProxy, m => m.SystemProxy(ctx));
|
2021-12-05 22:21:31 +00:00
|
|
|
|
|
|
|
// finally, parse commands that *do* take a system target
|
|
|
|
else
|
2019-10-05 05:41:00 +00:00
|
|
|
{
|
2021-12-05 22:21:31 +00:00
|
|
|
// try matching a system ID
|
|
|
|
var target = await ctx.MatchSystem();
|
|
|
|
var previousPtr = ctx.Parameters._ptr;
|
|
|
|
|
|
|
|
// if we have a parsed target and no more commands, don't bother with the command flow
|
|
|
|
// we skip the `target != null` check here since the argument isn't be popped if it's not a system
|
|
|
|
if (!ctx.HasNext())
|
|
|
|
{
|
|
|
|
await ctx.Execute<System>(SystemInfo, m => m.Query(ctx, target));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
await HandleSystemCommandTargeted(ctx, target ?? ctx.System);
|
|
|
|
|
|
|
|
// if we *still* haven't matched anything, the user entered an invalid command name or system reference
|
|
|
|
if (ctx.Parameters._ptr == previousPtr)
|
|
|
|
{
|
|
|
|
if (ctx.Parameters.Peek().Length != 5 && !ulong.TryParse(ctx.Parameters.Peek(), out _))
|
|
|
|
{
|
|
|
|
await PrintCommandNotFoundError(ctx, SystemCommands);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
var list = CreatePotentialCommandList(SystemCommands);
|
|
|
|
await ctx.Reply($"{Emojis.Error} {await CreateSystemNotFoundError(ctx)}\n\n"
|
|
|
|
+ $"Perhaps you meant to use one of the following commands?\n{list}");
|
|
|
|
}
|
2019-10-05 05:41:00 +00:00
|
|
|
}
|
2021-11-27 02:10:56 +00:00
|
|
|
}
|
2019-10-05 05:41:00 +00:00
|
|
|
|
2021-12-05 22:21:31 +00:00
|
|
|
private async Task HandleSystemCommandTargeted(Context ctx, PKSystem target)
|
2021-11-27 02:10:56 +00:00
|
|
|
{
|
2021-12-05 22:21:31 +00:00
|
|
|
if (ctx.Match("name", "rename", "changename"))
|
|
|
|
await ctx.Execute<SystemEdit>(SystemRename, m => m.Name(ctx, target));
|
|
|
|
else if (ctx.Match("tag"))
|
|
|
|
await ctx.Execute<SystemEdit>(SystemTag, m => m.Tag(ctx, target));
|
|
|
|
else if (ctx.Match("servertag"))
|
|
|
|
await ctx.Execute<SystemEdit>(SystemServerTag, m => m.ServerTag(ctx, target));
|
|
|
|
else if (ctx.Match("description", "desc", "bio"))
|
|
|
|
await ctx.Execute<SystemEdit>(SystemDesc, m => m.Description(ctx, target));
|
|
|
|
else if (ctx.Match("color", "colour"))
|
|
|
|
await ctx.Execute<SystemEdit>(SystemColor, m => m.Color(ctx, target));
|
|
|
|
else if (ctx.Match("banner", "splash", "cover"))
|
|
|
|
await ctx.Execute<SystemEdit>(SystemBannerImage, m => m.BannerImage(ctx, target));
|
2021-11-27 02:10:56 +00:00
|
|
|
else if (ctx.Match("avatar", "picture", "icon", "image", "pic", "pfp"))
|
|
|
|
await ctx.Execute<SystemEdit>(SystemAvatar, m => m.Avatar(ctx, target));
|
|
|
|
else if (ctx.Match("list", "l", "members"))
|
|
|
|
await ctx.Execute<SystemList>(SystemList, m => m.MemberList(ctx, target));
|
|
|
|
else if (ctx.Match("find", "search", "query", "fd", "s"))
|
|
|
|
await ctx.Execute<SystemList>(SystemFind, m => m.MemberList(ctx, target));
|
|
|
|
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));
|
2021-11-27 02:10:56 +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
|
2021-11-27 02:10:56 +00:00
|
|
|
await ctx.Execute<SystemFront>(SystemFronter, m => m.SystemFronter(ctx, target));
|
2019-10-05 05:41:00 +00:00
|
|
|
}
|
2021-11-27 02:10:56 +00:00
|
|
|
else if (ctx.Match("fh", "fronthistory", "history", "switches"))
|
|
|
|
await ctx.Execute<SystemFront>(SystemFrontHistory, m => m.SystemFrontHistory(ctx, target));
|
|
|
|
else if (ctx.Match("fp", "frontpercent", "front%", "frontbreakdown"))
|
|
|
|
await ctx.Execute<SystemFront>(SystemFrontPercent, m => m.SystemFrontPercent(ctx, target));
|
|
|
|
else if (ctx.Match("info", "view", "show"))
|
|
|
|
await ctx.Execute<System>(SystemInfo, m => m.Query(ctx, target));
|
|
|
|
else if (ctx.Match("groups", "gs"))
|
|
|
|
await ctx.Execute<Groups>(GroupList, g => g.ListSystemGroups(ctx, target));
|
2021-12-05 22:21:31 +00:00
|
|
|
else if (ctx.Match("privacy"))
|
|
|
|
await ctx.Execute<SystemEdit>(SystemPrivacy, m => m.SystemPrivacy(ctx, target));
|
|
|
|
else if (ctx.Match("delete", "remove", "destroy", "erase", "yeet"))
|
|
|
|
await ctx.Execute<SystemEdit>(SystemDelete, m => m.Delete(ctx, target));
|
2021-11-27 02:10:56 +00:00
|
|
|
}
|
2021-08-27 15:03:47 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
private async Task HandleMemberCommand(Context ctx)
|
|
|
|
{
|
|
|
|
if (ctx.Match("new", "n", "add", "create", "register"))
|
|
|
|
await ctx.Execute<Member>(MemberNew, m => m.NewMember(ctx));
|
|
|
|
else if (ctx.Match("list"))
|
|
|
|
await ctx.Execute<SystemList>(SystemList, m => m.MemberList(ctx, ctx.System));
|
|
|
|
else if (ctx.Match("commands", "help"))
|
|
|
|
await PrintCommandList(ctx, "members", MemberCommands);
|
|
|
|
else if (await ctx.MatchMember() is PKMember target)
|
|
|
|
await HandleMemberCommandTargeted(ctx, target);
|
|
|
|
else if (!ctx.HasNext())
|
|
|
|
await PrintCommandExpectedError(ctx, MemberNew, MemberInfo, MemberRename, MemberDisplayName,
|
|
|
|
MemberServerName, MemberDesc, MemberPronouns,
|
|
|
|
MemberColor, MemberBirthday, MemberProxy, MemberDelete, MemberAvatar);
|
|
|
|
else
|
|
|
|
await ctx.Reply($"{Emojis.Error} {ctx.CreateNotFoundError("Member", 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"))
|
|
|
|
await ctx.Execute<MemberEdit>(MemberRename, m => m.Name(ctx, target));
|
|
|
|
else if (ctx.Match("description", "info", "bio", "text", "desc"))
|
|
|
|
await ctx.Execute<MemberEdit>(MemberDesc, m => m.Description(ctx, target));
|
|
|
|
else if (ctx.Match("pronouns", "pronoun"))
|
|
|
|
await ctx.Execute<MemberEdit>(MemberPronouns, m => m.Pronouns(ctx, target));
|
|
|
|
else if (ctx.Match("color", "colour"))
|
|
|
|
await ctx.Execute<MemberEdit>(MemberColor, m => m.Color(ctx, target));
|
|
|
|
else if (ctx.Match("birthday", "bday", "birthdate", "cakeday", "bdate"))
|
|
|
|
await ctx.Execute<MemberEdit>(MemberBirthday, m => m.Birthday(ctx, target));
|
|
|
|
else if (ctx.Match("proxy", "tags", "proxytags", "brackets"))
|
|
|
|
await ctx.Execute<MemberProxy>(MemberProxy, m => m.Proxy(ctx, target));
|
|
|
|
else if (ctx.Match("delete", "remove", "destroy", "erase", "yeet"))
|
|
|
|
await ctx.Execute<MemberEdit>(MemberDelete, m => m.Delete(ctx, target));
|
|
|
|
else if (ctx.Match("avatar", "profile", "picture", "icon", "image", "pfp", "pic"))
|
|
|
|
await ctx.Execute<MemberAvatar>(MemberAvatar, m => m.Avatar(ctx, target));
|
|
|
|
else if (ctx.Match("banner", "splash", "cover"))
|
|
|
|
await ctx.Execute<MemberEdit>(MemberBannerImage, m => m.BannerImage(ctx, target));
|
|
|
|
else if (ctx.Match("group", "groups"))
|
|
|
|
if (ctx.Match("add", "a"))
|
2021-11-27 03:04:04 +00:00
|
|
|
await ctx.Execute<GroupMember>(MemberGroupAdd,
|
|
|
|
m => m.AddRemoveGroups(ctx, target, Groups.AddRemoveOperation.Add));
|
2021-11-27 02:10:56 +00:00
|
|
|
else if (ctx.Match("remove", "rem"))
|
2021-11-27 03:04:04 +00:00
|
|
|
await ctx.Execute<GroupMember>(MemberGroupRemove,
|
|
|
|
m => m.AddRemoveGroups(ctx, target, Groups.AddRemoveOperation.Remove));
|
2019-10-05 05:41:00 +00:00
|
|
|
else
|
2021-11-27 03:04:04 +00:00
|
|
|
await ctx.Execute<GroupMember>(MemberGroups, m => m.ListMemberGroups(ctx, target));
|
2022-01-19 22:23:10 +00:00
|
|
|
else if (ctx.Match("serveravatar", "sa", "servericon", "serverimage", "serverpfp", "serverpic", "savatar", "spic",
|
2021-11-27 02:10:56 +00:00
|
|
|
"guildavatar", "guildpic", "guildicon", "sicon"))
|
|
|
|
await ctx.Execute<MemberAvatar>(MemberServerAvatar, m => m.ServerAvatar(ctx, target));
|
|
|
|
else if (ctx.Match("displayname", "dn", "dname", "nick", "nickname", "dispname"))
|
|
|
|
await ctx.Execute<MemberEdit>(MemberDisplayName, m => m.DisplayName(ctx, target));
|
|
|
|
else if (ctx.Match("servername", "sn", "sname", "snick", "snickname", "servernick", "servernickname",
|
|
|
|
"serverdisplayname", "guildname", "guildnick", "guildnickname", "serverdn"))
|
|
|
|
await ctx.Execute<MemberEdit>(MemberServerName, m => m.ServerName(ctx, target));
|
|
|
|
else if (ctx.Match("autoproxy", "ap"))
|
|
|
|
await ctx.Execute<MemberEdit>(MemberAutoproxy, m => m.MemberAutoproxy(ctx, target));
|
|
|
|
else if (ctx.Match("keepproxy", "keeptags", "showtags"))
|
|
|
|
await ctx.Execute<MemberEdit>(MemberKeepProxy, m => m.KeepProxy(ctx, target));
|
|
|
|
else if (ctx.Match("privacy"))
|
|
|
|
await ctx.Execute<MemberEdit>(MemberPrivacy, m => m.Privacy(ctx, target, null));
|
|
|
|
else if (ctx.Match("private", "hidden", "hide"))
|
|
|
|
await ctx.Execute<MemberEdit>(MemberPrivacy, m => m.Privacy(ctx, target, PrivacyLevel.Private));
|
|
|
|
else if (ctx.Match("public", "shown", "show"))
|
|
|
|
await ctx.Execute<MemberEdit>(MemberPrivacy, m => m.Privacy(ctx, target, PrivacyLevel.Public));
|
|
|
|
else if (ctx.Match("soulscream"))
|
|
|
|
await ctx.Execute<Member>(MemberInfo, m => m.Soulscream(ctx, target));
|
|
|
|
else if (!ctx.HasNext()) // Bare command
|
|
|
|
await ctx.Execute<Member>(MemberInfo, m => m.ViewMember(ctx, target));
|
|
|
|
else
|
|
|
|
await PrintCommandNotFoundError(ctx, MemberInfo, MemberRename, MemberDisplayName, MemberServerName,
|
|
|
|
MemberDesc, MemberPronouns, MemberColor, MemberBirthday, MemberProxy, MemberDelete, MemberAvatar,
|
|
|
|
SystemList);
|
|
|
|
}
|
2019-10-05 05:41:00 +00:00
|
|
|
|
2021-11-27 02:10:56 +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));
|
|
|
|
else if (ctx.Match("list", "l"))
|
|
|
|
await ctx.Execute<Groups>(GroupList, g => g.ListSystemGroups(ctx, null));
|
|
|
|
else if (ctx.Match("commands", "help"))
|
|
|
|
await PrintCommandList(ctx, "groups", GroupCommands);
|
|
|
|
else if (await ctx.MatchGroup() is { } target)
|
2019-10-05 05:41:00 +00:00
|
|
|
{
|
2021-11-27 02:10:56 +00:00
|
|
|
// Commands with group argument
|
2019-10-05 05:41:00 +00:00
|
|
|
if (ctx.Match("rename", "name", "changename", "setname"))
|
2021-11-27 02:10:56 +00:00
|
|
|
await ctx.Execute<Groups>(GroupRename, g => g.RenameGroup(ctx, target));
|
|
|
|
else if (ctx.Match("nick", "dn", "displayname", "nickname"))
|
|
|
|
await ctx.Execute<Groups>(GroupDisplayName, g => g.GroupDisplayName(ctx, target));
|
2019-10-05 05:41:00 +00:00
|
|
|
else if (ctx.Match("description", "info", "bio", "text", "desc"))
|
2021-11-27 02:10:56 +00:00
|
|
|
await ctx.Execute<Groups>(GroupDesc, g => g.GroupDescription(ctx, target));
|
|
|
|
else if (ctx.Match("add", "a"))
|
2021-11-27 03:04:04 +00:00
|
|
|
await ctx.Execute<GroupMember>(GroupAdd,
|
2021-11-27 02:10:56 +00:00
|
|
|
g => g.AddRemoveMembers(ctx, target, Groups.AddRemoveOperation.Add));
|
|
|
|
else if (ctx.Match("remove", "rem", "r"))
|
2021-11-27 03:04:04 +00:00
|
|
|
await ctx.Execute<GroupMember>(GroupRemove,
|
2021-11-27 02:10:56 +00:00
|
|
|
g => g.AddRemoveMembers(ctx, target, Groups.AddRemoveOperation.Remove));
|
|
|
|
else if (ctx.Match("members", "list", "ms", "l"))
|
2021-11-27 03:04:04 +00:00
|
|
|
await ctx.Execute<GroupMember>(GroupMemberList, g => g.ListGroupMembers(ctx, target));
|
2021-11-27 02:10:56 +00:00
|
|
|
else if (ctx.Match("random"))
|
|
|
|
await ctx.Execute<Random>(GroupMemberRandom, r => r.GroupMember(ctx, target));
|
|
|
|
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));
|
2019-10-05 05:41:00 +00:00
|
|
|
else if (ctx.Match("delete", "remove", "destroy", "erase", "yeet"))
|
2021-11-27 02:10:56 +00:00
|
|
|
await ctx.Execute<Groups>(GroupDelete, g => g.DeleteGroup(ctx, target));
|
|
|
|
else if (ctx.Match("avatar", "picture", "icon", "image", "pic", "pfp"))
|
|
|
|
await ctx.Execute<Groups>(GroupIcon, g => g.GroupIcon(ctx, target));
|
2021-08-02 17:46:12 +00:00
|
|
|
else if (ctx.Match("banner", "splash", "cover"))
|
2021-11-27 02:10:56 +00:00
|
|
|
await ctx.Execute<Groups>(GroupBannerImage, g => g.GroupBannerImage(ctx, target));
|
|
|
|
else if (ctx.Match("fp", "frontpercent", "front%", "frontbreakdown"))
|
|
|
|
await ctx.Execute<Groups>(GroupFrontPercent, g => g.GroupFrontPercent(ctx, target));
|
|
|
|
else if (ctx.Match("color", "colour"))
|
|
|
|
await ctx.Execute<Groups>(GroupColor, g => g.GroupColor(ctx, target));
|
2020-07-06 17:50:39 +00:00
|
|
|
else if (!ctx.HasNext())
|
2021-11-27 02:10:56 +00:00
|
|
|
await ctx.Execute<Groups>(GroupInfo, g => g.ShowGroupCard(ctx, target));
|
2020-07-06 17:50:39 +00:00
|
|
|
else
|
2021-11-27 02:10:56 +00:00
|
|
|
await PrintCommandNotFoundError(ctx, GroupCommandsTargeted);
|
2020-06-29 21:51:12 +00:00
|
|
|
}
|
2021-11-27 02:10:56 +00:00
|
|
|
else if (!ctx.HasNext())
|
|
|
|
await PrintCommandExpectedError(ctx, GroupCommands);
|
|
|
|
else
|
|
|
|
await ctx.Reply($"{Emojis.Error} {ctx.CreateNotFoundError("Group", ctx.PopArgument())}");
|
|
|
|
}
|
2020-06-29 21:51:12 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
private async Task HandleSwitchCommand(Context ctx)
|
|
|
|
{
|
|
|
|
if (ctx.Match("out"))
|
|
|
|
await ctx.Execute<Switch>(SwitchOut, m => m.SwitchOut(ctx));
|
|
|
|
else if (ctx.Match("move", "shift", "offset"))
|
|
|
|
await ctx.Execute<Switch>(SwitchMove, m => m.SwitchMove(ctx));
|
|
|
|
else if (ctx.Match("edit", "replace"))
|
2019-10-05 05:41:00 +00:00
|
|
|
if (ctx.Match("out"))
|
2021-11-27 02:10:56 +00:00
|
|
|
await ctx.Execute<Switch>(SwitchEditOut, m => m.SwitchEditOut(ctx));
|
2019-10-05 05:41:00 +00:00
|
|
|
else
|
2021-11-27 02:10:56 +00:00
|
|
|
await ctx.Execute<Switch>(SwitchEdit, m => m.SwitchEdit(ctx));
|
|
|
|
else if (ctx.Match("delete", "remove", "erase", "cancel", "yeet"))
|
|
|
|
await ctx.Execute<Switch>(SwitchDelete, m => m.SwitchDelete(ctx));
|
|
|
|
else if (ctx.Match("commands", "help"))
|
|
|
|
await PrintCommandList(ctx, "switching", SwitchCommands);
|
|
|
|
else if (ctx.HasNext()) // there are following arguments
|
|
|
|
await ctx.Execute<Switch>(Switch, m => m.SwitchDo(ctx));
|
|
|
|
else
|
|
|
|
await PrintCommandNotFoundError(ctx, Switch, SwitchOut, SwitchMove, SwitchEdit, SwitchEditOut,
|
|
|
|
SwitchDelete, SystemFronter, SystemFrontHistory);
|
|
|
|
}
|
2019-10-05 05:41:00 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
private async Task CommandHelpRoot(Context ctx)
|
|
|
|
{
|
|
|
|
if (!ctx.HasNext())
|
2021-08-27 15:03:47 +00:00
|
|
|
{
|
2021-11-27 02:10:56 +00:00
|
|
|
await ctx.Reply(
|
2022-01-19 22:40:27 +00:00
|
|
|
"Available command help targets: `system`, `member`, `group`, `switch`, `config`, `autoproxy`, `log`, `blacklist`."
|
2021-11-27 02:10:56 +00:00
|
|
|
+ "\n- **pk;commands <target>** - *View commands related to a help target.*"
|
|
|
|
+ "\n\nFor the full list of commands, see the website: <https://pluralkit.me/commands>");
|
|
|
|
return;
|
2020-11-19 22:58:57 +00:00
|
|
|
}
|
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
switch (ctx.PeekArgument())
|
2020-11-21 01:48:33 +00:00
|
|
|
{
|
2021-11-27 02:10:56 +00:00
|
|
|
case "system":
|
|
|
|
case "systems":
|
|
|
|
case "s":
|
|
|
|
await PrintCommandList(ctx, "systems", SystemCommands);
|
|
|
|
break;
|
|
|
|
case "member":
|
|
|
|
case "members":
|
|
|
|
case "m":
|
|
|
|
await PrintCommandList(ctx, "members", MemberCommands);
|
|
|
|
break;
|
|
|
|
case "group":
|
|
|
|
case "groups":
|
|
|
|
case "g":
|
|
|
|
await PrintCommandList(ctx, "groups", GroupCommands);
|
|
|
|
break;
|
|
|
|
case "switch":
|
|
|
|
case "switches":
|
|
|
|
case "switching":
|
|
|
|
case "sw":
|
|
|
|
await PrintCommandList(ctx, "switching", SwitchCommands);
|
|
|
|
break;
|
|
|
|
case "log":
|
|
|
|
await PrintCommandList(ctx, "message logging", LogCommands);
|
|
|
|
break;
|
|
|
|
case "blacklist":
|
|
|
|
case "bl":
|
|
|
|
await PrintCommandList(ctx, "channel blacklisting", BlacklistCommands);
|
|
|
|
break;
|
2021-11-30 02:35:21 +00:00
|
|
|
case "config":
|
|
|
|
case "cfg":
|
|
|
|
await PrintCommandList(ctx, "settings", ConfigCommands);
|
2021-11-27 02:10:56 +00:00
|
|
|
break;
|
2022-01-19 22:40:27 +00:00
|
|
|
case "autoproxy":
|
|
|
|
case "ap":
|
|
|
|
await PrintCommandList(ctx, "autoproxy", AutoproxyCommands);
|
|
|
|
break;
|
2021-11-27 02:10:56 +00:00
|
|
|
default:
|
|
|
|
await ctx.Reply("For the full list of commands, see the website: <https://pluralkit.me/commands>");
|
|
|
|
break;
|
2020-11-21 01:48:33 +00:00
|
|
|
}
|
2021-11-27 02:10:56 +00:00
|
|
|
}
|
2020-11-21 01:48:33 +00:00
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
private Task HandleAutoproxyCommand(Context ctx)
|
|
|
|
{
|
|
|
|
// ctx.CheckSystem();
|
|
|
|
// oops, that breaks stuff! PKErrors before ctx.Execute don't actually do anything.
|
|
|
|
// so we just emulate checking and throwing an error.
|
|
|
|
if (ctx.System == null)
|
|
|
|
return ctx.Reply($"{Emojis.Error} {Errors.NoSystemError.Message}");
|
|
|
|
|
2021-11-30 02:35:21 +00:00
|
|
|
// todo: move this whole block to Autoproxy.cs when these are removed
|
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
if (ctx.Match("account", "ac"))
|
2021-11-30 02:35:21 +00:00
|
|
|
return ctx.Execute<Config>(ConfigAutoproxyAccount, m => m.AutoproxyAccount(ctx), true);
|
2021-11-27 02:10:56 +00:00
|
|
|
if (ctx.Match("timeout", "tm"))
|
2021-11-30 02:35:21 +00:00
|
|
|
return ctx.Execute<Config>(ConfigAutoproxyTimeout, m => m.AutoproxyTimeout(ctx), true);
|
|
|
|
|
2021-11-27 02:10:56 +00:00
|
|
|
return ctx.Execute<Autoproxy>(AutoproxySet, m => m.SetAutoproxyMode(ctx));
|
|
|
|
}
|
2021-11-30 02:35:21 +00:00
|
|
|
|
|
|
|
private Task HandleConfigCommand(Context ctx)
|
|
|
|
{
|
|
|
|
if (ctx.System == null)
|
|
|
|
return ctx.Reply($"{Emojis.Error} {Errors.NoSystemError.Message}");
|
|
|
|
|
|
|
|
if (!ctx.HasNext())
|
|
|
|
return ctx.Execute<Config>(null, m => m.ShowConfig(ctx));
|
|
|
|
|
|
|
|
if (ctx.MatchMultiple(new[] { "autoproxy", "ap" }, new[] { "account", "ac" }))
|
|
|
|
return ctx.Execute<Config>(null, m => m.AutoproxyAccount(ctx));
|
|
|
|
if (ctx.MatchMultiple(new[] { "autoproxy", "ap" }, new[] { "timeout", "tm" }))
|
|
|
|
return ctx.Execute<Config>(null, m => m.AutoproxyTimeout(ctx));
|
|
|
|
if (ctx.Match("timezone", "zone", "tz"))
|
|
|
|
return ctx.Execute<Config>(null, m => m.SystemTimezone(ctx));
|
|
|
|
if (ctx.Match("ping"))
|
|
|
|
return ctx.Execute<Config>(null, m => m.SystemPing(ctx));
|
2021-12-07 06:58:05 +00:00
|
|
|
if (ctx.MatchMultiple(new[] { "private" }, new[] { "member" }) || ctx.Match("mp"))
|
2021-12-01 16:48:49 +00:00
|
|
|
return ctx.Execute<Config>(null, m => m.MemberDefaultPrivacy(ctx));
|
2021-12-07 06:58:05 +00:00
|
|
|
if (ctx.MatchMultiple(new[] { "private" }, new[] { "group" }) || ctx.Match("gp"))
|
2021-12-01 16:48:49 +00:00
|
|
|
return ctx.Execute<Config>(null, m => m.GroupDefaultPrivacy(ctx));
|
2021-12-06 09:01:42 +00:00
|
|
|
if (ctx.MatchMultiple(new[] { "show" }, new[] { "private" }) || ctx.Match("sp"))
|
|
|
|
return ctx.Execute<Config>(null, m => m.ShowPrivateInfo(ctx));
|
2021-11-30 02:35:21 +00:00
|
|
|
|
|
|
|
// todo: maybe add the list of configuration keys here?
|
|
|
|
return ctx.Reply($"{Emojis.Error} Could not find a setting with that name. Please see `pk;commands config` for the list of possible config settings.");
|
|
|
|
}
|
2021-08-27 15:03:47 +00:00
|
|
|
}
|