remove rest of the parsing in csharp bot

This commit is contained in:
dusk 2025-10-08 03:26:40 +00:00
parent 15ffd16c01
commit 479e0a59b5
No known key found for this signature in database
35 changed files with 242 additions and 409 deletions

View file

@ -7,28 +7,13 @@ public partial class CommandTree
private async Task PrintCommandList(Context ctx, string subject, string commands) private async Task PrintCommandList(Context ctx, string subject, string commands)
{ {
await ctx.Reply( await ctx.Reply(
$"Here is a list of commands related to {subject}:", components: [
embed: new Embed() new MessageComponent()
{ {
Description = $"{commands}\nFor a full list of possible commands, see <https://pluralkit.me/commands>.", Type = ComponentType.Text,
Color = DiscordUtils.Blue, Content = $"Here is a list of commands related to {subject}:\n{commands}\nFor a full list of possible commands, see <https://pluralkit.me/commands>.",
} }
]
); );
} }
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.
var user = await ctx.Rest.GetUser(id);
if (user != null)
return $"Account **{user.Username}#{user.Discriminator}** does not have a system registered.";
return $"Account with ID `{id}` not found.";
}
return $"System with ID {input.AsCode()} not found.";
}
} }

View file

@ -22,13 +22,13 @@ public partial class CommandTree
Commands.MemberNew(var param, _) => ctx.Execute<Member>(MemberNew, m => m.NewMember(ctx, param.name)), Commands.MemberNew(var param, _) => ctx.Execute<Member>(MemberNew, m => m.NewMember(ctx, param.name)),
Commands.MemberSoulscream(var param, _) => ctx.Execute<Member>(MemberInfo, m => m.Soulscream(ctx, param.target)), Commands.MemberSoulscream(var param, _) => ctx.Execute<Member>(MemberInfo, m => m.Soulscream(ctx, param.target)),
Commands.MemberAvatarShow(var param, var flags) => ctx.Execute<MemberAvatar>(MemberAvatar, m => m.ShowAvatar(ctx, param.target, flags.GetReplyFormat())), Commands.MemberAvatarShow(var param, var flags) => ctx.Execute<MemberAvatar>(MemberAvatar, m => m.ShowAvatar(ctx, param.target, flags.GetReplyFormat())),
Commands.MemberAvatarClear(var param, var flags) => ctx.Execute<MemberAvatar>(MemberAvatar, m => m.ClearAvatar(ctx, param.target)), Commands.MemberAvatarClear(var param, var flags) => ctx.Execute<MemberAvatar>(MemberAvatar, m => m.ClearAvatar(ctx, param.target, flags.yes)),
Commands.MemberAvatarUpdate(var param, _) => ctx.Execute<MemberAvatar>(MemberAvatar, m => m.ChangeAvatar(ctx, param.target, param.avatar)), Commands.MemberAvatarUpdate(var param, _) => ctx.Execute<MemberAvatar>(MemberAvatar, m => m.ChangeAvatar(ctx, param.target, param.avatar)),
Commands.MemberWebhookAvatarShow(var param, var flags) => ctx.Execute<MemberAvatar>(MemberAvatar, m => m.ShowWebhookAvatar(ctx, param.target, flags.GetReplyFormat())), Commands.MemberWebhookAvatarShow(var param, var flags) => ctx.Execute<MemberAvatar>(MemberAvatar, m => m.ShowWebhookAvatar(ctx, param.target, flags.GetReplyFormat())),
Commands.MemberWebhookAvatarClear(var param, var flags) => ctx.Execute<MemberAvatar>(MemberAvatar, m => m.ClearWebhookAvatar(ctx, param.target)), Commands.MemberWebhookAvatarClear(var param, var flags) => ctx.Execute<MemberAvatar>(MemberAvatar, m => m.ClearWebhookAvatar(ctx, param.target, flags.yes)),
Commands.MemberWebhookAvatarUpdate(var param, _) => ctx.Execute<MemberAvatar>(MemberAvatar, m => m.ChangeWebhookAvatar(ctx, param.target, param.avatar)), Commands.MemberWebhookAvatarUpdate(var param, _) => ctx.Execute<MemberAvatar>(MemberAvatar, m => m.ChangeWebhookAvatar(ctx, param.target, param.avatar)),
Commands.MemberServerAvatarShow(var param, var flags) => ctx.Execute<MemberAvatar>(MemberAvatar, m => m.ShowServerAvatar(ctx, param.target, flags.GetReplyFormat())), Commands.MemberServerAvatarShow(var param, var flags) => ctx.Execute<MemberAvatar>(MemberAvatar, m => m.ShowServerAvatar(ctx, param.target, flags.GetReplyFormat())),
Commands.MemberServerAvatarClear(var param, var flags) => ctx.Execute<MemberAvatar>(MemberAvatar, m => m.ClearServerAvatar(ctx, param.target)), Commands.MemberServerAvatarClear(var param, var flags) => ctx.Execute<MemberAvatar>(MemberAvatar, m => m.ClearServerAvatar(ctx, param.target, flags.yes)),
Commands.MemberServerAvatarUpdate(var param, _) => ctx.Execute<MemberAvatar>(MemberAvatar, m => m.ChangeServerAvatar(ctx, param.target, param.avatar)), Commands.MemberServerAvatarUpdate(var param, _) => ctx.Execute<MemberAvatar>(MemberAvatar, m => m.ChangeServerAvatar(ctx, param.target, param.avatar)),
Commands.MemberPronounsShow(var param, var flags) => ctx.Execute<MemberEdit>(MemberPronouns, m => m.ShowPronouns(ctx, param.target, flags.GetReplyFormat())), Commands.MemberPronounsShow(var param, var flags) => ctx.Execute<MemberEdit>(MemberPronouns, m => m.ShowPronouns(ctx, param.target, flags.GetReplyFormat())),
Commands.MemberPronounsClear(var param, var flags) => ctx.Execute<MemberEdit>(MemberPronouns, m => m.ClearPronouns(ctx, param.target, flags.yes)), Commands.MemberPronounsClear(var param, var flags) => ctx.Execute<MemberEdit>(MemberPronouns, m => m.ClearPronouns(ctx, param.target, flags.yes)),
@ -37,7 +37,7 @@ public partial class CommandTree
Commands.MemberDescClear(var param, var flags) => ctx.Execute<MemberEdit>(MemberDesc, m => m.ClearDescription(ctx, param.target, flags.yes)), Commands.MemberDescClear(var param, var flags) => ctx.Execute<MemberEdit>(MemberDesc, m => m.ClearDescription(ctx, param.target, flags.yes)),
Commands.MemberDescUpdate(var param, _) => ctx.Execute<MemberEdit>(MemberDesc, m => m.ChangeDescription(ctx, param.target, param.description)), Commands.MemberDescUpdate(var param, _) => ctx.Execute<MemberEdit>(MemberDesc, m => m.ChangeDescription(ctx, param.target, param.description)),
Commands.MemberNameShow(var param, var flags) => ctx.Execute<MemberEdit>(MemberInfo, m => m.ShowName(ctx, param.target, flags.GetReplyFormat())), Commands.MemberNameShow(var param, var flags) => ctx.Execute<MemberEdit>(MemberInfo, m => m.ShowName(ctx, param.target, flags.GetReplyFormat())),
Commands.MemberNameUpdate(var param, _) => ctx.Execute<MemberEdit>(MemberInfo, m => m.ChangeName(ctx, param.target, param.name)), Commands.MemberNameUpdate(var param, var flags) => ctx.Execute<MemberEdit>(MemberInfo, m => m.ChangeName(ctx, param.target, param.name, flags.yes)),
Commands.MemberBannerShow(var param, var flags) => ctx.Execute<MemberEdit>(MemberBannerImage, m => m.ShowBannerImage(ctx, param.target, flags.GetReplyFormat())), Commands.MemberBannerShow(var param, var flags) => ctx.Execute<MemberEdit>(MemberBannerImage, m => m.ShowBannerImage(ctx, param.target, flags.GetReplyFormat())),
Commands.MemberBannerClear(var param, var flags) => ctx.Execute<MemberEdit>(MemberBannerImage, m => m.ClearBannerImage(ctx, param.target, flags.yes)), Commands.MemberBannerClear(var param, var flags) => ctx.Execute<MemberEdit>(MemberBannerImage, m => m.ClearBannerImage(ctx, param.target, flags.yes)),
Commands.MemberBannerUpdate(var param, _) => ctx.Execute<MemberEdit>(MemberBannerImage, m => m.ChangeBannerImage(ctx, param.target, param.banner)), Commands.MemberBannerUpdate(var param, _) => ctx.Execute<MemberEdit>(MemberBannerImage, m => m.ChangeBannerImage(ctx, param.target, param.banner)),
@ -59,7 +59,7 @@ public partial class CommandTree
Commands.MemberServerKeepproxyUpdate(var param, _) => ctx.Execute<MemberEdit>(MemberServerKeepProxy, m => m.ChangeServerKeepProxy(ctx, param.target, param.value)), Commands.MemberServerKeepproxyUpdate(var param, _) => ctx.Execute<MemberEdit>(MemberServerKeepProxy, m => m.ChangeServerKeepProxy(ctx, param.target, param.value)),
Commands.MemberServerKeepproxyClear(var param, var flags) => ctx.Execute<MemberEdit>(MemberServerKeepProxy, m => m.ClearServerKeepProxy(ctx, param.target, flags.yes)), Commands.MemberServerKeepproxyClear(var param, var flags) => ctx.Execute<MemberEdit>(MemberServerKeepProxy, m => m.ClearServerKeepProxy(ctx, param.target, flags.yes)),
Commands.MemberProxyShow(var param, _) => ctx.Execute<MemberProxy>(MemberProxy, m => m.ShowProxy(ctx, param.target)), Commands.MemberProxyShow(var param, _) => ctx.Execute<MemberProxy>(MemberProxy, m => m.ShowProxy(ctx, param.target)),
Commands.MemberProxyClear(var param, var flags) => ctx.Execute<MemberProxy>(MemberProxy, m => m.ClearProxy(ctx, param.target)), Commands.MemberProxyClear(var param, var flags) => ctx.Execute<MemberProxy>(MemberProxy, m => m.ClearProxy(ctx, param.target, flags.yes)),
Commands.MemberProxyAdd(var param, _) => ctx.Execute<MemberProxy>(MemberProxy, m => m.AddProxy(ctx, param.target, param.tag)), Commands.MemberProxyAdd(var param, _) => ctx.Execute<MemberProxy>(MemberProxy, m => m.AddProxy(ctx, param.target, param.tag)),
Commands.MemberProxyRemove(var param, _) => ctx.Execute<MemberProxy>(MemberProxy, m => m.RemoveProxy(ctx, param.target, param.tag)), Commands.MemberProxyRemove(var param, _) => ctx.Execute<MemberProxy>(MemberProxy, m => m.RemoveProxy(ctx, param.target, param.tag)),
Commands.MemberProxySet(var param, _) => ctx.Execute<MemberProxy>(MemberProxy, m => m.SetProxy(ctx, param.target, param.tags)), Commands.MemberProxySet(var param, _) => ctx.Execute<MemberProxy>(MemberProxy, m => m.SetProxy(ctx, param.target, param.tags)),
@ -205,7 +205,7 @@ public partial class CommandTree
Commands.SwitchDo(var param, _) => ctx.Execute<Switch>(Switch, m => m.SwitchDo(ctx, param.targets)), Commands.SwitchDo(var param, _) => ctx.Execute<Switch>(Switch, m => m.SwitchDo(ctx, param.targets)),
Commands.SwitchMove(var param, _) => ctx.Execute<Switch>(SwitchMove, m => m.SwitchMove(ctx, param.@string)), Commands.SwitchMove(var param, _) => ctx.Execute<Switch>(SwitchMove, m => m.SwitchMove(ctx, param.@string)),
Commands.SwitchEdit(var param, var flags) => ctx.Execute<Switch>(SwitchEdit, m => m.SwitchEdit(ctx, param.targets, false, flags.first, flags.remove, flags.append, flags.prepend)), Commands.SwitchEdit(var param, var flags) => ctx.Execute<Switch>(SwitchEdit, m => m.SwitchEdit(ctx, param.targets, false, flags.first, flags.remove, flags.append, flags.prepend)),
Commands.SwitchEditOut(_, _) => ctx.Execute<Switch>(SwitchEditOut, m => m.SwitchEditOut(ctx)), Commands.SwitchEditOut(_, var flags) => ctx.Execute<Switch>(SwitchEditOut, m => m.SwitchEditOut(ctx, flags.yes)),
Commands.SwitchDelete(var param, var flags) => ctx.Execute<Switch>(SwitchDelete, m => m.SwitchDelete(ctx, flags.all)), Commands.SwitchDelete(var param, var flags) => ctx.Execute<Switch>(SwitchDelete, m => m.SwitchDelete(ctx, flags.all)),
Commands.SwitchCopy(var param, var flags) => ctx.Execute<Switch>(SwitchCopy, m => m.SwitchEdit(ctx, param.targets, true, flags.first, flags.remove, flags.append, flags.prepend)), Commands.SwitchCopy(var param, var flags) => ctx.Execute<Switch>(SwitchCopy, m => m.SwitchEdit(ctx, param.targets, true, flags.first, flags.remove, flags.append, flags.prepend)),
Commands.SystemFronter(var param, var flags) => ctx.Execute<SystemFront>(SystemFronter, m => m.Fronter(ctx, param.target)), Commands.SystemFronter(var param, var flags) => ctx.Execute<SystemFront>(SystemFronter, m => m.Fronter(ctx, param.target)),
@ -213,7 +213,9 @@ public partial class CommandTree
Commands.SystemFronterPercent(var param, var flags) => ctx.Execute<SystemFront>(SystemFrontPercent, m => m.FrontPercent(ctx, param.target, flags.duration, flags.fronters_only, flags.flat)), Commands.SystemFronterPercent(var param, var flags) => ctx.Execute<SystemFront>(SystemFrontPercent, m => m.FrontPercent(ctx, param.target, flags.duration, flags.fronters_only, flags.flat)),
Commands.SystemDisplayId(var param, _) => ctx.Execute<System>(SystemId, m => m.DisplayId(ctx, param.target)), Commands.SystemDisplayId(var param, _) => ctx.Execute<System>(SystemId, m => m.DisplayId(ctx, param.target)),
Commands.SystemDisplayIdSelf => ctx.Execute<System>(SystemId, m => m.DisplayId(ctx, ctx.System)), Commands.SystemDisplayIdSelf => ctx.Execute<System>(SystemId, m => m.DisplayId(ctx, ctx.System)),
Commands.SystemWebhook => ctx.Execute<Api>(null, m => m.SystemWebhook(ctx)), Commands.SystemWebhookShow => ctx.Execute<Api>(null, m => m.GetSystemWebhook(ctx)),
Commands.SystemWebhookClear(_, var flags) => ctx.Execute<Api>(null, m => m.ClearSystemWebhook(ctx, flags.yes)),
Commands.SystemWebhookSet(var param, _) => ctx.Execute<Api>(null, m => m.SetSystemWebhook(ctx, param.url)),
Commands.RandomSelf(_, var flags) => Commands.RandomSelf(_, var flags) =>
flags.group flags.group
? ctx.Execute<Random>(GroupRandom, m => m.Group(ctx, ctx.System, flags.all, flags.show_embed)) ? ctx.Execute<Random>(GroupRandom, m => m.Group(ctx, ctx.System, flags.all, flags.show_embed))
@ -224,21 +226,21 @@ public partial class CommandTree
: ctx.Execute<Random>(MemberRandom, m => m.Member(ctx, param.target, flags.all, flags.show_embed)), : ctx.Execute<Random>(MemberRandom, m => m.Member(ctx, param.target, flags.all, flags.show_embed)),
Commands.GroupRandomMember(var param, var flags) => ctx.Execute<Random>(GroupMemberRandom, m => m.GroupMember(ctx, param.target, flags)), Commands.GroupRandomMember(var param, var flags) => ctx.Execute<Random>(GroupMemberRandom, m => m.GroupMember(ctx, param.target, flags)),
Commands.SystemLink(var param, _) => ctx.Execute<SystemLink>(Link, m => m.LinkSystem(ctx, param.account)), Commands.SystemLink(var param, _) => ctx.Execute<SystemLink>(Link, m => m.LinkSystem(ctx, param.account)),
Commands.SystemUnlink(var param, _) => ctx.Execute<SystemLink>(Unlink, m => m.UnlinkAccount(ctx, param.account)), Commands.SystemUnlink(var param, var flags) => ctx.Execute<SystemLink>(Unlink, m => m.UnlinkAccount(ctx, param.account, flags.yes)),
Commands.SystemMembersListSelf(var param, var flags) => ctx.Execute<SystemList>(SystemList, m => m.MemberList(ctx, ctx.System, null, flags)), Commands.SystemMembersListSelf(var param, var flags) => ctx.Execute<SystemList>(SystemList, m => m.MemberList(ctx, ctx.System, null, flags)),
Commands.SystemMembersSearchSelf(var param, var flags) => ctx.Execute<SystemList>(SystemFind, m => m.MemberList(ctx, ctx.System, param.query, flags)), Commands.SystemMembersSearchSelf(var param, var flags) => ctx.Execute<SystemList>(SystemFind, m => m.MemberList(ctx, ctx.System, param.query, flags)),
Commands.SystemMembersList(var param, var flags) => ctx.Execute<SystemList>(SystemList, m => m.MemberList(ctx, param.target, null, flags)), Commands.SystemMembersList(var param, var flags) => ctx.Execute<SystemList>(SystemList, m => m.MemberList(ctx, param.target, null, flags)),
Commands.SystemMembersSearch(var param, var flags) => ctx.Execute<SystemList>(SystemFind, m => m.MemberList(ctx, param.target, param.query, flags)), Commands.SystemMembersSearch(var param, var flags) => ctx.Execute<SystemList>(SystemFind, m => m.MemberList(ctx, param.target, param.query, flags)),
Commands.MemberListGroups(var param, var flags) => ctx.Execute<GroupMember>(MemberGroups, m => m.ListMemberGroups(ctx, param.target, null, flags)), Commands.MemberListGroups(var param, var flags) => ctx.Execute<GroupMember>(MemberGroups, m => m.ListMemberGroups(ctx, param.target, null, flags, flags.all)),
Commands.MemberSearchGroups(var param, var flags) => ctx.Execute<GroupMember>(MemberGroups, m => m.ListMemberGroups(ctx, param.target, param.query, flags)), Commands.MemberSearchGroups(var param, var flags) => ctx.Execute<GroupMember>(MemberGroups, m => m.ListMemberGroups(ctx, param.target, param.query, flags, flags.all)),
Commands.GroupListMembers(var param, var flags) => ctx.Execute<GroupMember>(GroupMemberList, m => m.ListGroupMembers(ctx, param.target, null, flags)), Commands.GroupListMembers(var param, var flags) => ctx.Execute<GroupMember>(GroupMemberList, m => m.ListGroupMembers(ctx, param.target, null, flags)),
Commands.GroupSearchMembers(var param, var flags) => ctx.Execute<GroupMember>(GroupMemberList, m => m.ListGroupMembers(ctx, param.target, param.query, flags)), Commands.GroupSearchMembers(var param, var flags) => ctx.Execute<GroupMember>(GroupMemberList, m => m.ListGroupMembers(ctx, param.target, param.query, flags)),
Commands.SystemListGroups(var param, var flags) => ctx.Execute<Groups>(GroupList, g => g.ListSystemGroups(ctx, param.target, null, flags)), Commands.SystemListGroups(var param, var flags) => ctx.Execute<Groups>(GroupList, g => g.ListSystemGroups(ctx, param.target, null, flags, flags.all)),
Commands.SystemSearchGroups(var param, var flags) => ctx.Execute<Groups>(GroupList, g => g.ListSystemGroups(ctx, param.target, param.query, flags)), Commands.SystemSearchGroups(var param, var flags) => ctx.Execute<Groups>(GroupList, g => g.ListSystemGroups(ctx, param.target, param.query, flags, flags.all)),
Commands.GroupListGroups(var param, var flags) => ctx.Execute<Groups>(GroupList, g => g.ListSystemGroups(ctx, ctx.System, null, flags)), Commands.GroupListGroups(var param, var flags) => ctx.Execute<Groups>(GroupList, g => g.ListSystemGroups(ctx, ctx.System, null, flags, flags.all)),
Commands.GroupSearchGroups(var param, var flags) => ctx.Execute<Groups>(GroupList, g => g.ListSystemGroups(ctx, ctx.System, param.query, flags)), Commands.GroupSearchGroups(var param, var flags) => ctx.Execute<Groups>(GroupList, g => g.ListSystemGroups(ctx, ctx.System, param.query, flags, flags.all)),
Commands.GroupNew(var param, _) => ctx.Execute<Groups>(GroupNew, g => g.CreateGroup(ctx, param.name)), Commands.GroupNew(var param, _) => ctx.Execute<Groups>(GroupNew, g => g.CreateGroup(ctx, param.name)),
Commands.GroupInfo(var param, _) => ctx.Execute<Groups>(GroupInfo, g => g.ShowGroupCard(ctx, param.target)), Commands.GroupInfo(var param, var flags) => ctx.Execute<Groups>(GroupInfo, g => g.ShowGroupCard(ctx, param.target, flags.show_embed, flags.all)),
Commands.GroupShowName(var param, var flags) => ctx.Execute<Groups>(GroupRename, g => g.ShowGroupDisplayName(ctx, param.target, flags.GetReplyFormat())), Commands.GroupShowName(var param, var flags) => ctx.Execute<Groups>(GroupRename, g => g.ShowGroupDisplayName(ctx, param.target, flags.GetReplyFormat())),
Commands.GroupClearName(var param, var flags) => ctx.Execute<Groups>(GroupRename, g => g.RenameGroup(ctx, param.target, null)), Commands.GroupClearName(var param, var flags) => ctx.Execute<Groups>(GroupRename, g => g.RenameGroup(ctx, param.target, null)),
Commands.GroupRename(var param, _) => ctx.Execute<Groups>(GroupRename, g => g.RenameGroup(ctx, param.target, param.name)), Commands.GroupRename(var param, _) => ctx.Execute<Groups>(GroupRename, g => g.RenameGroup(ctx, param.target, param.name)),
@ -249,16 +251,16 @@ public partial class CommandTree
Commands.GroupClearDescription(var param, var flags) => ctx.Execute<Groups>(GroupDesc, g => g.ClearGroupDescription(ctx, param.target)), Commands.GroupClearDescription(var param, var flags) => ctx.Execute<Groups>(GroupDesc, g => g.ClearGroupDescription(ctx, param.target)),
Commands.GroupChangeDescription(var param, _) => ctx.Execute<Groups>(GroupDesc, g => g.ChangeGroupDescription(ctx, param.target, param.description)), Commands.GroupChangeDescription(var param, _) => ctx.Execute<Groups>(GroupDesc, g => g.ChangeGroupDescription(ctx, param.target, param.description)),
Commands.GroupShowIcon(var param, var flags) => ctx.Execute<Groups>(GroupIcon, g => g.ShowGroupIcon(ctx, param.target, flags.GetReplyFormat())), Commands.GroupShowIcon(var param, var flags) => ctx.Execute<Groups>(GroupIcon, g => g.ShowGroupIcon(ctx, param.target, flags.GetReplyFormat())),
Commands.GroupClearIcon(var param, var flags) => ctx.Execute<Groups>(GroupIcon, g => g.ClearGroupIcon(ctx, param.target)), Commands.GroupClearIcon(var param, var flags) => ctx.Execute<Groups>(GroupIcon, g => g.ClearGroupIcon(ctx, param.target, flags.yes)),
Commands.GroupChangeIcon(var param, _) => ctx.Execute<Groups>(GroupIcon, g => g.ChangeGroupIcon(ctx, param.target, param.icon)), Commands.GroupChangeIcon(var param, _) => ctx.Execute<Groups>(GroupIcon, g => g.ChangeGroupIcon(ctx, param.target, param.icon)),
Commands.GroupShowBanner(var param, var flags) => ctx.Execute<Groups>(GroupBannerImage, g => g.ShowGroupBanner(ctx, param.target, flags.GetReplyFormat())), Commands.GroupShowBanner(var param, var flags) => ctx.Execute<Groups>(GroupBannerImage, g => g.ShowGroupBanner(ctx, param.target, flags.GetReplyFormat())),
Commands.GroupClearBanner(var param, var flags) => ctx.Execute<Groups>(GroupBannerImage, g => g.ClearGroupBanner(ctx, param.target)), Commands.GroupClearBanner(var param, var flags) => ctx.Execute<Groups>(GroupBannerImage, g => g.ClearGroupBanner(ctx, param.target, flags.yes)),
Commands.GroupChangeBanner(var param, _) => ctx.Execute<Groups>(GroupBannerImage, g => g.ChangeGroupBanner(ctx, param.target, param.banner)), Commands.GroupChangeBanner(var param, _) => ctx.Execute<Groups>(GroupBannerImage, g => g.ChangeGroupBanner(ctx, param.target, param.banner)),
Commands.GroupShowColor(var param, var flags) => ctx.Execute<Groups>(GroupColor, g => g.ShowGroupColor(ctx, param.target, flags.GetReplyFormat())), Commands.GroupShowColor(var param, var flags) => ctx.Execute<Groups>(GroupColor, g => g.ShowGroupColor(ctx, param.target, flags.GetReplyFormat())),
Commands.GroupClearColor(var param, var flags) => ctx.Execute<Groups>(GroupColor, g => g.ClearGroupColor(ctx, param.target)), Commands.GroupClearColor(var param, var flags) => ctx.Execute<Groups>(GroupColor, g => g.ClearGroupColor(ctx, param.target)),
Commands.GroupChangeColor(var param, _) => ctx.Execute<Groups>(GroupColor, g => g.ChangeGroupColor(ctx, param.target, param.color)), Commands.GroupChangeColor(var param, _) => ctx.Execute<Groups>(GroupColor, g => g.ChangeGroupColor(ctx, param.target, param.color)),
Commands.GroupAddMember(var param, var flags) => ctx.Execute<GroupMember>(GroupAdd, g => g.AddRemoveMembers(ctx, param.target, param.targets, Groups.AddRemoveOperation.Add, flags.all)), Commands.GroupAddMember(var param, var flags) => ctx.Execute<GroupMember>(GroupAdd, g => g.AddRemoveMembers(ctx, param.target, param.targets, Groups.AddRemoveOperation.Add, flags.all, flags.yes)),
Commands.GroupRemoveMember(var param, var flags) => ctx.Execute<GroupMember>(GroupRemove, g => g.AddRemoveMembers(ctx, param.target, param.targets, Groups.AddRemoveOperation.Remove, flags.all)), Commands.GroupRemoveMember(var param, var flags) => ctx.Execute<GroupMember>(GroupRemove, g => g.AddRemoveMembers(ctx, param.target, param.targets, Groups.AddRemoveOperation.Remove, flags.all, flags.yes)),
Commands.GroupShowPrivacy(var param, _) => ctx.Execute<Groups>(GroupPrivacy, g => g.ShowGroupPrivacy(ctx, param.target)), Commands.GroupShowPrivacy(var param, _) => ctx.Execute<Groups>(GroupPrivacy, g => g.ShowGroupPrivacy(ctx, param.target)),
Commands.GroupChangePrivacyAll(var param, _) => ctx.Execute<Groups>(GroupPrivacy, g => g.SetAllGroupPrivacy(ctx, param.target, param.level)), Commands.GroupChangePrivacyAll(var param, _) => ctx.Execute<Groups>(GroupPrivacy, g => g.SetAllGroupPrivacy(ctx, param.target, param.level)),
Commands.GroupChangePrivacy(var param, _) => ctx.Execute<Groups>(GroupPrivacy, g => g.SetGroupPrivacy(ctx, param.target, param.privacy, param.level)), Commands.GroupChangePrivacy(var param, _) => ctx.Execute<Groups>(GroupPrivacy, g => g.SetGroupPrivacy(ctx, param.target, param.privacy, param.level)),
@ -282,12 +284,12 @@ public partial class CommandTree
Commands.MessageDelete(var param, var flags) => ctx.Execute<ProxiedMessage>(Message, m => m.GetMessage(ctx, param.target.MessageId, flags.GetReplyFormat(), true, false)), Commands.MessageDelete(var param, var flags) => ctx.Execute<ProxiedMessage>(Message, m => m.GetMessage(ctx, param.target.MessageId, flags.GetReplyFormat(), true, false)),
Commands.MessageEdit(var param, var flags) => ctx.Execute<ProxiedMessage>(MessageEdit, m => m.EditMessage(ctx, param.target.MessageId, param.new_content, flags.regex, flags.mutate_space, flags.append, flags.prepend, flags.clear_embeds, flags.clear_attachments)), Commands.MessageEdit(var param, var flags) => ctx.Execute<ProxiedMessage>(MessageEdit, m => m.EditMessage(ctx, param.target.MessageId, param.new_content, flags.regex, flags.mutate_space, flags.append, flags.prepend, flags.clear_embeds, flags.clear_attachments)),
Commands.MessageReproxy(var param, _) => ctx.Execute<ProxiedMessage>(MessageReproxy, m => m.ReproxyMessage(ctx, param.msg.MessageId, param.member)), Commands.MessageReproxy(var param, _) => ctx.Execute<ProxiedMessage>(MessageReproxy, m => m.ReproxyMessage(ctx, param.msg.MessageId, param.member)),
Commands.Import(var param, _) => ctx.Execute<ImportExport>(Import, m => m.Import(ctx, param.url)), Commands.Import(var param, var flags) => ctx.Execute<ImportExport>(Import, m => m.Import(ctx, param.url, flags.yes)),
Commands.Export(_, _) => ctx.Execute<ImportExport>(Export, m => m.Export(ctx)), Commands.Export(_, _) => ctx.Execute<ImportExport>(Export, m => m.Export(ctx)),
Commands.ServerConfigShow => ctx.Execute<ServerConfig>(null, m => m.ShowConfig(ctx)), Commands.ServerConfigShow => ctx.Execute<ServerConfig>(null, m => m.ShowConfig(ctx)),
Commands.ServerConfigLogChannelShow => ctx.Execute<ServerConfig>(null, m => m.ShowLogChannel(ctx)), Commands.ServerConfigLogChannelShow => ctx.Execute<ServerConfig>(null, m => m.ShowLogChannel(ctx)),
Commands.ServerConfigLogChannelSet(var param, _) => ctx.Execute<ServerConfig>(null, m => m.SetLogChannel(ctx, param.channel)), Commands.ServerConfigLogChannelSet(var param, _) => ctx.Execute<ServerConfig>(null, m => m.SetLogChannel(ctx, param.channel)),
Commands.ServerConfigLogChannelClear => ctx.Execute<ServerConfig>(null, m => m.ClearLogChannel(ctx)), Commands.ServerConfigLogChannelClear(_, var flags) => ctx.Execute<ServerConfig>(null, m => m.ClearLogChannel(ctx, flags.yes)),
Commands.ServerConfigLogCleanupShow => ctx.Execute<ServerConfig>(null, m => m.ShowLogCleanup(ctx)), Commands.ServerConfigLogCleanupShow => ctx.Execute<ServerConfig>(null, m => m.ShowLogCleanup(ctx)),
Commands.ServerConfigLogCleanupSet(var param, _) => ctx.Execute<ServerConfig>(null, m => m.SetLogCleanup(ctx, param.toggle)), Commands.ServerConfigLogCleanupSet(var param, _) => ctx.Execute<ServerConfig>(null, m => m.SetLogCleanup(ctx, param.toggle)),
Commands.ServerConfigLogBlacklistShow => ctx.Execute<ServerConfig>(null, m => m.ShowLogBlacklist(ctx)), Commands.ServerConfigLogBlacklistShow => ctx.Execute<ServerConfig>(null, m => m.ShowLogBlacklist(ctx)),
@ -302,27 +304,27 @@ public partial class CommandTree
Commands.ServerConfigRequireSystemTagSet(var param, _) => ctx.Execute<ServerConfig>(null, m => m.SetRequireSystemTag(ctx, param.toggle)), Commands.ServerConfigRequireSystemTagSet(var param, _) => ctx.Execute<ServerConfig>(null, m => m.SetRequireSystemTag(ctx, param.toggle)),
Commands.ServerConfigSuppressNotificationsShow => ctx.Execute<ServerConfig>(null, m => m.ShowSuppressNotifications(ctx)), Commands.ServerConfigSuppressNotificationsShow => ctx.Execute<ServerConfig>(null, m => m.ShowSuppressNotifications(ctx)),
Commands.ServerConfigSuppressNotificationsSet(var param, _) => ctx.Execute<ServerConfig>(null, m => m.SetSuppressNotifications(ctx, param.toggle)), Commands.ServerConfigSuppressNotificationsSet(var param, _) => ctx.Execute<ServerConfig>(null, m => m.SetSuppressNotifications(ctx, param.toggle)),
Commands.AdminUpdateSystemId(var param, _) => ctx.Execute<Admin>(null, m => m.UpdateSystemId(ctx, param.target, param.new_hid)), Commands.AdminUpdateSystemId(var param, var flags) => ctx.Execute<Admin>(null, m => m.UpdateSystemId(ctx, param.target, param.new_hid, flags.yes)),
Commands.AdminUpdateMemberId(var param, _) => ctx.Execute<Admin>(null, m => m.UpdateMemberId(ctx, param.target, param.new_hid)), Commands.AdminUpdateMemberId(var param, var flags) => ctx.Execute<Admin>(null, m => m.UpdateMemberId(ctx, param.target, param.new_hid, flags.yes)),
Commands.AdminUpdateGroupId(var param, _) => ctx.Execute<Admin>(null, m => m.UpdateGroupId(ctx, param.target, param.new_hid)), Commands.AdminUpdateGroupId(var param, var flags) => ctx.Execute<Admin>(null, m => m.UpdateGroupId(ctx, param.target, param.new_hid, flags.yes)),
Commands.AdminRerollSystemId(var param, _) => ctx.Execute<Admin>(null, m => m.RerollSystemId(ctx, param.target)), Commands.AdminRerollSystemId(var param, var flags) => ctx.Execute<Admin>(null, m => m.RerollSystemId(ctx, param.target, flags.yes)),
Commands.AdminRerollMemberId(var param, _) => ctx.Execute<Admin>(null, m => m.RerollMemberId(ctx, param.target)), Commands.AdminRerollMemberId(var param, var flags) => ctx.Execute<Admin>(null, m => m.RerollMemberId(ctx, param.target, flags.yes)),
Commands.AdminRerollGroupId(var param, _) => ctx.Execute<Admin>(null, m => m.RerollGroupId(ctx, param.target)), Commands.AdminRerollGroupId(var param, var flags) => ctx.Execute<Admin>(null, m => m.RerollGroupId(ctx, param.target, flags.yes)),
Commands.AdminSystemMemberLimit(var param, _) => ctx.Execute<Admin>(null, m => m.SystemMemberLimit(ctx, param.target, param.limit)), Commands.AdminSystemMemberLimit(var param, var flags) => ctx.Execute<Admin>(null, m => m.SystemMemberLimit(ctx, param.target, param.limit, flags.yes)),
Commands.AdminSystemGroupLimit(var param, _) => ctx.Execute<Admin>(null, m => m.SystemGroupLimit(ctx, param.target, param.limit)), Commands.AdminSystemGroupLimit(var param, var flags) => ctx.Execute<Admin>(null, m => m.SystemGroupLimit(ctx, param.target, param.limit, flags.yes)),
Commands.AdminSystemRecover(var param, var flags) => ctx.Execute<Admin>(null, m => m.SystemRecover(ctx, param.token, param.account, flags.reroll_token)), Commands.AdminSystemRecover(var param, var flags) => ctx.Execute<Admin>(null, m => m.SystemRecover(ctx, param.token, param.account, flags.reroll_token, flags.yes)),
Commands.AdminSystemDelete(var param, _) => ctx.Execute<Admin>(null, m => m.SystemDelete(ctx, param.target)), Commands.AdminSystemDelete(var param, _) => ctx.Execute<Admin>(null, m => m.SystemDelete(ctx, param.target)),
Commands.AdminSendMessage(var param, _) => ctx.Execute<Admin>(null, m => m.SendAdminMessage(ctx, param.account, param.content)), Commands.AdminSendMessage(var param, _) => ctx.Execute<Admin>(null, m => m.SendAdminMessage(ctx, param.account, param.content)),
Commands.AdminAbuselogCreate(var param, var flags) => ctx.Execute<Admin>(null, m => m.AbuseLogCreate(ctx, param.account, flags.deny_boy_usage, param.description)), Commands.AdminAbuselogCreate(var param, var flags) => ctx.Execute<Admin>(null, m => m.AbuseLogCreate(ctx, param.account, flags.deny_boy_usage, param.description)),
Commands.AdminAbuselogShowAccount(var param, _) => ctx.Execute<Admin>(null, m => m.AbuseLogShow(ctx, param.account, null)), Commands.AdminAbuselogShowAccount(var param, _) => ctx.Execute<Admin>(null, m => m.AbuseLogShow(ctx, param.account, null)),
Commands.AdminAbuselogFlagDenyAccount(var param, _) => ctx.Execute<Admin>(null, m => m.AbuseLogFlagDeny(ctx, param.account, null, param.value)), Commands.AdminAbuselogFlagDenyAccount(var param, _) => ctx.Execute<Admin>(null, m => m.AbuseLogFlagDeny(ctx, param.account, null, param.value)),
Commands.AdminAbuselogDescriptionAccount(var param, var flags) => ctx.Execute<Admin>(null, m => m.AbuseLogDescription(ctx, param.account, null, param.desc, flags.clear)), Commands.AdminAbuselogDescriptionAccount(var param, var flags) => ctx.Execute<Admin>(null, m => m.AbuseLogDescription(ctx, param.account, null, param.desc, flags.clear, flags.yes)),
Commands.AdminAbuselogAddUserAccount(var param, _) => ctx.Execute<Admin>(null, m => m.AbuseLogAddUser(ctx, param.account, null, ctx.Author)), Commands.AdminAbuselogAddUserAccount(var param, _) => ctx.Execute<Admin>(null, m => m.AbuseLogAddUser(ctx, param.account, null, ctx.Author)),
Commands.AdminAbuselogRemoveUserAccount(var param, _) => ctx.Execute<Admin>(null, m => m.AbuseLogRemoveUser(ctx, param.account, null, ctx.Author)), Commands.AdminAbuselogRemoveUserAccount(var param, _) => ctx.Execute<Admin>(null, m => m.AbuseLogRemoveUser(ctx, param.account, null, ctx.Author)),
Commands.AdminAbuselogDeleteAccount(var param, _) => ctx.Execute<Admin>(null, m => m.AbuseLogDelete(ctx, param.account, null)), Commands.AdminAbuselogDeleteAccount(var param, _) => ctx.Execute<Admin>(null, m => m.AbuseLogDelete(ctx, param.account, null)),
Commands.AdminAbuselogShowLogId(var param, _) => ctx.Execute<Admin>(null, m => m.AbuseLogShow(ctx, null, param.log_id)), Commands.AdminAbuselogShowLogId(var param, _) => ctx.Execute<Admin>(null, m => m.AbuseLogShow(ctx, null, param.log_id)),
Commands.AdminAbuselogFlagDenyLogId(var param, _) => ctx.Execute<Admin>(null, m => m.AbuseLogFlagDeny(ctx, null, param.log_id, param.value)), Commands.AdminAbuselogFlagDenyLogId(var param, _) => ctx.Execute<Admin>(null, m => m.AbuseLogFlagDeny(ctx, null, param.log_id, param.value)),
Commands.AdminAbuselogDescriptionLogId(var param, var flags) => ctx.Execute<Admin>(null, m => m.AbuseLogDescription(ctx, null, param.log_id, param.desc, flags.clear)), Commands.AdminAbuselogDescriptionLogId(var param, var flags) => ctx.Execute<Admin>(null, m => m.AbuseLogDescription(ctx, null, param.log_id, param.desc, flags.clear, flags.yes)),
Commands.AdminAbuselogAddUserLogId(var param, _) => ctx.Execute<Admin>(null, m => m.AbuseLogAddUser(ctx, null, param.log_id, ctx.Author)), Commands.AdminAbuselogAddUserLogId(var param, _) => ctx.Execute<Admin>(null, m => m.AbuseLogAddUser(ctx, null, param.log_id, ctx.Author)),
Commands.AdminAbuselogRemoveUserLogId(var param, _) => ctx.Execute<Admin>(null, m => m.AbuseLogRemoveUser(ctx, null, param.log_id, ctx.Author)), Commands.AdminAbuselogRemoveUserLogId(var param, _) => ctx.Execute<Admin>(null, m => m.AbuseLogRemoveUser(ctx, null, param.log_id, ctx.Author)),
Commands.AdminAbuselogDeleteLogId(var param, _) => ctx.Execute<Admin>(null, m => m.AbuseLogDelete(ctx, null, param.log_id)), Commands.AdminAbuselogDeleteLogId(var param, _) => ctx.Execute<Admin>(null, m => m.AbuseLogDelete(ctx, null, param.log_id)),

View file

@ -2,110 +2,10 @@ using System.Text.RegularExpressions;
using Myriad.Types; using Myriad.Types;
using PluralKit.Core;
namespace PluralKit.Bot; namespace PluralKit.Bot;
public static class ContextArgumentsExt public static class ContextArgumentsExt
{ {
public static string PopArgument(this Context ctx) => throw new PKError("todo: PopArgument");
public static string PeekArgument(this Context ctx) => throw new PKError("todo: PeekArgument");
public static string RemainderOrNull(this Context ctx, bool skipFlags = true) => throw new PKError("todo: RemainderOrNull");
public static bool HasNext(this Context ctx, bool skipFlags = true) => throw new PKError("todo: HasNext");
public static string FullCommand(this Context ctx) => throw new PKError("todo: FullCommand");
/// <summary>
/// Checks if the next parameter is equal to one of the given keywords and pops it from the stack. Case-insensitive.
/// </summary>
public static bool Match(this Context ctx, ref string used, params string[] potentialMatches)
{
var arg = ctx.PeekArgument();
foreach (var match in potentialMatches)
if (arg.Equals(match, StringComparison.InvariantCultureIgnoreCase))
{
used = ctx.PopArgument();
return true;
}
return false;
}
/// <summary>
/// Checks if the next parameter is equal to one of the given keywords. Case-insensitive.
/// </summary>
public static bool Match(this Context ctx, params string[] potentialMatches)
{
string used = null; // Unused and unreturned, we just yeet it
return ctx.Match(ref used, potentialMatches);
}
/// <summary>
/// Checks if the next parameter (starting from `ptr`) is equal to one of the given keywords, and leaves it on the stack. Case-insensitive.
/// </summary>
public static bool PeekMatch(this Context ctx, ref int ptr, string[] potentialMatches)
{
throw new PKError("todo: PeekMatch");
}
/// <summary>
/// Matches the next *n* parameters against each parameter consecutively.
/// <br />
/// Note that this is handled differently than single-parameter Match:
/// each method parameter is an array of potential matches for the *n*th command string parameter.
/// </summary>
public static bool MatchMultiple(this Context ctx, params string[][] potentialParametersMatches)
{
throw new PKError("todo: MatchMultiple");
}
public static bool MatchFlag(this Context ctx, params string[] potentialMatches)
{
// Flags are *ALWAYS PARSED LOWERCASE*. This means we skip out on a "ToLower" call here.
// Can assume the caller array only contains lowercase *and* the set below only contains lowercase
throw new NotImplementedException();
}
public static bool MatchClear(this Context ctx)
=> ctx.Match("clear", "reset", "default") || ctx.MatchFlag("c", "clear");
public static ReplyFormat MatchFormat(this Context ctx)
{
if (ctx.Match("r", "raw") || ctx.MatchFlag("r", "raw")) return ReplyFormat.Raw;
if (ctx.Match("pt", "plaintext") || ctx.MatchFlag("pt", "plaintext")) return ReplyFormat.Plaintext;
return ReplyFormat.Standard;
}
public static ReplyFormat PeekMatchFormat(this Context ctx)
{
throw new PKError("todo: PeekMatchFormat");
}
public static bool MatchToggle(this Context ctx, bool? defaultValue = null)
{
var value = ctx.MatchToggleOrNull(defaultValue);
if (value == null) throw new PKError("You must pass either \"on\" or \"off\" to this command.");
return value.Value;
}
public static bool? MatchToggleOrNull(this Context ctx, bool? defaultValue = null)
{
if (defaultValue != null && ctx.MatchClear())
return defaultValue.Value;
var yesToggles = new[] { "yes", "on", "enable", "enabled", "true" };
var noToggles = new[] { "no", "off", "disable", "disabled", "false" };
if (ctx.Match(yesToggles) || ctx.MatchFlag(yesToggles))
return true;
else if (ctx.Match(noToggles) || ctx.MatchFlag(noToggles))
return false;
else return null;
}
public static (ulong? messageId, ulong? channelId) GetRepliedTo(this Context ctx) public static (ulong? messageId, ulong? channelId) GetRepliedTo(this Context ctx)
{ {
if (ctx.Message.Type == Message.MessageType.Reply && ctx.Message.MessageReference?.MessageId != null) if (ctx.Message.Type == Message.MessageType.Reply && ctx.Message.MessageReference?.MessageId != null)

View file

@ -48,10 +48,6 @@ public static class ContextAvatarExt
// ToString URL-decodes, which breaks URLs to spaces; AbsoluteUri doesn't // ToString URL-decodes, which breaks URLs to spaces; AbsoluteUri doesn't
return new ParsedImage { Url = uri.AbsoluteUri, Source = AvatarSource.Url }; return new ParsedImage { Url = uri.AbsoluteUri, Source = AvatarSource.Url };
} }
public static async Task<ParsedImage?> MatchImage(this Context ctx)
{
throw new NotImplementedException();
}
} }
public struct ParsedImage public struct ParsedImage

View file

@ -1,9 +1,6 @@
using System.Text.RegularExpressions;
using Myriad.Extensions; using Myriad.Extensions;
using Myriad.Types; using Myriad.Types;
using PluralKit.Bot.Utils;
using PluralKit.Core; using PluralKit.Core;
namespace PluralKit.Bot; namespace PluralKit.Bot;
@ -120,23 +117,4 @@ public static class ContextEntityArgumentsExt
return $"{entity} with ID or name \"{input}\" not found."; return $"{entity} with ID or name \"{input}\" not found.";
return $"{entity} with name \"{input}\" not found. Note that a {entity.ToLower()} ID is 5 or 6 characters long."; return $"{entity} with name \"{input}\" not found. Note that a {entity.ToLower()} ID is 5 or 6 characters long.";
} }
public static async Task<Channel> MatchChannel(this Context ctx)
{
if (!MentionUtils.TryParseChannel(ctx.PeekArgument(), out var id))
return null;
// todo: match channels in other guilds
var channel = await ctx.Cache.TryGetChannel(ctx.Guild!.Id, id);
if (channel == null)
channel = await ctx.Rest.GetChannelOrNull(id);
if (channel == null)
return null;
if (!DiscordUtils.IsValidGuildChannel(channel))
return null;
ctx.PopArgument();
return channel;
}
} }

View file

@ -1,51 +0,0 @@
using PluralKit.Core;
namespace PluralKit.Bot;
public static class ContextPrivacyExt
{
public static PrivacyLevel PopPrivacyLevel(this Context ctx)
{
if (ctx.Match("public", "pub", "show", "shown", "visible", "unhide", "unhidden"))
return PrivacyLevel.Public;
if (ctx.Match("private", "priv", "hide", "hidden"))
return PrivacyLevel.Private;
if (!ctx.HasNext())
throw new PKSyntaxError("You must pass a privacy level (`public` or `private`)");
throw new PKSyntaxError(
$"Invalid privacy level {ctx.PopArgument().AsCode()} (must be `public` or `private`).");
}
public static SystemPrivacySubject PopSystemPrivacySubject(this Context ctx)
{
if (!SystemPrivacyUtils.TryParseSystemPrivacy(ctx.PeekArgument(), out var subject))
throw new PKSyntaxError(
$"Invalid privacy subject {ctx.PopArgument().AsCode()} (must be `description`, `members`, `front`, `fronthistory`, `groups`, or `all`).");
ctx.PopArgument();
return subject;
}
public static MemberPrivacySubject PopMemberPrivacySubject(this Context ctx)
{
if (!MemberPrivacyUtils.TryParseMemberPrivacy(ctx.PeekArgument(), out var subject))
throw new PKSyntaxError(
$"Invalid privacy subject {ctx.PopArgument().AsCode()} (must be `name`, `description`, `avatar`, `birthday`, `pronouns`, `proxy`, `metadata`, `visibility`, or `all`).");
ctx.PopArgument();
return subject;
}
public static GroupPrivacySubject PopGroupPrivacySubject(this Context ctx)
{
if (!GroupPrivacyUtils.TryParseGroupPrivacy(ctx.PeekArgument(), out var subject))
throw new PKSyntaxError(
$"Invalid privacy subject {ctx.PopArgument().AsCode()} (must be `name`, `description`, `icon`, `metadata`, `visibility`, or `all`).");
ctx.PopArgument();
return subject;
}
}

View file

@ -72,7 +72,7 @@ public class Parameters
private async Task<Parameter?> ResolveFfiParam(Context ctx, uniffi.commands.Parameter ffi_param) private async Task<Parameter?> ResolveFfiParam(Context ctx, uniffi.commands.Parameter ffi_param)
{ {
var byId = HasFlag("id", "by-id"); var byId = HasFlag("id", "by-id"); // this is added as a hidden flag to all command definitions
switch (ffi_param) switch (ffi_param)
{ {
case uniffi.commands.Parameter.MemberRef memberRef: case uniffi.commands.Parameter.MemberRef memberRef:

View file

@ -111,7 +111,7 @@ public class Admin
return eb.Build(); return eb.Build();
} }
public async Task UpdateSystemId(Context ctx, PKSystem target, string newHid) public async Task UpdateSystemId(Context ctx, PKSystem target, string newHid, bool confirmYes)
{ {
ctx.AssertBotAdmin(); ctx.AssertBotAdmin();
@ -121,14 +121,14 @@ public class Admin
await ctx.Reply(null, await CreateEmbed(ctx, target)); await ctx.Reply(null, await CreateEmbed(ctx, target));
if (!await ctx.PromptYesNo($"Change system ID of `{target.Hid}` to `{newHid}`?", "Change")) if (!await ctx.PromptYesNo($"Change system ID of `{target.Hid}` to `{newHid}`?", "Change", flagValue: confirmYes))
throw new PKError("ID change cancelled."); throw new PKError("ID change cancelled.");
await ctx.Repository.UpdateSystem(target.Id, new SystemPatch { Hid = newHid }); await ctx.Repository.UpdateSystem(target.Id, new SystemPatch { Hid = newHid });
await ctx.Reply($"{Emojis.Success} System ID updated (`{target.Hid}` -> `{newHid}`)."); await ctx.Reply($"{Emojis.Success} System ID updated (`{target.Hid}` -> `{newHid}`).");
} }
public async Task UpdateMemberId(Context ctx, PKMember target, string newHid) public async Task UpdateMemberId(Context ctx, PKMember target, string newHid, bool confirmYes)
{ {
ctx.AssertBotAdmin(); ctx.AssertBotAdmin();
@ -141,7 +141,7 @@ public class Admin
if (!await ctx.PromptYesNo( if (!await ctx.PromptYesNo(
$"Change member ID of **{target.NameFor(LookupContext.ByNonOwner)}** (`{target.Hid}`) to `{newHid}`?", $"Change member ID of **{target.NameFor(LookupContext.ByNonOwner)}** (`{target.Hid}`) to `{newHid}`?",
"Change" "Change", flagValue: confirmYes
)) ))
throw new PKError("ID change cancelled."); throw new PKError("ID change cancelled.");
@ -149,7 +149,7 @@ public class Admin
await ctx.Reply($"{Emojis.Success} Member ID updated (`{target.Hid}` -> `{newHid}`)."); await ctx.Reply($"{Emojis.Success} Member ID updated (`{target.Hid}` -> `{newHid}`).");
} }
public async Task UpdateGroupId(Context ctx, PKGroup target, string newHid) public async Task UpdateGroupId(Context ctx, PKGroup target, string newHid, bool confirmYes)
{ {
ctx.AssertBotAdmin(); ctx.AssertBotAdmin();
@ -161,7 +161,7 @@ public class Admin
await ctx.Reply(null, await CreateEmbed(ctx, system)); await ctx.Reply(null, await CreateEmbed(ctx, system));
if (!await ctx.PromptYesNo($"Change group ID of **{target.Name}** (`{target.Hid}`) to `{newHid}`?", if (!await ctx.PromptYesNo($"Change group ID of **{target.Name}** (`{target.Hid}`) to `{newHid}`?",
"Change" "Change", flagValue: confirmYes
)) ))
throw new PKError("ID change cancelled."); throw new PKError("ID change cancelled.");
@ -169,13 +169,13 @@ public class Admin
await ctx.Reply($"{Emojis.Success} Group ID updated (`{target.Hid}` -> `{newHid}`)."); await ctx.Reply($"{Emojis.Success} Group ID updated (`{target.Hid}` -> `{newHid}`).");
} }
public async Task RerollSystemId(Context ctx, PKSystem target) public async Task RerollSystemId(Context ctx, PKSystem target, bool confirmYes)
{ {
ctx.AssertBotAdmin(); ctx.AssertBotAdmin();
await ctx.Reply(null, await CreateEmbed(ctx, target)); await ctx.Reply(null, await CreateEmbed(ctx, target));
if (!await ctx.PromptYesNo($"Reroll system ID `{target.Hid}`?", "Reroll")) if (!await ctx.PromptYesNo($"Reroll system ID `{target.Hid}`?", "Reroll", flagValue: confirmYes))
throw new PKError("ID change cancelled."); throw new PKError("ID change cancelled.");
var query = new Query("systems").AsUpdate(new var query = new Query("systems").AsUpdate(new
@ -188,7 +188,7 @@ public class Admin
await ctx.Reply($"{Emojis.Success} System ID updated (`{target.Hid}` -> `{newHid}`)."); await ctx.Reply($"{Emojis.Success} System ID updated (`{target.Hid}` -> `{newHid}`).");
} }
public async Task RerollMemberId(Context ctx, PKMember target) public async Task RerollMemberId(Context ctx, PKMember target, bool confirmYes)
{ {
ctx.AssertBotAdmin(); ctx.AssertBotAdmin();
@ -197,7 +197,7 @@ public class Admin
if (!await ctx.PromptYesNo( if (!await ctx.PromptYesNo(
$"Reroll member ID for **{target.NameFor(LookupContext.ByNonOwner)}** (`{target.Hid}`)?", $"Reroll member ID for **{target.NameFor(LookupContext.ByNonOwner)}** (`{target.Hid}`)?",
"Reroll" "Reroll", flagValue: confirmYes
)) ))
throw new PKError("ID change cancelled."); throw new PKError("ID change cancelled.");
@ -211,7 +211,7 @@ public class Admin
await ctx.Reply($"{Emojis.Success} Member ID updated (`{target.Hid}` -> `{newHid}`)."); await ctx.Reply($"{Emojis.Success} Member ID updated (`{target.Hid}` -> `{newHid}`).");
} }
public async Task RerollGroupId(Context ctx, PKGroup target) public async Task RerollGroupId(Context ctx, PKGroup target, bool confirmYes)
{ {
ctx.AssertBotAdmin(); ctx.AssertBotAdmin();
@ -219,7 +219,7 @@ public class Admin
await ctx.Reply(null, await CreateEmbed(ctx, system)); await ctx.Reply(null, await CreateEmbed(ctx, system));
if (!await ctx.PromptYesNo($"Reroll group ID for **{target.Name}** (`{target.Hid}`)?", if (!await ctx.PromptYesNo($"Reroll group ID for **{target.Name}** (`{target.Hid}`)?",
"Change" "Change", flagValue: confirmYes
)) ))
throw new PKError("ID change cancelled."); throw new PKError("ID change cancelled.");
@ -233,7 +233,7 @@ public class Admin
await ctx.Reply($"{Emojis.Success} Group ID updated (`{target.Hid}` -> `{newHid}`)."); await ctx.Reply($"{Emojis.Success} Group ID updated (`{target.Hid}` -> `{newHid}`).");
} }
public async Task SystemMemberLimit(Context ctx, PKSystem target, int? newLimit) public async Task SystemMemberLimit(Context ctx, PKSystem target, int? newLimit, bool confirmYes)
{ {
ctx.AssertBotAdmin(); ctx.AssertBotAdmin();
@ -247,14 +247,14 @@ public class Admin
} }
await ctx.Reply(null, await CreateEmbed(ctx, target)); await ctx.Reply(null, await CreateEmbed(ctx, target));
if (!await ctx.PromptYesNo($"Update member limit from **{currentLimit}** to **{newLimit}**?", "Update")) if (!await ctx.PromptYesNo($"Update member limit from **{currentLimit}** to **{newLimit}**?", "Update", flagValue: confirmYes))
throw new PKError("Member limit change cancelled."); throw new PKError("Member limit change cancelled.");
await ctx.Repository.UpdateSystemConfig(target.Id, new SystemConfigPatch { MemberLimitOverride = newLimit }); await ctx.Repository.UpdateSystemConfig(target.Id, new SystemConfigPatch { MemberLimitOverride = newLimit });
await ctx.Reply($"{Emojis.Success} Member limit updated."); await ctx.Reply($"{Emojis.Success} Member limit updated.");
} }
public async Task SystemGroupLimit(Context ctx, PKSystem target, int? newLimit) public async Task SystemGroupLimit(Context ctx, PKSystem target, int? newLimit, bool confirmYes)
{ {
ctx.AssertBotAdmin(); ctx.AssertBotAdmin();
@ -268,14 +268,14 @@ public class Admin
} }
await ctx.Reply(null, await CreateEmbed(ctx, target)); await ctx.Reply(null, await CreateEmbed(ctx, target));
if (!await ctx.PromptYesNo($"Update group limit from **{currentLimit}** to **{newLimit}**?", "Update")) if (!await ctx.PromptYesNo($"Update group limit from **{currentLimit}** to **{newLimit}**?", "Update", flagValue: confirmYes))
throw new PKError("Group limit change cancelled."); throw new PKError("Group limit change cancelled.");
await ctx.Repository.UpdateSystemConfig(target.Id, new SystemConfigPatch { GroupLimitOverride = newLimit }); await ctx.Repository.UpdateSystemConfig(target.Id, new SystemConfigPatch { GroupLimitOverride = newLimit });
await ctx.Reply($"{Emojis.Success} Group limit updated."); await ctx.Reply($"{Emojis.Success} Group limit updated.");
} }
public async Task SystemRecover(Context ctx, string systemToken, User account, bool rerollToken) public async Task SystemRecover(Context ctx, string systemToken, User account, bool rerollToken, bool confirmYes)
{ {
ctx.AssertBotAdmin(); ctx.AssertBotAdmin();
@ -294,7 +294,7 @@ public class Admin
var system = await ctx.Repository.GetSystem(systemId.Value!); var system = await ctx.Repository.GetSystem(systemId.Value!);
await ctx.Reply(null, await CreateEmbed(ctx, system)); await ctx.Reply(null, await CreateEmbed(ctx, system));
if (!await ctx.PromptYesNo($"Associate account {account.NameAndMention()} with system `{system.Hid}`?", "Recover account")) if (!await ctx.PromptYesNo($"Associate account {account.NameAndMention()} with system `{system.Hid}`?", "Recover account", flagValue: confirmYes))
throw new PKError("System recovery cancelled."); throw new PKError("System recovery cancelled.");
await ctx.Repository.AddAccount(system.Id, account.Id); await ctx.Repository.AddAccount(system.Id, account.Id);
@ -402,7 +402,7 @@ public class Admin
} }
} }
public async Task AbuseLogDescription(Context ctx, User? account, string? id, string? description, bool clear) public async Task AbuseLogDescription(Context ctx, User? account, string? id, string? description, bool clear, bool confirmClear)
{ {
ctx.AssertBotAdmin(); ctx.AssertBotAdmin();
@ -410,7 +410,7 @@ public class Admin
if (abuseLog == null) if (abuseLog == null)
return; return;
if (clear && await ctx.ConfirmClear("this abuse log description")) if (clear && await ctx.ConfirmClear("this abuse log description", confirmClear))
{ {
await ctx.Repository.UpdateAbuseLog(abuseLog.Id, new AbuseLogPatch { Description = null }); await ctx.Repository.UpdateAbuseLog(abuseLog.Id, new AbuseLogPatch { Description = null });
await ctx.Reply($"{Emojis.Success} Abuse log description cleared."); await ctx.Reply($"{Emojis.Success} Abuse log description cleared.");

View file

@ -115,28 +115,32 @@ public class Api
} }
} }
public async Task SystemWebhook(Context ctx) public async Task GetSystemWebhook(Context ctx)
{ {
ctx.CheckSystem().CheckDMContext(); ctx.CheckSystem().CheckDMContext();
if (!ctx.HasNext(false)) if (ctx.System.WebhookUrl == null)
{ await ctx.Reply($"Your system does not have a webhook URL set. Set one with `{ctx.DefaultPrefix}system webhook <url>`!");
if (ctx.System.WebhookUrl == null) else
await ctx.Reply($"Your system does not have a webhook URL set. Set one with `{ctx.DefaultPrefix}system webhook <url>`!"); await ctx.Reply($"Your system's webhook URL is <{ctx.System.WebhookUrl}>.");
else }
await ctx.Reply($"Your system's webhook URL is <{ctx.System.WebhookUrl}>.");
public async Task ClearSystemWebhook(Context ctx, bool confirmYes)
{
ctx.CheckSystem().CheckDMContext();
if (!await ctx.ConfirmClear("your system's webhook URL", confirmYes))
return; return;
}
if (ctx.MatchClear() && await ctx.ConfirmClear("your system's webhook URL")) await ctx.Repository.UpdateSystem(ctx.System.Id, new SystemPatch { WebhookUrl = null, WebhookToken = null });
{
await ctx.Repository.UpdateSystem(ctx.System.Id, new SystemPatch { WebhookUrl = null, WebhookToken = null });
await ctx.Reply($"{Emojis.Success} System webhook URL removed."); await ctx.Reply($"{Emojis.Success} System webhook URL removed.");
return; }
}
public async Task SetSystemWebhook(Context ctx, string newUrl)
{
ctx.CheckSystem().CheckDMContext();
var newUrl = ctx.RemainderOrNull();
if (!await DispatchExt.ValidateUri(newUrl)) if (!await DispatchExt.ValidateUri(newUrl))
throw new PKError($"The URL {newUrl.AsCode()} is invalid or I cannot access it. Are you sure this is a valid, publicly accessible URL?"); throw new PKError($"The URL {newUrl.AsCode()} is invalid or I cannot access it. Are you sure this is a valid, publicly accessible URL?");

View file

@ -290,7 +290,7 @@ public class Config
await ctx.Reply($"{Emojis.Success} System time zone cleared (set to UTC)."); await ctx.Reply($"{Emojis.Success} System time zone cleared (set to UTC).");
} }
public async Task EditSystemTimezone(Context ctx, string zoneStr) public async Task EditSystemTimezone(Context ctx, string zoneStr, bool confirmYes = false)
{ {
if (ctx.System == null) throw Errors.NoSystemError(ctx.DefaultPrefix); if (ctx.System == null) throw Errors.NoSystemError(ctx.DefaultPrefix);
@ -299,7 +299,7 @@ public class Config
var currentTime = SystemClock.Instance.GetCurrentInstant().InZone(zone); var currentTime = SystemClock.Instance.GetCurrentInstant().InZone(zone);
var msg = $"This will change the system time zone to **{zone.Id}**. The current time is **{currentTime.FormatZoned()}**. Is this correct?"; var msg = $"This will change the system time zone to **{zone.Id}**. The current time is **{currentTime.FormatZoned()}**. Is this correct?";
if (!await ctx.PromptYesNo(msg, "Change Timezone")) throw Errors.TimezoneChangeCancelled; if (!await ctx.PromptYesNo(msg, "Change Timezone", flagValue: confirmYes)) throw Errors.TimezoneChangeCancelled;
await ctx.Repository.UpdateSystemConfig(ctx.System.Id, new() { UiTz = zone.Id }); await ctx.Repository.UpdateSystemConfig(ctx.System.Id, new() { UiTz = zone.Id });

View file

@ -37,20 +37,16 @@ public class Fun
public Task Meow(Context ctx) => public Task Meow(Context ctx) =>
ctx.Reply("*mrrp :3*"); ctx.Reply("*mrrp :3*");
public Task Error(Context ctx) public Task ErrorMessage(Context ctx) => ctx.Reply("> **Error code:** `50f3c7b439d111ecab2023a5431fffbd`", new EmbedBuilder()
{ .Color(0xE74C3C)
if (ctx.Match("message")) .Title("Internal error occurred")
return ctx.Reply("> **Error code:** `50f3c7b439d111ecab2023a5431fffbd`", new EmbedBuilder() .Description(
.Color(0xE74C3C) "For support, please send the error code above in **#bug-reports-and-errors** on **[the support server *(click to join)*](https://discord.gg/PczBt78)** with a description of what you were doing at the time.")
.Title("Internal error occurred") .Footer(new Embed.EmbedFooter("50f3c7b439d111ecab2023a5431fffbd"))
.Description( .Timestamp(SystemClock.Instance.GetCurrentInstant().ToDateTimeOffset().ToString("O"))
"For support, please send the error code above in **#bug-reports-and-errors** on **[the support server *(click to join)*](https://discord.gg/PczBt78)** with a description of what you were doing at the time.") .Build()
.Footer(new Embed.EmbedFooter("50f3c7b439d111ecab2023a5431fffbd")) );
.Timestamp(SystemClock.Instance.GetCurrentInstant().ToDateTimeOffset().ToString("O"))
.Build()
);
return ctx.Reply( public Task Error(Context ctx) => ctx.Reply(
$"{Emojis.Error} Unknown command {"error".AsCode()}. For a list of possible commands, see <https://pluralkit.me/commands>."); $"{Emojis.Error} Unknown command {"error".AsCode()}. For a list of possible commands, see <https://pluralkit.me/commands>.");
}
} }

View file

@ -51,7 +51,7 @@ public class GroupMember
groups.Count - toAction.Count)); groups.Count - toAction.Count));
} }
public async Task ListMemberGroups(Context ctx, PKMember target, string? query, IHasListOptions flags) public async Task ListMemberGroups(Context ctx, PKMember target, string? query, IHasListOptions flags, bool all)
{ {
var targetSystem = await ctx.Repository.GetSystem(target.System); var targetSystem = await ctx.Repository.GetSystem(target.System);
var opts = flags.GetListOptions(ctx, target.System); var opts = flags.GetListOptions(ctx, target.System);
@ -80,10 +80,10 @@ public class GroupMember
title.Append($" matching **{opts.Search.Truncate(100)}**"); title.Append($" matching **{opts.Search.Truncate(100)}**");
await ctx.RenderGroupList(ctx.LookupContextFor(target.System), target.System, title.ToString(), await ctx.RenderGroupList(ctx.LookupContextFor(target.System), target.System, title.ToString(),
target.Color, opts); target.Color, opts, all);
} }
public async Task AddRemoveMembers(Context ctx, PKGroup target, List<PKMember> _members, Groups.AddRemoveOperation op, bool all) public async Task AddRemoveMembers(Context ctx, PKGroup target, List<PKMember> _members, Groups.AddRemoveOperation op, bool all, bool confirmYes)
{ {
ctx.CheckOwnGroup(target); ctx.CheckOwnGroup(target);
@ -126,7 +126,7 @@ public class GroupMember
.Where(m => existingMembersInGroup.Contains(m.Value)) .Where(m => existingMembersInGroup.Contains(m.Value))
.ToList(); .ToList();
if (all && !await ctx.PromptYesNo($"Are you sure you want to remove all members from group {target.Reference(ctx)}?", "Empty Group")) throw Errors.GenericCancelled(); if (all && !await ctx.PromptYesNo($"Are you sure you want to remove all members from group {target.Reference(ctx)}?", "Empty Group", flagValue: confirmYes)) throw Errors.GenericCancelled();
await ctx.Repository.RemoveMembersFromGroup(target.Id, toAction); await ctx.Repository.RemoveMembersFromGroup(target.Id, toAction);
} }

View file

@ -32,7 +32,7 @@ public class Groups
_avatarHosting = avatarHosting; _avatarHosting = avatarHosting;
} }
public async Task CreateGroup(Context ctx, string groupName) public async Task CreateGroup(Context ctx, string groupName, bool confirmYes = false)
{ {
ctx.CheckSystem(); ctx.CheckSystem();
@ -53,7 +53,7 @@ public class Groups
{ {
var msg = var msg =
$"{Emojis.Warn} You already have a group in your system with the name \"{existingGroup.Name}\" (with ID `{existingGroup.DisplayHid(ctx.Config)}`). Do you want to create another group with the same name?"; $"{Emojis.Warn} You already have a group in your system with the name \"{existingGroup.Name}\" (with ID `{existingGroup.DisplayHid(ctx.Config)}`). Do you want to create another group with the same name?";
if (!await ctx.PromptYesNo(msg, "Create")) if (!await ctx.PromptYesNo(msg, "Create", flagValue: confirmYes))
throw new PKError("Group creation cancelled."); throw new PKError("Group creation cancelled.");
} }
@ -98,7 +98,7 @@ public class Groups
await ctx.Reply(replyStr, eb.Build()); await ctx.Reply(replyStr, eb.Build());
} }
public async Task RenameGroup(Context ctx, PKGroup target, string newName) public async Task RenameGroup(Context ctx, PKGroup target, string? newName, bool confirmYes = false)
{ {
ctx.CheckOwnGroup(target); ctx.CheckOwnGroup(target);
@ -113,7 +113,7 @@ public class Groups
{ {
var msg = var msg =
$"{Emojis.Warn} You already have a group in your system with the name \"{existingGroup.Name}\" (with ID `{existingGroup.DisplayHid(ctx.Config)}`). Do you want to rename this group to that name too?"; $"{Emojis.Warn} You already have a group in your system with the name \"{existingGroup.Name}\" (with ID `{existingGroup.DisplayHid(ctx.Config)}`). Do you want to rename this group to that name too?";
if (!await ctx.PromptYesNo(msg, "Rename")) if (!await ctx.PromptYesNo(msg, "Rename", flagValue: confirmYes))
throw new PKError("Group rename cancelled."); throw new PKError("Group rename cancelled.");
} }
@ -320,10 +320,10 @@ public class Groups
await ctx.Reply(embed: ebS.Build()); await ctx.Reply(embed: ebS.Build());
} }
public async Task ClearGroupIcon(Context ctx, PKGroup target) public async Task ClearGroupIcon(Context ctx, PKGroup target, bool confirmYes)
{ {
ctx.CheckOwnGroup(target); ctx.CheckOwnGroup(target);
await ctx.ConfirmClear("this group's icon"); await ctx.ConfirmClear("this group's icon", confirmYes);
await ctx.Repository.UpdateGroup(target.Id, new GroupPatch { Icon = null }); await ctx.Repository.UpdateGroup(target.Id, new GroupPatch { Icon = null });
await ctx.Reply($"{Emojis.Success} Group icon cleared."); await ctx.Reply($"{Emojis.Success} Group icon cleared.");
@ -400,10 +400,10 @@ public class Groups
await ctx.Reply(embed: ebS.Build()); await ctx.Reply(embed: ebS.Build());
} }
public async Task ClearGroupBanner(Context ctx, PKGroup target) public async Task ClearGroupBanner(Context ctx, PKGroup target, bool confirmYes)
{ {
ctx.CheckOwnGroup(target); ctx.CheckOwnGroup(target);
await ctx.ConfirmClear("this group's banner image"); await ctx.ConfirmClear("this group's banner image", confirmYes);
await ctx.Repository.UpdateGroup(target.Id, new GroupPatch { BannerImage = null }); await ctx.Repository.UpdateGroup(target.Id, new GroupPatch { BannerImage = null });
await ctx.Reply($"{Emojis.Success} Group banner image cleared."); await ctx.Reply($"{Emojis.Success} Group banner image cleared.");
@ -506,7 +506,7 @@ public class Groups
files: [MiscUtils.GenerateColorPreview(color)]); files: [MiscUtils.GenerateColorPreview(color)]);
} }
public async Task ListSystemGroups(Context ctx, PKSystem system, string? query, IHasListOptions flags) public async Task ListSystemGroups(Context ctx, PKSystem system, string? query, IHasListOptions flags, bool all)
{ {
if (system == null) if (system == null)
{ {
@ -528,7 +528,8 @@ public class Groups
system.Id, system.Id,
GetEmbedTitle(ctx, system, opts), GetEmbedTitle(ctx, system, opts),
system.Color, system.Color,
opts opts,
all
); );
} }
@ -547,16 +548,16 @@ public class Groups
return title.ToString(); return title.ToString();
} }
public async Task ShowGroupCard(Context ctx, PKGroup target, bool showEmbed = false) public async Task ShowGroupCard(Context ctx, PKGroup target, bool showEmbed, bool all)
{ {
var system = await GetGroupSystem(ctx, target); var system = await GetGroupSystem(ctx, target);
if (showEmbed) if (showEmbed)
{ {
await ctx.Reply(text: EmbedService.LEGACY_EMBED_WARNING, embed: await _embeds.CreateGroupEmbed(ctx, system, target)); await ctx.Reply(text: EmbedService.LEGACY_EMBED_WARNING, embed: await _embeds.CreateGroupEmbed(ctx, system, target, all));
return; return;
} }
await ctx.Reply(components: await _embeds.CreateGroupMessageComponents(ctx, system, target)); await ctx.Reply(components: await _embeds.CreateGroupMessageComponents(ctx, system, target, all));
} }
public async Task ShowGroupPrivacy(Context ctx, PKGroup target) public async Task ShowGroupPrivacy(Context ctx, PKGroup target)

View file

@ -31,7 +31,7 @@ public class ImportExport
_dmCache = dmCache; _dmCache = dmCache;
} }
public async Task Import(Context ctx, string? inputUrl) public async Task Import(Context ctx, string? inputUrl, bool confirmYes)
{ {
inputUrl = inputUrl ?? ctx.Message.Attachments.FirstOrDefault()?.Url; inputUrl = inputUrl ?? ctx.Message.Attachments.FirstOrDefault()?.Url;
if (inputUrl == null) throw Errors.NoImportFilePassed; if (inputUrl == null) throw Errors.NoImportFilePassed;
@ -77,7 +77,7 @@ public class ImportExport
async Task ConfirmImport(string message) async Task ConfirmImport(string message)
{ {
var msg = $"{message}\n\nDo you want to proceed with the import?"; var msg = $"{message}\n\nDo you want to proceed with the import?";
if (!await ctx.PromptYesNo(msg, "Proceed")) if (!await ctx.PromptYesNo(msg, "Proceed", flagValue: confirmYes))
throw Errors.ImportCancelled; throw Errors.ImportCancelled;
} }
@ -86,7 +86,7 @@ public class ImportExport
&& data.Value<JArray>("accounts").Contains(ctx.Author.Id.ToString())) && data.Value<JArray>("accounts").Contains(ctx.Author.Id.ToString()))
{ {
var msg = $"{Emojis.Warn} You seem to importing a system profile belonging to another account. Are you sure you want to proceed?"; var msg = $"{Emojis.Warn} You seem to importing a system profile belonging to another account. Are you sure you want to proceed?";
if (!await ctx.PromptYesNo(msg, "Import")) throw Errors.ImportCancelled; if (!await ctx.PromptYesNo(msg, "Import", flagValue: confirmYes)) throw Errors.ImportCancelled;
} }
var result = await _dataFiles.ImportSystem(ctx.Author.Id, ctx.System, data, ConfirmImport); var result = await _dataFiles.ImportSystem(ctx.Author.Id, ctx.System, data, ConfirmImport);

View file

@ -130,7 +130,7 @@ public static class ContextListExt
} }
public static async Task RenderGroupList(this Context ctx, LookupContext lookupCtx, public static async Task RenderGroupList(this Context ctx, LookupContext lookupCtx,
SystemId system, string embedTitle, string color, ListOptions opts) SystemId system, string embedTitle, string color, ListOptions opts, bool all)
{ {
// We take an IDatabase instead of a IPKConnection so we don't keep the handle open for the entire runtime // We take an IDatabase instead of a IPKConnection so we don't keep the handle open for the entire runtime
// We wanna release it as soon as the member list is actually *fetched*, instead of potentially minutes later (paginate timeout) // We wanna release it as soon as the member list is actually *fetched*, instead of potentially minutes later (paginate timeout)
@ -204,7 +204,7 @@ public static class ContextListExt
{ {
if (g.ListPrivacy == PrivacyLevel.Public || lookupCtx == LookupContext.ByOwner) if (g.ListPrivacy == PrivacyLevel.Public || lookupCtx == LookupContext.ByOwner)
{ {
if (ctx.MatchFlag("all", "a")) if (all)
{ {
ret += $"({"member".ToQuantity(g.TotalMemberCount)})"; ret += $"({"member".ToQuantity(g.TotalMemberCount)})";
} }
@ -242,7 +242,7 @@ public static class ContextListExt
if (g.ListPrivacy == PrivacyLevel.Public || lookupCtx == LookupContext.ByOwner) if (g.ListPrivacy == PrivacyLevel.Public || lookupCtx == LookupContext.ByOwner)
{ {
if (ctx.MatchFlag("all", "a") && ctx.DirectLookupContextFor(system) == LookupContext.ByOwner) if (all && ctx.DirectLookupContextFor(system) == LookupContext.ByOwner)
profile.Append($"\n**Member Count:** {g.TotalMemberCount}"); profile.Append($"\n**Member Count:** {g.TotalMemberCount}");
else else
profile.Append($"\n**Member Count:** {g.PublicMemberCount}"); profile.Append($"\n**Member Count:** {g.PublicMemberCount}");

View file

@ -28,7 +28,7 @@ public class Member
_avatarHosting = avatarHosting; _avatarHosting = avatarHosting;
} }
public async Task NewMember(Context ctx, string? memberName) public async Task NewMember(Context ctx, string? memberName, bool confirmYes = false)
{ {
if (ctx.System == null) throw Errors.NoSystemError(ctx.DefaultPrefix); if (ctx.System == null) throw Errors.NoSystemError(ctx.DefaultPrefix);
memberName = memberName ?? throw new PKSyntaxError("You must pass a member name."); memberName = memberName ?? throw new PKSyntaxError("You must pass a member name.");
@ -42,7 +42,7 @@ public class Member
if (existingMember != null) if (existingMember != null)
{ {
var msg = $"{Emojis.Warn} You already have a member in your system with the name \"{existingMember.NameFor(ctx)}\" (with ID `{existingMember.DisplayHid(ctx.Config)}`). Do you want to create another member with the same name?"; var msg = $"{Emojis.Warn} You already have a member in your system with the name \"{existingMember.NameFor(ctx)}\" (with ID `{existingMember.DisplayHid(ctx.Config)}`). Do you want to create another member with the same name?";
if (!await ctx.PromptYesNo(msg, "Create")) throw new PKError("Member creation cancelled."); if (!await ctx.PromptYesNo(msg, "Create", flagValue: confirmYes)) throw new PKError("Member creation cancelled.");
} }
await using var conn = await ctx.Database.Obtain(); await using var conn = await ctx.Database.Obtain();

View file

@ -17,10 +17,10 @@ public class MemberAvatar
_avatarHosting = avatarHosting; _avatarHosting = avatarHosting;
} }
private async Task AvatarClear(MemberAvatarLocation location, Context ctx, PKMember target, MemberGuildSettings? mgs) private async Task AvatarClear(MemberAvatarLocation location, Context ctx, PKMember target, MemberGuildSettings? mgs, bool confirmYes)
{ {
ctx.CheckSystem().CheckOwnMember(target); ctx.CheckSystem().CheckOwnMember(target);
await ctx.ConfirmClear("this member's " + location.Name()); await ctx.ConfirmClear("this member's " + location.Name(), confirmYes);
await UpdateAvatar(location, ctx, target, null); await UpdateAvatar(location, ctx, target, null);
if (location == MemberAvatarLocation.Server) if (location == MemberAvatarLocation.Server)
@ -149,10 +149,10 @@ public class MemberAvatar
await AvatarShow(MemberAvatarLocation.Server, ctx, target, guildData, format); await AvatarShow(MemberAvatarLocation.Server, ctx, target, guildData, format);
} }
public async Task ClearServerAvatar(Context ctx, PKMember target) public async Task ClearServerAvatar(Context ctx, PKMember target, bool confirmYes)
{ {
var guildData = await GetServerAvatarGuildData(ctx, target); var guildData = await GetServerAvatarGuildData(ctx, target);
await AvatarClear(MemberAvatarLocation.Server, ctx, target, guildData); await AvatarClear(MemberAvatarLocation.Server, ctx, target, guildData, confirmYes);
} }
public async Task ChangeServerAvatar(Context ctx, PKMember target, ParsedImage avatar) public async Task ChangeServerAvatar(Context ctx, PKMember target, ParsedImage avatar)
@ -167,10 +167,10 @@ public class MemberAvatar
await AvatarShow(MemberAvatarLocation.Member, ctx, target, guildData, format); await AvatarShow(MemberAvatarLocation.Member, ctx, target, guildData, format);
} }
public async Task ClearAvatar(Context ctx, PKMember target) public async Task ClearAvatar(Context ctx, PKMember target, bool confirmYes)
{ {
var guildData = await GetAvatarGuildData(ctx, target); var guildData = await GetAvatarGuildData(ctx, target);
await AvatarClear(MemberAvatarLocation.Member, ctx, target, guildData); await AvatarClear(MemberAvatarLocation.Member, ctx, target, guildData, confirmYes);
} }
public async Task ChangeAvatar(Context ctx, PKMember target, ParsedImage avatar) public async Task ChangeAvatar(Context ctx, PKMember target, ParsedImage avatar)
@ -185,10 +185,10 @@ public class MemberAvatar
await AvatarShow(MemberAvatarLocation.MemberWebhook, ctx, target, guildData, format); await AvatarShow(MemberAvatarLocation.MemberWebhook, ctx, target, guildData, format);
} }
public async Task ClearWebhookAvatar(Context ctx, PKMember target) public async Task ClearWebhookAvatar(Context ctx, PKMember target, bool confirmYes)
{ {
var guildData = await GetWebhookAvatarGuildData(ctx, target); var guildData = await GetWebhookAvatarGuildData(ctx, target);
await AvatarClear(MemberAvatarLocation.MemberWebhook, ctx, target, guildData); await AvatarClear(MemberAvatarLocation.MemberWebhook, ctx, target, guildData, confirmYes);
} }
public async Task ChangeWebhookAvatar(Context ctx, PKMember target, ParsedImage avatar) public async Task ChangeWebhookAvatar(Context ctx, PKMember target, ParsedImage avatar)

View file

@ -44,7 +44,7 @@ public class MemberEdit
} }
} }
public async Task ChangeName(Context ctx, PKMember target, string newName) public async Task ChangeName(Context ctx, PKMember target, string newName, bool confirmYes)
{ {
ctx.CheckSystem().CheckOwnMember(target); ctx.CheckSystem().CheckOwnMember(target);
@ -58,7 +58,7 @@ public class MemberEdit
{ {
var msg = var msg =
$"{Emojis.Warn} You already have a member in your system with the name \"{existingMember.NameFor(ctx)}\" (`{existingMember.DisplayHid(ctx.Config)}`). Do you want to rename this member to that name too?"; $"{Emojis.Warn} You already have a member in your system with the name \"{existingMember.NameFor(ctx)}\" (`{existingMember.DisplayHid(ctx.Config)}`). Do you want to rename this member to that name too?";
if (!await ctx.PromptYesNo(msg, "Rename")) throw new PKError("Member renaming cancelled."); if (!await ctx.PromptYesNo(msg, "Rename", flagValue: confirmYes)) throw new PKError("Member renaming cancelled.");
} }
// Rename the member // Rename the member

View file

@ -14,7 +14,7 @@ public class MemberProxy
await ctx.Reply($"This member's proxy tags are:\n{target.ProxyTagsString("\n")}"); await ctx.Reply($"This member's proxy tags are:\n{target.ProxyTagsString("\n")}");
} }
public async Task ClearProxy(Context ctx, PKMember target) public async Task ClearProxy(Context ctx, PKMember target, bool confirmYes = false)
{ {
ctx.CheckSystem().CheckOwnMember(target); ctx.CheckSystem().CheckOwnMember(target);
@ -22,7 +22,7 @@ public class MemberProxy
if (target.ProxyTags.Count > 1) if (target.ProxyTags.Count > 1)
{ {
var msg = $"{Emojis.Warn} You already have multiple proxy tags set: {target.ProxyTagsString()}\nDo you want to clear them all?"; var msg = $"{Emojis.Warn} You already have multiple proxy tags set: {target.ProxyTagsString()}\nDo you want to clear them all?";
if (!await ctx.PromptYesNo(msg, "Clear")) if (!await ctx.PromptYesNo(msg, "Clear", flagValue: confirmYes))
throw Errors.GenericCancelled(); throw Errors.GenericCancelled();
} }
@ -32,7 +32,7 @@ public class MemberProxy
await ctx.Reply($"{Emojis.Success} Proxy tags cleared."); await ctx.Reply($"{Emojis.Success} Proxy tags cleared.");
} }
public async Task AddProxy(Context ctx, PKMember target, string proxyString) public async Task AddProxy(Context ctx, PKMember target, string proxyString, bool confirmYes = false)
{ {
ctx.CheckSystem().CheckOwnMember(target); ctx.CheckSystem().CheckOwnMember(target);
@ -44,7 +44,7 @@ public class MemberProxy
throw new PKError( throw new PKError(
$"Proxy tag too long ({tagToAdd.ProxyString.Length} > {Limits.MaxProxyTagLength} characters)."); $"Proxy tag too long ({tagToAdd.ProxyString.Length} > {Limits.MaxProxyTagLength} characters).");
if (!await WarnOnConflict(ctx, target, tagToAdd)) if (!await WarnOnConflict(ctx, target, tagToAdd, confirmYes))
throw Errors.GenericCancelled(); throw Errors.GenericCancelled();
var newTags = target.ProxyTags.ToList(); var newTags = target.ProxyTags.ToList();
@ -72,7 +72,7 @@ public class MemberProxy
await ctx.Reply($"{Emojis.Success} Removed proxy tags {tagToRemove.ProxyString.AsCode()}."); await ctx.Reply($"{Emojis.Success} Removed proxy tags {tagToRemove.ProxyString.AsCode()}.");
} }
public async Task SetProxy(Context ctx, PKMember target, string proxyString) public async Task SetProxy(Context ctx, PKMember target, string proxyString, bool confirmYes = false)
{ {
ctx.CheckSystem().CheckOwnMember(target); ctx.CheckSystem().CheckOwnMember(target);
@ -82,7 +82,7 @@ public class MemberProxy
if (target.ProxyTags.Count > 1) if (target.ProxyTags.Count > 1)
{ {
var msg = $"This member already has more than one proxy tag set: {target.ProxyTagsString()}\nDo you want to replace them?"; var msg = $"This member already has more than one proxy tag set: {target.ProxyTagsString()}\nDo you want to replace them?";
if (!await ctx.PromptYesNo(msg, "Replace")) if (!await ctx.PromptYesNo(msg, "Replace", flagValue: confirmYes))
throw Errors.GenericCancelled(); throw Errors.GenericCancelled();
} }
@ -90,7 +90,7 @@ public class MemberProxy
throw new PKError( throw new PKError(
$"Proxy tag too long ({requestedTag.ProxyString.Length} > {Limits.MaxProxyTagLength} characters)."); $"Proxy tag too long ({requestedTag.ProxyString.Length} > {Limits.MaxProxyTagLength} characters).");
if (!await WarnOnConflict(ctx, target, requestedTag)) if (!await WarnOnConflict(ctx, target, requestedTag, confirmYes))
throw Errors.GenericCancelled(); throw Errors.GenericCancelled();
var newTags = new[] { requestedTag }; var newTags = new[] { requestedTag };
@ -110,7 +110,7 @@ public class MemberProxy
return new ProxyTag(prefixAndSuffix[0], prefixAndSuffix[1]); return new ProxyTag(prefixAndSuffix[0], prefixAndSuffix[1]);
} }
private async Task<bool> WarnOnConflict(Context ctx, PKMember target, ProxyTag newTag) private async Task<bool> WarnOnConflict(Context ctx, PKMember target, ProxyTag newTag, bool confirmYes = false)
{ {
var query = "select * from (select *, (unnest(proxy_tags)).prefix as prefix, (unnest(proxy_tags)).suffix as suffix from members where system = @System) as _ where prefix is not distinct from @Prefix and suffix is not distinct from @Suffix and id != @Existing"; var query = "select * from (select *, (unnest(proxy_tags)).prefix as prefix, (unnest(proxy_tags)).suffix as suffix from members where system = @System) as _ where prefix is not distinct from @Prefix and suffix is not distinct from @Suffix and id != @Existing";
var conflicts = (await ctx.Database.Execute(conn => conn.QueryAsync<PKMember>(query, var conflicts = (await ctx.Database.Execute(conn => conn.QueryAsync<PKMember>(query,
@ -120,6 +120,6 @@ public class MemberProxy
var conflictList = conflicts.Select(m => $"- **{m.NameFor(ctx)}**"); var conflictList = conflicts.Select(m => $"- **{m.NameFor(ctx)}**");
var msg = $"{Emojis.Warn} The following members have conflicting proxy tags:\n{string.Join('\n', conflictList)}\nDo you want to proceed anyway?"; var msg = $"{Emojis.Warn} The following members have conflicting proxy tags:\n{string.Join('\n', conflictList)}\nDo you want to proceed anyway?";
return await ctx.PromptYesNo(msg, "Proceed"); return await ctx.PromptYesNo(msg, "Proceed", flagValue: confirmYes);
} }
} }

View file

@ -322,9 +322,7 @@ public class ProxiedMessage
{ {
if (messageId == null) if (messageId == null)
{ {
if (!ctx.HasNext()) throw new PKSyntaxError("You must pass a message ID or link.");
throw new PKSyntaxError("You must pass a message ID or link.");
throw new PKSyntaxError($"Could not parse {ctx.PeekArgument().AsCode()} as a message ID or link.");
} }
var message = await ctx.Repository.GetFullMessage(messageId.Value); var message = await ctx.Repository.GetFullMessage(messageId.Value);

View file

@ -74,12 +74,12 @@ public class Random
{ {
await ctx.Reply( await ctx.Reply(
text: EmbedService.LEGACY_EMBED_WARNING, text: EmbedService.LEGACY_EMBED_WARNING,
embed: await _embeds.CreateGroupEmbed(ctx, target, groups.ToArray()[randInt])); embed: await _embeds.CreateGroupEmbed(ctx, target, groups.ToArray()[randInt], all));
return; return;
} }
await ctx.Reply( await ctx.Reply(
components: await _embeds.CreateGroupMessageComponents(ctx, target, groups.ToArray()[randInt])); components: await _embeds.CreateGroupMessageComponents(ctx, target, groups.ToArray()[randInt], all));
} }
public async Task GroupMember(Context ctx, PKGroup group, GroupRandomMemberFlags flags) public async Task GroupMember(Context ctx, PKGroup group, GroupRandomMemberFlags flags)

View file

@ -144,11 +144,11 @@ public class ServerConfig
await ctx.Reply($"{Emojis.Success} Proxy logging channel set to <#{channel.Id}>."); await ctx.Reply($"{Emojis.Success} Proxy logging channel set to <#{channel.Id}>.");
} }
public async Task ClearLogChannel(Context ctx) public async Task ClearLogChannel(Context ctx, bool confirmYes)
{ {
await ctx.CheckGuildContext().CheckAuthorPermission(PermissionSet.ManageGuild, "Manage Server"); await ctx.CheckGuildContext().CheckAuthorPermission(PermissionSet.ManageGuild, "Manage Server");
if (!await ctx.ConfirmClear("the server log channel")) if (!await ctx.ConfirmClear("the server log channel", confirmYes))
return; return;
await ctx.Repository.UpdateGuild(ctx.Guild.Id, new GuildPatch { LogChannel = null }); await ctx.Repository.UpdateGuild(ctx.Guild.Id, new GuildPatch { LogChannel = null });

View file

@ -57,14 +57,14 @@ public class Switch
$"{Emojis.Success} Switch registered. Current fronters are now {string.Join(", ", members.Select(m => m.NameFor(ctx)))}."); $"{Emojis.Success} Switch registered. Current fronters are now {string.Join(", ", members.Select(m => m.NameFor(ctx)))}.");
} }
public async Task SwitchMove(Context ctx, string timeToMove) public async Task SwitchMove(Context ctx, string str, bool confirmYes = false)
{ {
ctx.CheckSystem(); ctx.CheckSystem();
var tz = TzdbDateTimeZoneSource.Default.ForId(ctx.Config?.UiTz ?? "UTC"); var tz = TzdbDateTimeZoneSource.Default.ForId(ctx.Config?.UiTz ?? "UTC");
var result = DateUtils.ParseDateTime(timeToMove, true, tz); var result = DateUtils.ParseDateTime(str, true, tz);
if (result == null) throw Errors.InvalidDateTime(timeToMove); if (result == null) throw Errors.InvalidDateTime(str);
var time = result.Value; var time = result.Value;
@ -95,14 +95,14 @@ public class Switch
// yeet // yeet
var msg = var msg =
$"{Emojis.Warn} This will move the latest switch ({lastSwitchMemberStr}) from <t:{lastSwitchTime}> ({lastSwitchDeltaStr} ago) to <t:{newSwitchTime}> ({newSwitchDeltaStr} ago). Is this OK?"; $"{Emojis.Warn} This will move the latest switch ({lastSwitchMemberStr}) from <t:{lastSwitchTime}> ({lastSwitchDeltaStr} ago) to <t:{newSwitchTime}> ({newSwitchDeltaStr} ago). Is this OK?";
if (!await ctx.PromptYesNo(msg, "Move Switch")) throw Errors.SwitchMoveCancelled; if (!await ctx.PromptYesNo(msg, "Move Switch", flagValue: confirmYes)) throw Errors.SwitchMoveCancelled;
// aaaand *now* we do the move // aaaand *now* we do the move
await ctx.Repository.MoveSwitch(lastTwoSwitches[0].Id, time.ToInstant()); await ctx.Repository.MoveSwitch(lastTwoSwitches[0].Id, time.ToInstant());
await ctx.Reply($"{Emojis.Success} Switch moved to <t:{newSwitchTime}> ({newSwitchDeltaStr} ago)."); await ctx.Reply($"{Emojis.Success} Switch moved to <t:{newSwitchTime}> ({newSwitchDeltaStr} ago).");
} }
public async Task SwitchEdit(Context ctx, List<PKMember>? newMembers, bool newSwitch = false, bool first = false, bool remove = false, bool append = false, bool prepend = false) public async Task SwitchEdit(Context ctx, List<PKMember>? newMembers, bool newSwitch = false, bool first = false, bool remove = false, bool append = false, bool prepend = false, bool confirmYes = false)
{ {
ctx.CheckSystem(); ctx.CheckSystem();
@ -131,7 +131,7 @@ public class Switch
await DoSwitchCommand(ctx, newMembers); await DoSwitchCommand(ctx, newMembers);
} }
else else
await DoEditCommand(ctx, newMembers); await DoEditCommand(ctx, newMembers, confirmYes);
} }
public List<PKMember> PrependToSwitch(List<PKMember> members, List<PKMember> currentSwitchMembers) public List<PKMember> PrependToSwitch(List<PKMember> members, List<PKMember> currentSwitchMembers)
@ -167,13 +167,13 @@ public class Switch
return members; return members;
} }
public async Task SwitchEditOut(Context ctx) public async Task SwitchEditOut(Context ctx, bool confirmYes)
{ {
ctx.CheckSystem(); ctx.CheckSystem();
await DoEditCommand(ctx, []); await DoEditCommand(ctx, [], confirmYes);
} }
public async Task DoEditCommand(Context ctx, ICollection<PKMember>? members) public async Task DoEditCommand(Context ctx, ICollection<PKMember>? members, bool confirmYes)
{ {
if (members == null) members = new List<PKMember>(); if (members == null) members = new List<PKMember>();
@ -203,7 +203,7 @@ public class Switch
msg = $"{Emojis.Warn} This will turn the latest switch ({lastSwitchMemberStr}, {lastSwitchDeltaStr} ago) into a switch-out. Is this okay?"; msg = $"{Emojis.Warn} This will turn the latest switch ({lastSwitchMemberStr}, {lastSwitchDeltaStr} ago) into a switch-out. Is this okay?";
else else
msg = $"{Emojis.Warn} This will change the latest switch ({lastSwitchMemberStr}, {lastSwitchDeltaStr} ago) to {newSwitchMemberStr}. Is this okay?"; msg = $"{Emojis.Warn} This will change the latest switch ({lastSwitchMemberStr}, {lastSwitchDeltaStr} ago) to {newSwitchMemberStr}. Is this okay?";
if (!await ctx.PromptYesNo(msg, "Edit")) throw Errors.SwitchEditCancelled; if (!await ctx.PromptYesNo(msg, "Edit", flagValue: confirmYes)) throw Errors.SwitchEditCancelled;
// Actually edit the switch // Actually edit the switch
await ctx.Repository.EditSwitch(conn, lastSwitch.Id, members.Select(m => m.Id).ToList()); await ctx.Repository.EditSwitch(conn, lastSwitch.Id, members.Select(m => m.Id).ToList());
@ -217,7 +217,7 @@ public class Switch
await ctx.Reply($"{Emojis.Success} Switch edited. Current fronters are now {newSwitchMemberStr}."); await ctx.Reply($"{Emojis.Success} Switch edited. Current fronters are now {newSwitchMemberStr}.");
} }
public async Task SwitchDelete(Context ctx, bool all) public async Task SwitchDelete(Context ctx, bool all = false, bool confirmYes = false)
{ {
ctx.CheckSystem(); ctx.CheckSystem();
@ -226,7 +226,7 @@ public class Switch
// Subcommand: "delete all" // Subcommand: "delete all"
var purgeMsg = var purgeMsg =
$"{Emojis.Warn} This will delete *all registered switches* in your system. Are you sure you want to proceed?"; $"{Emojis.Warn} This will delete *all registered switches* in your system. Are you sure you want to proceed?";
if (!await ctx.PromptYesNo(purgeMsg, "Clear Switches")) if (!await ctx.PromptYesNo(purgeMsg, "Clear Switches", flagValue: confirmYes))
throw Errors.GenericCancelled(); throw Errors.GenericCancelled();
await ctx.Repository.DeleteAllSwitches(ctx.System.Id); await ctx.Repository.DeleteAllSwitches(ctx.System.Id);
await ctx.Reply($"{Emojis.Success} Cleared system switches!"); await ctx.Reply($"{Emojis.Success} Cleared system switches!");
@ -258,7 +258,7 @@ public class Switch
msg = $"{Emojis.Warn} This will delete the latest switch ({lastSwitchMemberStr}, {lastSwitchDeltaStr} ago). The next latest switch is {secondSwitchMemberStr} ({secondSwitchDeltaStr} ago). Is this okay?"; msg = $"{Emojis.Warn} This will delete the latest switch ({lastSwitchMemberStr}, {lastSwitchDeltaStr} ago). The next latest switch is {secondSwitchMemberStr} ({secondSwitchDeltaStr} ago). Is this okay?";
} }
if (!await ctx.PromptYesNo(msg, "Delete Switch")) throw Errors.SwitchDeleteCancelled; if (!await ctx.PromptYesNo(msg, "Delete Switch", flagValue: confirmYes)) throw Errors.SwitchDeleteCancelled;
await ctx.Repository.DeleteSwitch(lastTwoSwitches[0].Id); await ctx.Repository.DeleteSwitch(lastTwoSwitches[0].Id);
await ctx.Reply($"{Emojis.Success} Switch deleted."); await ctx.Reply($"{Emojis.Success} Switch deleted.");

View file

@ -26,7 +26,7 @@ public class SystemFront
await ctx.Reply(embed: await _embeds.CreateFronterEmbed(sw, ctx.Zone, ctx.LookupContextFor(system.Id))); await ctx.Reply(embed: await _embeds.CreateFronterEmbed(sw, ctx.Zone, ctx.LookupContextFor(system.Id)));
} }
public async Task FrontHistory(Context ctx, PKSystem system, bool clear = false) public async Task FrontHistory(Context ctx, PKSystem system, bool showMemberId, bool clear = false)
{ {
if (clear) if (clear)
{ {
@ -55,8 +55,6 @@ public class SystemFront
embedTitle = $"Front history of {guildSettings.DisplayName} (`{system.Hid}`)"; embedTitle = $"Front history of {guildSettings.DisplayName} (`{system.Hid}`)";
} }
var showMemberId = ctx.MatchFlag("with-id", "wid");
await ctx.Paginate( await ctx.Paginate(
sws, sws,
totalSwitches, totalSwitches,

View file

@ -25,7 +25,7 @@ public class SystemLink
await ctx.Reply($"{Emojis.Success} Account linked to system."); await ctx.Reply($"{Emojis.Success} Account linked to system.");
} }
public async Task UnlinkAccount(Context ctx, string idRaw) public async Task UnlinkAccount(Context ctx, string idRaw, bool confirmYes)
{ {
ctx.CheckSystem(); ctx.CheckSystem();
@ -38,7 +38,7 @@ public class SystemLink
if (accountIds.Count == 1) throw Errors.UnlinkingLastAccount(ctx.DefaultPrefix); if (accountIds.Count == 1) throw Errors.UnlinkingLastAccount(ctx.DefaultPrefix);
var msg = $"Are you sure you want to unlink <@{id}> from your system?"; var msg = $"Are you sure you want to unlink <@{id}> from your system?";
if (!await ctx.PromptYesNo(msg, "Unlink")) throw Errors.MemberUnlinkCancelled; if (!await ctx.PromptYesNo(msg, "Unlink", flagValue: confirmYes)) throw Errors.MemberUnlinkCancelled;
await ctx.Repository.RemoveAccount(ctx.System.Id, id); await ctx.Repository.RemoveAccount(ctx.System.Id, id);
await ctx.Reply($"{Emojis.Success} Account unlinked."); await ctx.Reply($"{Emojis.Success} Account unlinked.");

View file

@ -560,7 +560,7 @@ public class EmbedService
return eb.Build(); return eb.Build();
} }
public async Task<MessageComponent[]> CreateGroupMessageComponents(Context ctx, PKSystem system, PKGroup target) public async Task<MessageComponent[]> CreateGroupMessageComponents(Context ctx, PKSystem system, PKGroup target, bool all)
{ {
var pctx = ctx.LookupContextFor(system.Id); var pctx = ctx.LookupContextFor(system.Id);
var name = target.NameFor(ctx); var name = target.NameFor(ctx);
@ -568,7 +568,7 @@ public class EmbedService
var systemName = (ctx.Guild != null && systemGuildSettings?.DisplayName != null) ? systemGuildSettings?.DisplayName! : system.NameFor(ctx); var systemName = (ctx.Guild != null && systemGuildSettings?.DisplayName != null) ? systemGuildSettings?.DisplayName! : system.NameFor(ctx);
var countctx = LookupContext.ByNonOwner; var countctx = LookupContext.ByNonOwner;
if (ctx.MatchFlag("a", "all")) if (all)
{ {
if (system.Id == ctx.System?.Id) if (system.Id == ctx.System?.Id)
countctx = LookupContext.ByOwner; countctx = LookupContext.ByOwner;
@ -673,12 +673,12 @@ public class EmbedService
]; ];
} }
public async Task<Embed> CreateGroupEmbed(Context ctx, PKSystem system, PKGroup target) public async Task<Embed> CreateGroupEmbed(Context ctx, PKSystem system, PKGroup target, bool all)
{ {
var pctx = ctx.LookupContextFor(system.Id); var pctx = ctx.LookupContextFor(system.Id);
var countctx = LookupContext.ByNonOwner; var countctx = LookupContext.ByNonOwner;
if (ctx.MatchFlag("a", "all")) if (all)
{ {
if (system.Id == ctx.System?.Id) if (system.Id == ctx.System?.Id)
countctx = LookupContext.ByOwner; countctx = LookupContext.ByOwner;

View file

@ -16,17 +16,17 @@ namespace PluralKit.Bot;
public static class ContextUtils public static class ContextUtils
{ {
public static async Task<bool> ConfirmClear(this Context ctx, string toClear, bool? confirmYes = null) public static async Task<bool> ConfirmClear(this Context ctx, string toClear, bool confirmYes)
{ {
if (!await ctx.PromptYesNo($"{Emojis.Warn} Are you sure you want to clear {toClear}?", "Clear", null, true, confirmYes)) if (!await ctx.PromptYesNo($"{Emojis.Warn} Are you sure you want to clear {toClear}?", "Clear", flagValue: confirmYes))
throw Errors.GenericCancelled(); throw Errors.GenericCancelled();
return true; return true;
} }
public static async Task<bool> PromptYesNo(this Context ctx, string msgString, string acceptButton, public static async Task<bool> PromptYesNo(this Context ctx, string msgString, string acceptButton,
User user = null, bool matchFlag = true, bool? flagValue = null) User user = null, bool matchFlag = true, bool flagValue = false)
{ {
if (matchFlag && (flagValue ?? ctx.MatchFlag("y", "yes"))) return true; if (matchFlag && flagValue) return true;
var prompt = new YesNoPrompt(ctx) var prompt = new YesNoPrompt(ctx)
{ {

View file

@ -16,6 +16,7 @@ pub fn cmds() -> impl Iterator<Item = Command> {
.help("Sets the deny flag on an abuse log entry"), .help("Sets the deny flag on an abuse log entry"),
command!(abuselog, ("description", ["desc"]), log_param, Optional(("desc", OpaqueStringRemainder)) => format!("admin_abuselog_description_{}", log_param.name())) command!(abuselog, ("description", ["desc"]), log_param, Optional(("desc", OpaqueStringRemainder)) => format!("admin_abuselog_description_{}", log_param.name()))
.flag(("clear", ["c"])) .flag(("clear", ["c"]))
.flag(("yes", ["y"]))
.help("Sets the description of an abuse log entry"), .help("Sets the description of an abuse log entry"),
command!(abuselog, ("adduser", ["au"]), log_param => format!("admin_abuselog_add_user_{}", log_param.name())) command!(abuselog, ("adduser", ["au"]), log_param => format!("admin_abuselog_add_user_{}", log_param.name()))
.help("Adds a user to an abuse log entry"), .help("Adds a user to an abuse log entry"),
@ -36,22 +37,31 @@ pub fn cmds() -> impl Iterator<Item = Command> {
[ [
command!(admin, ("updatesystemid", ["usid"]), SystemRef, ("new_hid", OpaqueString) => "admin_update_system_id") command!(admin, ("updatesystemid", ["usid"]), SystemRef, ("new_hid", OpaqueString) => "admin_update_system_id")
.flag(("yes", ["y"]))
.help("Updates a system's ID"), .help("Updates a system's ID"),
command!(admin, ("updatememberid", ["umid"]), MemberRef, ("new_hid", OpaqueString) => "admin_update_member_id") command!(admin, ("updatememberid", ["umid"]), MemberRef, ("new_hid", OpaqueString) => "admin_update_member_id")
.flag(("yes", ["y"]))
.help("Updates a member's ID"), .help("Updates a member's ID"),
command!(admin, ("updategroupid", ["ugid"]), GroupRef, ("new_hid", OpaqueString) => "admin_update_group_id") command!(admin, ("updategroupid", ["ugid"]), GroupRef, ("new_hid", OpaqueString) => "admin_update_group_id")
.flag(("yes", ["y"]))
.help("Updates a group's ID"), .help("Updates a group's ID"),
command!(admin, ("rerollsystemid", ["rsid"]), SystemRef => "admin_reroll_system_id") command!(admin, ("rerollsystemid", ["rsid"]), SystemRef => "admin_reroll_system_id")
.flag(("yes", ["y"]))
.help("Rerolls a system's ID"), .help("Rerolls a system's ID"),
command!(admin, ("rerollmemberid", ["rmid"]), MemberRef => "admin_reroll_member_id") command!(admin, ("rerollmemberid", ["rmid"]), MemberRef => "admin_reroll_member_id")
.flag(("yes", ["y"]))
.help("Rerolls a member's ID"), .help("Rerolls a member's ID"),
command!(admin, ("rerollgroupid", ["rgid"]), GroupRef => "admin_reroll_group_id") command!(admin, ("rerollgroupid", ["rgid"]), GroupRef => "admin_reroll_group_id")
.flag(("yes", ["y"]))
.help("Rerolls a group's ID"), .help("Rerolls a group's ID"),
command!(admin, ("updatememberlimit", ["uml"]), SystemRef, Optional(("limit", OpaqueInt)) => "admin_system_member_limit") command!(admin, ("updatememberlimit", ["uml"]), SystemRef, Optional(("limit", OpaqueInt)) => "admin_system_member_limit")
.flag(("yes", ["y"]))
.help("Updates a system's member limit"), .help("Updates a system's member limit"),
command!(admin, ("updategrouplimit", ["ugl"]), SystemRef, Optional(("limit", OpaqueInt)) => "admin_system_group_limit") command!(admin, ("updategrouplimit", ["ugl"]), SystemRef, Optional(("limit", OpaqueInt)) => "admin_system_group_limit")
.flag(("yes", ["y"]))
.help("Updates a system's group limit"), .help("Updates a system's group limit"),
command!(admin, ("systemrecover", ["sr"]), ("token", OpaqueString), ("account", UserRef) => "admin_system_recover") command!(admin, ("systemrecover", ["sr"]), ("token", OpaqueString), ("account", UserRef) => "admin_system_recover")
.flag(("yes", ["y"]))
.flag(("reroll-token", ["rt"])) .flag(("reroll-token", ["rt"]))
.help("Recovers a system"), .help("Recovers a system"),
command!(admin, ("systemdelete", ["sd"]), SystemRef => "admin_system_delete") command!(admin, ("systemdelete", ["sd"]), SystemRef => "admin_system_delete")

View file

@ -21,9 +21,10 @@ pub fn cmds() -> impl Iterator<Item = Command> {
[command!(group_new, ("name", OpaqueString) => "group_new").help("Creates a new group")] [command!(group_new, ("name", OpaqueString) => "group_new").help("Creates a new group")]
.into_iter(); .into_iter();
let group_info_cmd = let group_info_cmd = [command!(group_target => "group_info")
[command!(group_target => "group_info").help("Shows information about a group")] .flag(("all", ["a"]))
.into_iter(); .help("Shows information about a group")]
.into_iter();
let group_name = tokens!( let group_name = tokens!(
group_target, group_target,
@ -159,9 +160,9 @@ pub fn cmds() -> impl Iterator<Item = Command> {
let group_modify_members_cmd = [ let group_modify_members_cmd = [
command!(group_target, "add", Optional(MemberRefs) => "group_add_member") command!(group_target, "add", Optional(MemberRefs) => "group_add_member")
.flag(("all", ["a"])), .flag(("all", ["a"])).flag(("yes", ["y"])),
command!(group_target, ("remove", ["delete", "del", "rem"]), Optional(MemberRefs) => "group_remove_member") command!(group_target, ("remove", ["delete", "del", "rem"]), Optional(MemberRefs) => "group_remove_member")
.flag(("all", ["a"])), .flag(("all", ["a"])).flag(("yes", ["y"])),
] ]
.into_iter(); .into_iter();

View file

@ -2,7 +2,8 @@ use super::*;
pub fn cmds() -> impl Iterator<Item = Command> { pub fn cmds() -> impl Iterator<Item = Command> {
[ [
command!("import", Optional(("url", OpaqueStringRemainder)) => "import"), command!("import", Optional(("url", OpaqueStringRemainder)) => "import")
.flag(("yes", ["y"])),
command!("export" => "export"), command!("export" => "export"),
] ]
.into_iter() .into_iter()

View file

@ -49,6 +49,7 @@ pub fn cmds() -> impl Iterator<Item = Command> {
[ [
command!(member_name => "member_name_show").help("Shows a member's name"), command!(member_name => "member_name_show").help("Shows a member's name"),
command!(member_name, ("name", OpaqueStringRemainder) => "member_name_update") command!(member_name, ("name", OpaqueStringRemainder) => "member_name_update")
.flag(("yes", ["y"]))
.help("Changes a member's name"), .help("Changes a member's name"),
] ]
.into_iter() .into_iter()

View file

@ -51,6 +51,7 @@ pub fn cmds() -> impl Iterator<Item = Command> {
command!(log_channel, ("channel", ChannelRef) => "server_config_log_channel_set") command!(log_channel, ("channel", ChannelRef) => "server_config_log_channel_set")
.help("Sets the log channel"), .help("Sets the log channel"),
command!(log_channel, ("clear", ["c"]) => "server_config_log_channel_clear") command!(log_channel, ("clear", ["c"]) => "server_config_log_channel_clear")
.flag(("yes", ["y"]))
.help("Clears the log channel"), .help("Clears the log channel"),
] ]
.into_iter(); .into_iter();

View file

@ -20,7 +20,7 @@ pub fn cmds() -> impl Iterator<Item = Command> {
command!(switch, out => "switch_out"), command!(switch, out => "switch_out"),
command!(switch, r#move, OpaqueString => "switch_move"), // TODO: datetime parsing command!(switch, r#move, OpaqueString => "switch_move"), // TODO: datetime parsing
command!(switch, delete => "switch_delete").flag(("all", ["clear", "c"])), command!(switch, delete => "switch_delete").flag(("all", ["clear", "c"])),
command!(switch, edit, out => "switch_edit_out"), command!(switch, edit, out => "switch_edit_out").flag(("yes", ["y"])),
command!(switch, edit, Optional(MemberRefs) => "switch_edit").flags(edit_flags), command!(switch, edit, Optional(MemberRefs) => "switch_edit").flags(edit_flags),
command!(switch, copy, Optional(MemberRefs) => "switch_copy").flags(edit_flags), command!(switch, copy, Optional(MemberRefs) => "switch_copy").flags(edit_flags),
command!(switch, ("commands", ["help"]) => "switch_commands"), command!(switch, ("commands", ["help"]) => "switch_commands"),

View file

@ -28,25 +28,33 @@ pub fn edit() -> impl Iterator<Item = Command> {
] ]
.into_iter(); .into_iter();
let system_webhook_cmd = [command!(system, ("webhook", ["hook"]) => "system_webhook") let system_webhook = tokens!(system, ("webhook", ["hook"]));
.help("Creates a webhook for your system")] let system_webhook_cmd = [
command!(system_webhook => "system_webhook_show").help("Shows your system's webhook URL"),
command!(system_webhook, ("clear", ["c"]) => "system_webhook_clear")
.flag(("yes", ["y"]))
.help("Clears your system's webhook URL"),
command!(system_webhook, ("url", OpaqueString) => "system_webhook_set")
.help("Sets your system's webhook URL"),
]
.into_iter(); .into_iter();
let system_info_cmd = [ let add_info_flags = |cmd: Command| {
command!(system => "system_info_self").help("Shows information about your system"),
command!(system_target, ("info", ["show", "view"]) => "system_info")
.help("Shows information about your system"),
]
.into_iter()
.map(|cmd| {
cmd.flag(("public", ["pub"])) cmd.flag(("public", ["pub"]))
.flag(("private", ["priv"])) .flag(("private", ["priv"]))
.flag(("all", ["a"])) .flag(("all", ["a"]))
}); };
let system_info_cmd_self = std::iter::once(add_info_flags(
command!(system => "system_info_self").help("Shows information about your system"),
));
let system_info_cmd = std::iter::once(add_info_flags(
command!(system_target, ("info", ["show", "view"]) => "system_info")
.help("Shows information about your system"),
));
let system_name = tokens!(system_target, "name"); let system_name = tokens!(system_target, "name");
let system_name_cmd = let system_name_cmd =
[command!(system_name => "system_show_name").help("Shows the systems name")].into_iter(); std::iter::once(command!(system_name => "system_show_name").help("Shows the systems name"));
let system_name_self = tokens!(system, "name"); let system_name_self = tokens!(system, "name");
let system_name_self_cmd = [ let system_name_self_cmd = [
@ -60,9 +68,10 @@ pub fn edit() -> impl Iterator<Item = Command> {
.into_iter(); .into_iter();
let system_server_name = tokens!(system_target, ("servername", ["sn", "guildname"])); let system_server_name = tokens!(system_target, ("servername", ["sn", "guildname"]));
let system_server_name_cmd = [command!(system_server_name => "system_show_server_name") let system_server_name_cmd = std::iter::once(
.help("Shows the system's server name")] command!(system_server_name => "system_show_server_name")
.into_iter(); .help("Shows the system's server name"),
);
let system_server_name_self = tokens!(system, ("servername", ["sn", "guildname"])); let system_server_name_self = tokens!(system, ("servername", ["sn", "guildname"]));
let system_server_name_self_cmd = [ let system_server_name_self_cmd = [
@ -77,9 +86,10 @@ pub fn edit() -> impl Iterator<Item = Command> {
.into_iter(); .into_iter();
let system_description = tokens!(system_target, ("description", ["desc", "d"])); let system_description = tokens!(system_target, ("description", ["desc", "d"]));
let system_description_cmd = [command!(system_description => "system_show_description") let system_description_cmd = std::iter::once(
.help("Shows the system's description")] command!(system_description => "system_show_description")
.into_iter(); .help("Shows the system's description"),
);
let system_description_self = tokens!(system, ("description", ["desc", "d"])); let system_description_self = tokens!(system, ("description", ["desc", "d"]));
let system_description_self_cmd = [ let system_description_self_cmd = [
@ -93,9 +103,9 @@ pub fn edit() -> impl Iterator<Item = Command> {
.into_iter(); .into_iter();
let system_color = tokens!(system_target, ("color", ["colour"])); let system_color = tokens!(system_target, ("color", ["colour"]));
let system_color_cmd = let system_color_cmd = std::iter::once(
[command!(system_color => "system_show_color").help("Shows the system's color")] command!(system_color => "system_show_color").help("Shows the system's color"),
.into_iter(); );
let system_color_self = tokens!(system, ("color", ["colour"])); let system_color_self = tokens!(system, ("color", ["colour"]));
let system_color_self_cmd = [ let system_color_self_cmd = [
@ -110,7 +120,7 @@ pub fn edit() -> impl Iterator<Item = Command> {
let system_tag = tokens!(system_target, ("tag", ["suffix"])); let system_tag = tokens!(system_target, ("tag", ["suffix"]));
let system_tag_cmd = let system_tag_cmd =
[command!(system_tag => "system_show_tag").help("Shows the system's tag")].into_iter(); std::iter::once(command!(system_tag => "system_show_tag").help("Shows the system's tag"));
let system_tag_self = tokens!(system, ("tag", ["suffix"])); let system_tag_self = tokens!(system, ("tag", ["suffix"]));
let system_tag_self_cmd = [ let system_tag_self_cmd = [
@ -124,9 +134,10 @@ pub fn edit() -> impl Iterator<Item = Command> {
.into_iter(); .into_iter();
let system_server_tag = tokens!(system_target, ("servertag", ["st", "guildtag"])); let system_server_tag = tokens!(system_target, ("servertag", ["st", "guildtag"]));
let system_server_tag_cmd = [command!(system_server_tag => "system_show_server_tag") let system_server_tag_cmd = std::iter::once(
.help("Shows the system's server tag")] command!(system_server_tag => "system_show_server_tag")
.into_iter(); .help("Shows the system's server tag"),
);
let system_server_tag_self = tokens!(system, ("servertag", ["st", "guildtag"])); let system_server_tag_self = tokens!(system, ("servertag", ["st", "guildtag"]));
let system_server_tag_self_cmd = [ let system_server_tag_self_cmd = [
@ -141,9 +152,9 @@ pub fn edit() -> impl Iterator<Item = Command> {
.into_iter(); .into_iter();
let system_pronouns = tokens!(system_target, ("pronouns", ["prns"])); let system_pronouns = tokens!(system_target, ("pronouns", ["prns"]));
let system_pronouns_cmd = let system_pronouns_cmd = std::iter::once(
[command!(system_pronouns => "system_show_pronouns").help("Shows the system's pronouns")] command!(system_pronouns => "system_show_pronouns").help("Shows the system's pronouns"),
.into_iter(); );
let system_pronouns_self = tokens!(system, ("pronouns", ["prns"])); let system_pronouns_self = tokens!(system, ("pronouns", ["prns"]));
let system_pronouns_self_cmd = [ let system_pronouns_self_cmd = [
@ -158,9 +169,9 @@ pub fn edit() -> impl Iterator<Item = Command> {
.into_iter(); .into_iter();
let system_avatar = tokens!(system_target, ("avatar", ["pfp"])); let system_avatar = tokens!(system_target, ("avatar", ["pfp"]));
let system_avatar_cmd = let system_avatar_cmd = std::iter::once(
[command!(system_avatar => "system_show_avatar").help("Shows the system's avatar")] command!(system_avatar => "system_show_avatar").help("Shows the system's avatar"),
.into_iter(); );
let system_avatar_self = tokens!(system, ("avatar", ["pfp"])); let system_avatar_self = tokens!(system, ("avatar", ["pfp"]));
let system_avatar_self_cmd = [ let system_avatar_self_cmd = [
@ -175,11 +186,10 @@ pub fn edit() -> impl Iterator<Item = Command> {
.into_iter(); .into_iter();
let system_server_avatar = tokens!(system_target, ("serveravatar", ["spfp"])); let system_server_avatar = tokens!(system_target, ("serveravatar", ["spfp"]));
let system_server_avatar_cmd = [ let system_server_avatar_cmd = std::iter::once(
command!(system_server_avatar => "system_show_server_avatar") command!(system_server_avatar => "system_show_server_avatar")
.help("Shows the system's server avatar"), .help("Shows the system's server avatar"),
] );
.into_iter();
let system_server_avatar_self = tokens!(system, ("serveravatar", ["spfp"])); let system_server_avatar_self = tokens!(system, ("serveravatar", ["spfp"]));
let system_server_avatar_self_cmd = [ let system_server_avatar_self_cmd = [
@ -194,9 +204,9 @@ pub fn edit() -> impl Iterator<Item = Command> {
.into_iter(); .into_iter();
let system_banner = tokens!(system_target, ("banner", ["cover"])); let system_banner = tokens!(system_target, ("banner", ["cover"]));
let system_banner_cmd = let system_banner_cmd = std::iter::once(
[command!(system_banner => "system_show_banner").help("Shows the system's banner")] command!(system_banner => "system_show_banner").help("Shows the system's banner"),
.into_iter(); );
let system_banner_self = tokens!(system, ("banner", ["cover"])); let system_banner_self = tokens!(system, ("banner", ["cover"]));
let system_banner_self_cmd = [ let system_banner_self_cmd = [
@ -253,7 +263,7 @@ pub fn edit() -> impl Iterator<Item = Command> {
let system_link = [ let system_link = [
command!("link", ("account", UserRef) => "system_link"), command!("link", ("account", UserRef) => "system_link"),
command!("unlink", ("account", OpaqueString) => "system_unlink"), command!("unlink", ("account", OpaqueString) => "system_unlink").flag(("yes", ["y"])),
] ]
.into_iter(); .into_iter();
@ -286,10 +296,12 @@ pub fn edit() -> impl Iterator<Item = Command> {
.map(add_list_flags); .map(add_list_flags);
let system_display_id_self_cmd = let system_display_id_self_cmd =
[command!(system, "id" => "system_display_id_self")].into_iter(); std::iter::once(command!(system, "id" => "system_display_id_self"));
let system_display_id_cmd = [command!(system_target, "id" => "system_display_id")].into_iter(); let system_display_id_cmd =
std::iter::once(command!(system_target, "id" => "system_display_id"));
system_new_cmd system_info_cmd_self
.chain(system_new_cmd)
.chain(system_webhook_cmd) .chain(system_webhook_cmd)
.chain(system_name_self_cmd) .chain(system_name_self_cmd)
.chain(system_server_name_self_cmd) .chain(system_server_name_self_cmd)

View file

@ -4,7 +4,7 @@ use command_parser::Tree;
use commands::COMMAND_TREE; use commands::COMMAND_TREE;
fn main() { fn main() {
parse(); related();
} }
fn related() { fn related() {