From 4cc729c93c525d20be75caa68d651fb8173782fd Mon Sep 17 00:00:00 2001 From: dusk Date: Tue, 1 Apr 2025 01:03:49 +0900 Subject: [PATCH] feat: add color, tag, description, server tag system commands --- PluralKit.Bot/CommandMeta/CommandTree.cs | 58 +-- PluralKit.Bot/Commands/SystemEdit.cs | 501 +++++++++++------------ crates/command_definitions/src/system.rs | 123 +++++- 3 files changed, 385 insertions(+), 297 deletions(-) diff --git a/PluralKit.Bot/CommandMeta/CommandTree.cs b/PluralKit.Bot/CommandMeta/CommandTree.cs index f62d24b4..3f03c84c 100644 --- a/PluralKit.Bot/CommandMeta/CommandTree.cs +++ b/PluralKit.Bot/CommandMeta/CommandTree.cs @@ -13,27 +13,45 @@ public partial class CommandTree "For the list of commands, see the website: "), Commands.HelpProxy => ctx.Reply( "The proxy help page has been moved! See the website: https://pluralkit.me/guide#proxying"), - Commands.MemberShow(MemberShowParams param, _) => ctx.Execute(MemberInfo, m => m.ViewMember(ctx, param.target)), - Commands.MemberNew(MemberNewParams param, _) => ctx.Execute(MemberNew, m => m.NewMember(ctx, param.name)), - Commands.MemberSoulscream(MemberSoulscreamParams param, _) => ctx.Execute(MemberInfo, m => m.Soulscream(ctx, param.target)), + Commands.MemberShow(var param, _) => ctx.Execute(MemberInfo, m => m.ViewMember(ctx, param.target)), + Commands.MemberNew(var param, _) => ctx.Execute(MemberNew, m => m.NewMember(ctx, param.name)), + Commands.MemberSoulscream(var param, _) => ctx.Execute(MemberInfo, m => m.Soulscream(ctx, param.target)), Commands.CfgApAccountShow => ctx.Execute(null, m => m.ViewAutoproxyAccount(ctx)), - Commands.CfgApAccountUpdate(CfgApAccountUpdateParams param, _) => ctx.Execute(null, m => m.EditAutoproxyAccount(ctx, param.toggle)), + Commands.CfgApAccountUpdate(var param, _) => ctx.Execute(null, m => m.EditAutoproxyAccount(ctx, param.toggle)), Commands.CfgApTimeoutShow => ctx.Execute(null, m => m.ViewAutoproxyTimeout(ctx)), Commands.CfgApTimeoutOff => ctx.Execute(null, m => m.DisableAutoproxyTimeout(ctx)), Commands.CfgApTimeoutReset => ctx.Execute(null, m => m.ResetAutoproxyTimeout(ctx)), - Commands.CfgApTimeoutUpdate(CfgApTimeoutUpdateParams param, _) => ctx.Execute(null, m => m.EditAutoproxyTimeout(ctx, param.timeout)), + Commands.CfgApTimeoutUpdate(var param, _) => ctx.Execute(null, m => m.EditAutoproxyTimeout(ctx, param.timeout)), Commands.FunThunder => ctx.Execute(null, m => m.Thunder(ctx)), Commands.FunMeow => ctx.Execute(null, m => m.Meow(ctx)), - Commands.SystemInfo(SystemInfoParams param, SystemInfoFlags flags) => ctx.Execute(SystemInfo, m => m.Query(ctx, param.target, flags.all, flags.@public, flags.@private)), - Commands.SystemInfoSelf(_, SystemInfoSelfFlags flags) => ctx.Execute(SystemInfo, m => m.Query(ctx, ctx.System, flags.all, flags.@public, flags.@private)), - Commands.SystemNew(SystemNewParams param, _) => ctx.Execute(SystemNew, m => m.New(ctx, null)), - Commands.SystemNewName(SystemNewNameParams param, _) => ctx.Execute(SystemNew, m => m.New(ctx, param.name)), - Commands.SystemShowName(SystemShowNameParams param, SystemShowNameFlags flags) => ctx.Execute(SystemRename, m => m.ShowName(ctx, param.target, flags.GetReplyFormat())), - Commands.SystemRename(SystemRenameParams param, _) => ctx.Execute(SystemRename, m => m.Rename(ctx, param.target, param.name)), - Commands.SystemClearName(SystemClearNameParams param, _) => ctx.Execute(SystemRename, m => m.ClearName(ctx, param.target)), - Commands.SystemShowServerName(SystemShowServerNameParams param, SystemShowServerNameFlags flags) => ctx.Execute(SystemServerName, m => m.ShowServerName(ctx, param.target, flags.GetReplyFormat())), - Commands.SystemClearServerName(SystemClearServerNameParams param, _) => ctx.Execute(SystemServerName, m => m.ClearServerName(ctx, param.target)), - Commands.SystemRenameServerName(SystemRenameServerNameParams param, _) => ctx.Execute(SystemServerName, m => m.RenameServerName(ctx, param.target, param.name)), + Commands.SystemInfo(var param, var flags) => ctx.Execute(SystemInfo, m => m.Query(ctx, param.target, flags.all, flags.@public, flags.@private)), + Commands.SystemInfoSelf(_, var flags) => ctx.Execute(SystemInfo, m => m.Query(ctx, ctx.System, flags.all, flags.@public, flags.@private)), + Commands.SystemNew(var param, _) => ctx.Execute(SystemNew, m => m.New(ctx, null)), + Commands.SystemNewName(var param, _) => ctx.Execute(SystemNew, m => m.New(ctx, param.name)), + Commands.SystemShowNameSelf(_, var flags) => ctx.Execute(SystemRename, m => m.ShowName(ctx, ctx.System, flags.GetReplyFormat())), + Commands.SystemShowName(var param, var flags) => ctx.Execute(SystemRename, m => m.ShowName(ctx, param.target, flags.GetReplyFormat())), + Commands.SystemRename(var param, _) => ctx.Execute(SystemRename, m => m.Rename(ctx, ctx.System, param.name)), + Commands.SystemClearName(var param, _) => ctx.Execute(SystemRename, m => m.ClearName(ctx, ctx.System)), + Commands.SystemShowServerNameSelf(_, var flags) => ctx.Execute(SystemServerName, m => m.ShowServerName(ctx, ctx.System, flags.GetReplyFormat())), + Commands.SystemShowServerName(var param, var flags) => ctx.Execute(SystemServerName, m => m.ShowServerName(ctx, param.target, flags.GetReplyFormat())), + Commands.SystemClearServerName(var param, _) => ctx.Execute(SystemServerName, m => m.ClearServerName(ctx, ctx.System)), + Commands.SystemRenameServerName(var param, _) => ctx.Execute(SystemServerName, m => m.RenameServerName(ctx, ctx.System, param.name)), + Commands.SystemShowDescriptionSelf(_, var flags) => ctx.Execute(SystemDesc, m => m.ShowDescription(ctx, ctx.System, flags.GetReplyFormat())), + Commands.SystemShowDescription(var param, var flags) => ctx.Execute(SystemDesc, m => m.ShowDescription(ctx, param.target, flags.GetReplyFormat())), + Commands.SystemClearDescription(var param, _) => ctx.Execute(SystemDesc, m => m.ClearDescription(ctx, ctx.System)), + Commands.SystemChangeDescription(var param, _) => ctx.Execute(SystemDesc, m => m.ChangeDescription(ctx, ctx.System, param.description)), + Commands.SystemShowColorSelf(_, var flags) => ctx.Execute(SystemColor, m => m.ShowColor(ctx, ctx.System, flags.GetReplyFormat())), + Commands.SystemShowColor(var param, var flags) => ctx.Execute(SystemColor, m => m.ShowColor(ctx, param.target, flags.GetReplyFormat())), + Commands.SystemClearColor(var param, _) => ctx.Execute(SystemColor, m => m.ClearColor(ctx, ctx.System)), + Commands.SystemChangeColor(var param, _) => ctx.Execute(SystemColor, m => m.ChangeColor(ctx, ctx.System, param.color)), + Commands.SystemShowTagSelf(_, var flags) => ctx.Execute(SystemTag, m => m.ShowTag(ctx, ctx.System, flags.GetReplyFormat())), + Commands.SystemShowTag(var param, var flags) => ctx.Execute(SystemTag, m => m.ShowTag(ctx, param.target, flags.GetReplyFormat())), + Commands.SystemClearTag(var param, _) => ctx.Execute(SystemTag, m => m.ClearTag(ctx, ctx.System)), + Commands.SystemChangeTag(var param, _) => ctx.Execute(SystemTag, m => m.ChangeTag(ctx, ctx.System, param.tag)), + Commands.SystemShowServerTagSelf(_, var flags) => ctx.Execute(SystemServerTag, m => m.ShowServerTag(ctx, ctx.System, flags.GetReplyFormat())), + Commands.SystemShowServerTag(var param, var flags) => ctx.Execute(SystemServerTag, m => m.ShowServerTag(ctx, param.target, flags.GetReplyFormat())), + Commands.SystemClearServerTag(var param, _) => ctx.Execute(SystemServerTag, m => m.ClearServerTag(ctx, ctx.System)), + Commands.SystemChangeServerTag(var param, _) => ctx.Execute(SystemServerTag, m => m.ChangeServerTag(ctx, ctx.System, param.tag)), _ => // this should only ever occur when deving if commands are not implemented... ctx.Reply( @@ -282,16 +300,8 @@ public partial class CommandTree private async Task HandleSystemCommandTargeted(Context ctx, PKSystem target) { - if (ctx.Match("tag", "t")) - await ctx.CheckSystem(target).Execute(SystemTag, m => m.Tag(ctx, target)); - else if (ctx.Match("servertag", "st", "stag", "deer")) - await ctx.CheckSystem(target).Execute(SystemServerTag, m => m.ServerTag(ctx, target)); - else if (ctx.Match("description", "desc", "describe", "d", "bio", "info", "text", "intro")) - await ctx.CheckSystem(target).Execute(SystemDesc, m => m.Description(ctx, target)); - else if (ctx.Match("pronouns", "pronoun", "prns", "pn")) + if (ctx.Match("pronouns", "pronoun", "prns", "pn")) await ctx.CheckSystem(target).Execute(SystemPronouns, m => m.Pronouns(ctx, target)); - else if (ctx.Match("color", "colour")) - await ctx.CheckSystem(target).Execute(SystemColor, m => m.Color(ctx, target)); else if (ctx.Match("banner", "splash", "cover")) await ctx.CheckSystem(target).Execute(SystemBannerImage, m => m.BannerImage(ctx, target)); else if (ctx.Match("avatar", "picture", "icon", "image", "pic", "pfp")) diff --git a/PluralKit.Bot/Commands/SystemEdit.cs b/PluralKit.Bot/Commands/SystemEdit.cs index b9e2c6f1..32e87da2 100644 --- a/PluralKit.Bot/Commands/SystemEdit.cs +++ b/PluralKit.Bot/Commands/SystemEdit.cs @@ -154,7 +154,20 @@ public class SystemEdit await ctx.Reply($"{Emojis.Success} System name for this server changed (using {newSystemGuildName.Length}/{Limits.MaxSystemNameLength} characters)."); } - public async Task Description(Context ctx, PKSystem target) + public async Task ClearDescription(Context ctx, PKSystem target) + { + ctx.CheckSystemPrivacy(target.Id, target.DescriptionPrivacy); + ctx.CheckSystem().CheckOwnSystem(target); + + if (await ctx.ConfirmClear("your system's description")) + { + await ctx.Repository.UpdateSystem(target.Id, new SystemPatch { Description = null }); + + await ctx.Reply($"{Emojis.Success} System description cleared."); + } + } + + public async Task ShowDescription(Context ctx, PKSystem target, ReplyFormat format) { ctx.CheckSystemPrivacy(target.Id, target.DescriptionPrivacy); @@ -164,15 +177,11 @@ public class SystemEdit if (isOwnSystem) noDescriptionSetMessage += $" To set one, type `{ctx.DefaultPrefix}s description `."; - var format = ctx.MatchFormat(); - - // if there's nothing next or what's next is "raw"/"plaintext" we're doing a query, so check for null - if (!ctx.HasNext(false) || format != ReplyFormat.Standard) - if (target.Description == null) - { - await ctx.Reply(noDescriptionSetMessage); - return; - } + if (target.Description == null) + { + await ctx.Reply(noDescriptionSetMessage); + return; + } if (format == ReplyFormat.Raw) { @@ -187,92 +196,142 @@ public class SystemEdit return; } - if (!ctx.HasNext(false)) - { - await ctx.Reply(embed: new EmbedBuilder() - .Title("System description") - .Description(target.Description) - .Footer(new Embed.EmbedFooter( - $"To print the description with formatting, type `{ctx.DefaultPrefix}s description -raw`." - + (isOwnSystem ? $" To clear it, type `{ctx.DefaultPrefix}s description -clear`. To change it, type `{ctx.DefaultPrefix}s description `." - + $" Using {target.Description.Length}/{Limits.MaxDescriptionLength} characters." : ""))) - .Build()); - return; - } - - ctx.CheckSystem().CheckOwnSystem(target); - - if (ctx.MatchClear() && await ctx.ConfirmClear("your system's description")) - { - await ctx.Repository.UpdateSystem(target.Id, new SystemPatch { Description = null }); - - await ctx.Reply($"{Emojis.Success} System description cleared."); - } - else - { - var newDescription = ctx.RemainderOrNull(false).NormalizeLineEndSpacing(); - if (newDescription.Length > Limits.MaxDescriptionLength) - throw Errors.StringTooLongError("Description", newDescription.Length, Limits.MaxDescriptionLength); - - await ctx.Repository.UpdateSystem(target.Id, new SystemPatch { Description = newDescription }); - - await ctx.Reply($"{Emojis.Success} System description changed (using {newDescription.Length}/{Limits.MaxDescriptionLength} characters)."); - } + await ctx.Reply(embed: new EmbedBuilder() + .Title("System description") + .Description(target.Description) + .Footer(new Embed.EmbedFooter( + $"To print the description with formatting, type `{ctx.DefaultPrefix}s description -raw`." + + (isOwnSystem ? $" To clear it, type `{ctx.DefaultPrefix}s description -clear`. To change it, type `{ctx.DefaultPrefix}s description `." + + $" Using {target.Description.Length}/{Limits.MaxDescriptionLength} characters." : ""))) + .Build()); } - public async Task Color(Context ctx, PKSystem target) + public async Task ChangeDescription(Context ctx, PKSystem target, string newDescription) + { + ctx.CheckSystemPrivacy(target.Id, target.DescriptionPrivacy); + ctx.CheckSystem().CheckOwnSystem(target); + + newDescription = newDescription.NormalizeLineEndSpacing(); + if (newDescription.Length > Limits.MaxDescriptionLength) + throw Errors.StringTooLongError("Description", newDescription.Length, Limits.MaxDescriptionLength); + + await ctx.Repository.UpdateSystem(target.Id, new SystemPatch { Description = newDescription }); + + await ctx.Reply($"{Emojis.Success} System description changed (using {newDescription.Length}/{Limits.MaxDescriptionLength} characters)."); + } + + public async Task ChangeColor(Context ctx, PKSystem target, string newColor) + { + ctx.CheckSystem().CheckOwnSystem(target); + + if (newColor.StartsWith("#")) newColor = newColor.Substring(1); + if (!Regex.IsMatch(newColor, "^[0-9a-fA-F]{6}$")) throw Errors.InvalidColorError(newColor); + + await ctx.Repository.UpdateSystem(target.Id, + new SystemPatch { Color = Partial.Present(newColor.ToLowerInvariant()) }); + + await ctx.Reply(embed: new EmbedBuilder() + .Title($"{Emojis.Success} System color changed.") + .Color(newColor.ToDiscordColor()) + .Thumbnail(new Embed.EmbedThumbnail($"https://fakeimg.pl/256x256/{newColor}/?text=%20")) + .Build()); + } + + public async Task ClearColor(Context ctx, PKSystem target) + { + ctx.CheckSystem().CheckOwnSystem(target); + + await ctx.Repository.UpdateSystem(target.Id, new SystemPatch { Color = Partial.Null() }); + await ctx.Reply($"{Emojis.Success} System color cleared."); + } + + public async Task ShowColor(Context ctx, PKSystem target, ReplyFormat format) { var isOwnSystem = ctx.System?.Id == target.Id; - var matchedFormat = ctx.MatchFormat(); - var matchedClear = ctx.MatchClear(); - if (!isOwnSystem || !(ctx.HasNext() || matchedClear)) + if (target.Color == null) { - if (target.Color == null) - await ctx.Reply( - "This system does not have a color set." + (isOwnSystem ? $" To set one, type `{ctx.DefaultPrefix}system color `." : "")); - else if (matchedFormat == ReplyFormat.Raw) - await ctx.Reply("```\n#" + target.Color + "\n```"); - else if (matchedFormat == ReplyFormat.Plaintext) - await ctx.Reply(target.Color); - else - await ctx.Reply(embed: new EmbedBuilder() - .Title("System color") - .Color(target.Color.ToDiscordColor()) - .Thumbnail(new Embed.EmbedThumbnail($"https://fakeimg.pl/256x256/{target.Color}/?text=%20")) - .Description( - $"This system's color is **#{target.Color}**." + (isOwnSystem ? $" To clear it, type `{ctx.DefaultPrefix}s color -clear`." : "")) - .Build()); + await ctx.Reply( + "This system does not have a color set." + (isOwnSystem ? $" To set one, type `{ctx.DefaultPrefix}system color `." : "")); return; } + if (format == ReplyFormat.Raw) + { + await ctx.Reply("```\n#" + target.Color + "\n```"); + return; + } + + if (format == ReplyFormat.Plaintext) + { + await ctx.Reply(target.Color); + return; + } + + await ctx.Reply(embed: new EmbedBuilder() + .Title("System color") + .Color(target.Color.ToDiscordColor()) + .Thumbnail(new Embed.EmbedThumbnail($"https://fakeimg.pl/256x256/{target.Color}/?text=%20")) + .Description( + $"This system's color is **#{target.Color}**." + (isOwnSystem ? $" To clear it, type `{ctx.DefaultPrefix}s color -clear`." : "")) + .Build()); + } + + public async Task ClearTag(Context ctx, PKSystem target) + { ctx.CheckSystem().CheckOwnSystem(target); - if (matchedClear) + if (await ctx.ConfirmClear("your system's tag")) { - await ctx.Repository.UpdateSystem(target.Id, new SystemPatch { Color = Partial.Null() }); + await ctx.Repository.UpdateSystem(target.Id, new SystemPatch { Tag = null }); - await ctx.Reply($"{Emojis.Success} System color cleared."); - } - else - { - var color = ctx.RemainderOrNull(); + var replyStr = $"{Emojis.Success} System tag cleared."; - if (color.StartsWith("#")) color = color.Substring(1); - if (!Regex.IsMatch(color, "^[0-9a-fA-F]{6}$")) throw Errors.InvalidColorError(color); + if (ctx.Guild != null) + { + var servertag = (await ctx.Repository.GetSystemGuild(ctx.Guild.Id, target.Id)).Tag; + if (servertag is not null) + replyStr += $"\n{Emojis.Note} You have a server tag set in this server ({servertag}) so it will still be shown on proxies."; + else if (ctx.GuildConfig.RequireSystemTag) + replyStr += $"\n{Emojis.Warn} This server requires a tag in order to proxy. If you do not add a new tag you will not be able to proxy in this server."; + } - await ctx.Repository.UpdateSystem(target.Id, - new SystemPatch { Color = Partial.Present(color.ToLowerInvariant()) }); - - await ctx.Reply(embed: new EmbedBuilder() - .Title($"{Emojis.Success} System color changed.") - .Color(color.ToDiscordColor()) - .Thumbnail(new Embed.EmbedThumbnail($"https://fakeimg.pl/256x256/{color}/?text=%20")) - .Build()); + await ctx.Reply(replyStr); } } - public async Task Tag(Context ctx, PKSystem target) + public async Task ChangeTag(Context ctx, PKSystem target, string newTag) + { + ctx.CheckSystem().CheckOwnSystem(target); + + newTag = newTag.NormalizeLineEndSpacing(); + if (newTag.Length > Limits.MaxSystemTagLength) + throw Errors.StringTooLongError("System tag", newTag.Length, Limits.MaxSystemTagLength); + + await ctx.Repository.UpdateSystem(target.Id, new SystemPatch { Tag = newTag }); + + var replyStr = $"{Emojis.Success} System tag changed (using {newTag.Length}/{Limits.MaxSystemTagLength} characters)."; + if (ctx.Config.NameFormat is null || ctx.Config.NameFormat.Contains("{tag}")) + replyStr += $"Member names will now have the tag {newTag.AsCode()} when proxied.\n{Emojis.Note}To check or change where your tag appears in your name use the command `{ctx.DefaultPrefix}cfg name format`."; + else + replyStr += $"\n{Emojis.Warn} You do not have a designated place for a tag in your name format so it **will not be put in proxy names**. To change this type `{ctx.DefaultPrefix}cfg name format`."; + + if (ctx.Guild != null) + { + var guildSettings = await ctx.Repository.GetSystemGuild(ctx.Guild.Id, target.Id); + + if (guildSettings.Tag is not null) + replyStr += $"\n{Emojis.Note} Note that you have a server tag set ({guildSettings.Tag}) and it will be shown in proxies instead."; + if (!guildSettings.TagEnabled) + replyStr += $"\n{Emojis.Note} Note that your tag is disabled in this server and will not be shown in proxies. To change this type `{ctx.DefaultPrefix}system servertag enable`."; + if (guildSettings.NameFormat is not null && !guildSettings.NameFormat.Contains("{tag}")) + replyStr += $"\n{Emojis.Note} You do not have a designated place for a tag in your server name format so it **will not be put in proxy names**. To change this type `{ctx.DefaultPrefix}cfg server name format`."; + } + + await ctx.Reply(replyStr); + } + + public async Task ShowTag(Context ctx, PKSystem target, ReplyFormat format) { var isOwnSystem = ctx.System?.Id == target.Id; @@ -280,15 +339,11 @@ public class SystemEdit ? $"You currently have no system tag set. To set one, type `{ctx.DefaultPrefix}s tag `." : "This system currently has no system tag set."; - var format = ctx.MatchFormat(); - - // if there's nothing next or what's next is "raw"/"plaintext" we're doing a query, so check for null - if (!ctx.HasNext(false) || format != ReplyFormat.Standard) - if (target.Tag == null) - { - await ctx.Reply(noTagSetMessage); - return; - } + if (target.Tag == null) + { + await ctx.Reply(noTagSetMessage); + return; + } if (format == ReplyFormat.Raw) { @@ -303,193 +358,125 @@ public class SystemEdit return; } - if (!ctx.HasNext(false)) - { - await ctx.Reply($"{(isOwnSystem ? "Your" : "This system's")} current system tag is {target.Tag.AsCode()}." - + (isOwnSystem ? $"To change it, type `{ctx.DefaultPrefix}s tag `. To clear it, type `{ctx.DefaultPrefix}s tag -clear`." : "")); - return; - } - - ctx.CheckSystem().CheckOwnSystem(target); - - if (ctx.MatchClear() && await ctx.ConfirmClear("your system's tag")) - { - await ctx.Repository.UpdateSystem(target.Id, new SystemPatch { Tag = null }); - - var replyStr = $"{Emojis.Success} System tag cleared."; - - if (ctx.Guild != null) - { - var servertag = (await ctx.Repository.GetSystemGuild(ctx.Guild.Id, target.Id)).Tag; - if (servertag is not null) - replyStr += $"\n{Emojis.Note} You have a server tag set in this server ({servertag}) so it will still be shown on proxies."; - - else if (ctx.GuildConfig.RequireSystemTag) - replyStr += $"\n{Emojis.Warn} This server requires a tag in order to proxy. If you do not add a new tag you will not be able to proxy in this server."; - } - - await ctx.Reply(replyStr); - } - else - { - var newTag = ctx.RemainderOrNull(false).NormalizeLineEndSpacing(); - if (newTag != null) - if (newTag.Length > Limits.MaxSystemTagLength) - throw Errors.StringTooLongError("System tag", newTag.Length, Limits.MaxSystemTagLength); - - await ctx.Repository.UpdateSystem(target.Id, new SystemPatch { Tag = newTag }); - - var replyStr = $"{Emojis.Success} System tag changed (using {newTag.Length}/{Limits.MaxSystemTagLength} characters)."; - if (ctx.Config.NameFormat is null || ctx.Config.NameFormat.Contains("{tag}")) - replyStr += $"Member names will now have the tag {newTag.AsCode()} when proxied.\n{Emojis.Note}To check or change where your tag appears in your name use the command `{ctx.DefaultPrefix}cfg name format`."; - else - replyStr += $"\n{Emojis.Warn} You do not have a designated place for a tag in your name format so it **will not be put in proxy names**. To change this type `{ctx.DefaultPrefix}cfg name format`."; - if (ctx.Guild != null) - { - var guildSettings = await ctx.Repository.GetSystemGuild(ctx.Guild.Id, target.Id); - - if (guildSettings.Tag is not null) - replyStr += $"\n{Emojis.Note} Note that you have a server tag set ({guildSettings.Tag}) and it will be shown in proxies instead."; - if (!guildSettings.TagEnabled) - replyStr += $"\n{Emojis.Note} Note that your tag is disabled in this server and will not be shown in proxies. To change this type `{ctx.DefaultPrefix}system servertag enable`."; - if (guildSettings.NameFormat is not null && !guildSettings.NameFormat.Contains("{tag}")) - replyStr += $"\n{Emojis.Note} You do not have a designated place for a tag in your server name format so it **will not be put in proxy names**. To change this type `{ctx.DefaultPrefix}cfg server name format`."; - } - - await ctx.Reply(replyStr); - } + await ctx.Reply($"{(isOwnSystem ? "Your" : "This system's")} current system tag is {target.Tag.AsCode()}." + + (isOwnSystem ? $"To change it, type `{ctx.DefaultPrefix}s tag `. To clear it, type `{ctx.DefaultPrefix}s tag -clear`." : "")); } - public async Task ServerTag(Context ctx, PKSystem target) + public async Task ShowServerTag(Context ctx, PKSystem target, ReplyFormat format) { ctx.CheckSystem().CheckOwnSystem(target).CheckGuildContext(); - var setDisabledWarning = - $"{Emojis.Warn} Your system tag is currently **disabled** in this server. No tag will be applied when proxying.\nTo re-enable the system tag in the current server, type `{ctx.DefaultPrefix}s servertag -enable`."; - var settings = await ctx.Repository.GetSystemGuild(ctx.Guild.Id, target.Id); - async Task Show(ReplyFormat format = ReplyFormat.Standard) + if (settings.Tag != null) { - if (settings.Tag != null) + if (format == ReplyFormat.Raw) { - if (format == ReplyFormat.Raw) - { - await ctx.Reply($"```{settings.Tag}```"); - return; - } - if (format == ReplyFormat.Plaintext) - { - var eb = new EmbedBuilder() - .Description($"Showing servertag for system `{target.DisplayHid(ctx.Config)}`"); - await ctx.Reply(settings.Tag, embed: eb.Build()); - return; - } - - var msg = $"Your current system tag in '{ctx.Guild.Name}' is {settings.Tag.AsCode()}"; - if (!settings.TagEnabled) - msg += $", but it is currently **disabled**. To re-enable it, type `{ctx.DefaultPrefix}s servertag -enable`."; - else - msg += - $". To change it, type `{ctx.DefaultPrefix}s servertag `. To clear it, type `{ctx.DefaultPrefix}s servertag -clear`."; - - await ctx.Reply(msg); + await ctx.Reply($"```{settings.Tag}```"); + return; + } + if (format == ReplyFormat.Plaintext) + { + var eb = new EmbedBuilder() + .Description($"Showing servertag for system `{target.DisplayHid(ctx.Config)}`"); + await ctx.Reply(settings.Tag, embed: eb.Build()); return; } + var msg = $"Your current system tag in '{ctx.Guild.Name}' is {settings.Tag.AsCode()}"; if (!settings.TagEnabled) - await ctx.Reply( - $"Your global system tag is {target.Tag}, but it is **disabled** in this server. To re-enable it, type `{ctx.DefaultPrefix}s servertag -enable`"); + msg += $", but it is currently **disabled**. To re-enable it, type `{ctx.DefaultPrefix}s servertag -enable`."; else - await ctx.Reply( - $"You currently have no system tag specific to the server '{ctx.Guild.Name}'. To set one, type `{ctx.DefaultPrefix}s servertag `. To disable the system tag in the current server, type `{ctx.DefaultPrefix}s servertag -disable`."); + msg += + $". To change it, type `{ctx.DefaultPrefix}s servertag `. To clear it, type `{ctx.DefaultPrefix}s servertag -clear`."; + + await ctx.Reply(msg); + return; } - async Task Set() - { - var newTag = ctx.RemainderOrNull(false); - if (newTag != null && newTag.Length > Limits.MaxSystemTagLength) - throw Errors.StringTooLongError("System server tag", newTag.Length, Limits.MaxSystemTagLength); - - await ctx.Repository.UpdateSystemGuild(target.Id, ctx.Guild.Id, new SystemGuildPatch { Tag = newTag }); - - var replyStr = $"{Emojis.Success} System server tag changed (using {newTag.Length}/{Limits.MaxSystemTagLength} characters). Member names will now have the tag {newTag.AsCode()} when proxied in the current server '{ctx.Guild.Name}'.\n\nTo check or change where your tag appears in your name use the command `{ctx.DefaultPrefix}cfg name format`."; - - if (!settings.TagEnabled) - replyStr += "\n" + setDisabledWarning; - - await ctx.Reply(replyStr); - } - - async Task Clear() - { - await ctx.Repository.UpdateSystemGuild(target.Id, ctx.Guild.Id, new SystemGuildPatch { Tag = null }); - - var replyStr = $"{Emojis.Success} System server tag cleared. Member names will now use the global system tag, if there is one set.\n\nTo check or change where your tag appears in your name use the command `{ctx.DefaultPrefix}cfg name format`."; - - if (!settings.TagEnabled) - replyStr += "\n" + setDisabledWarning; - - await ctx.Reply(replyStr); - } - - async Task EnableDisable(bool newValue) - { - await ctx.Repository.UpdateSystemGuild(target.Id, ctx.Guild.Id, - new SystemGuildPatch { TagEnabled = newValue }); - - await ctx.Reply(PrintEnableDisableResult(newValue, newValue != settings.TagEnabled)); - } - - string PrintEnableDisableResult(bool newValue, bool changedValue) - { - var opStr = newValue ? "enabled" : "disabled"; - var str = ""; - - if (!changedValue) - str = $"{Emojis.Note} The system tag is already {opStr} in this server."; - else - str = $"{Emojis.Success} System tag {opStr} in this server."; - - if (newValue) - { - if (settings.TagEnabled) - { - if (settings.Tag == null) - str += - " However, you do not have a system tag specific to this server. Messages will be proxied using your global system tag, if there is one set."; - else - str += - $" Your current system tag in '{ctx.Guild.Name}' is {settings.Tag.AsCode()}."; - } - else - { - if (settings.Tag != null) - str += - $" Member names will now use the server-specific tag {settings.Tag.AsCode()} when proxied in the current server '{ctx.Guild.Name}'." - + $"\n\nTo check or change where your tag appears in your name use the command `{ctx.DefaultPrefix}cfg name format`."; - else - str += - " Member names will now use the global system tag when proxied in the current server, if there is one set." - + "\n\nTo check or change where your tag appears in your name use the command `{ctx.DefaultPrefix}cfg name format`."; - } - } - - return str; - } - - if (ctx.MatchClear() && await ctx.ConfirmClear("your system's server tag")) - await Clear(); - else if (ctx.Match("disable") || ctx.MatchFlag("disable")) - await EnableDisable(false); - else if (ctx.Match("enable") || ctx.MatchFlag("enable")) - await EnableDisable(true); - else if (ctx.MatchFormat() != ReplyFormat.Standard) - await Show(ctx.MatchFormat()); - else if (!ctx.HasNext(false)) - await Show(); + if (!settings.TagEnabled) + await ctx.Reply( + $"Your global system tag is {target.Tag}, but it is **disabled** in this server. To re-enable it, type `{ctx.DefaultPrefix}s servertag -enable`"); else - await Set(); + await ctx.Reply( + $"You currently have no system tag specific to the server '{ctx.Guild.Name}'. To set one, type `{ctx.DefaultPrefix}s servertag `. To disable the system tag in the current server, type `{ctx.DefaultPrefix}s servertag -disable`."); + } + + public async Task ClearServerTag(Context ctx, PKSystem target) + { + ctx.CheckSystem().CheckOwnSystem(target).CheckGuildContext(); + + if (!await ctx.ConfirmClear("your system's server tag")) + return; + + var settings = await ctx.Repository.GetSystemGuild(ctx.Guild.Id, target.Id); + await ctx.Repository.UpdateSystemGuild(target.Id, ctx.Guild.Id, new SystemGuildPatch { Tag = null }); + + var replyStr = $"{Emojis.Success} System server tag cleared. Member names will now use the global system tag, if there is one set.\n\nTo check or change where your tag appears in your name use the command `{ctx.DefaultPrefix}cfg name format`."; + + if (!settings.TagEnabled) + replyStr += $"\n{Emojis.Warn} Your system tag is currently **disabled** in this server. No tag will be applied when proxying.\nTo re-enable the system tag in the current server, type `{ctx.DefaultPrefix}s servertag -enable`."; + + await ctx.Reply(replyStr); + } + + public async Task ChangeServerTag(Context ctx, PKSystem target, string newTag) + { + ctx.CheckSystem().CheckOwnSystem(target).CheckGuildContext(); + + var settings = await ctx.Repository.GetSystemGuild(ctx.Guild.Id, target.Id); + + if (newTag != null && newTag.Length > Limits.MaxSystemTagLength) + throw Errors.StringTooLongError("System server tag", newTag.Length, Limits.MaxSystemTagLength); + + await ctx.Repository.UpdateSystemGuild(target.Id, ctx.Guild.Id, new SystemGuildPatch { Tag = newTag }); + + var replyStr = $"{Emojis.Success} System server tag changed (using {newTag.Length}/{Limits.MaxSystemTagLength} characters). Member names will now have the tag {newTag.AsCode()} when proxied in the current server '{ctx.Guild.Name}'.\n\nTo check or change where your tag appears in your name use the command `{ctx.DefaultPrefix}cfg name format`."; + + if (!settings.TagEnabled) + replyStr += $"\n{Emojis.Warn} Your system tag is currently **disabled** in this server. No tag will be applied when proxying.\nTo re-enable the system tag in the current server, type `{ctx.DefaultPrefix}s servertag -enable`."; + + await ctx.Reply(replyStr); + } + + public async Task ToggleServerTag(Context ctx, PKSystem target, bool newValue) + { + ctx.CheckSystem().CheckOwnSystem(target).CheckGuildContext(); + + var settings = await ctx.Repository.GetSystemGuild(ctx.Guild.Id, target.Id); + await ctx.Repository.UpdateSystemGuild(target.Id, ctx.Guild.Id, new SystemGuildPatch { TagEnabled = newValue }); + + var opStr = newValue ? "enabled" : "disabled"; + string str; + + if (newValue == settings.TagEnabled) + str = $"{Emojis.Note} The system tag is already {opStr} in this server."; + else + str = $"{Emojis.Success} System tag {opStr} in this server."; + + if (newValue) + { + if (settings.TagEnabled) + { + if (settings.Tag == null) + str += " However, you do not have a system tag specific to this server. Messages will be proxied using your global system tag, if there is one set."; + else + str += $" Your current system tag in '{ctx.Guild.Name}' is {settings.Tag.AsCode()}."; + } + else + { + if (settings.Tag != null) + str += + $" Member names will now use the server-specific tag {settings.Tag.AsCode()} when proxied in the current server '{ctx.Guild.Name}'." + + $"\n\nTo check or change where your tag appears in your name use the command `{ctx.DefaultPrefix}cfg name format`."; + else + str += + " Member names will now use the global system tag when proxied in the current server, if there is one set." + + "\n\nTo check or change where your tag appears in your name use the command `{ctx.DefaultPrefix}cfg name format`."; + } + } + + await ctx.Reply(str); } public async Task Pronouns(Context ctx, PKSystem target) diff --git a/crates/command_definitions/src/system.rs b/crates/command_definitions/src/system.rs index e08e61c4..f7262832 100644 --- a/crates/command_definitions/src/system.rs +++ b/crates/command_definitions/src/system.rs @@ -1,9 +1,21 @@ use super::*; pub fn cmds() -> impl Iterator { + edit() +} + +pub fn edit() -> impl Iterator { let system = ("system", ["s"]); let system_target = tokens!(system, SystemRef); + let system_new = tokens!(system, ("new", ["n"])); + let system_new_cmd = [ + command!(system_new => "system_new").help("Creates a new system"), + command!(system_new, ("name", OpaqueString) => "system_new_name") + .help("Creates a new system (using the provided name)"), + ] + .into_iter(); + let system_info_cmd = [ command!(system => "system_info_self").help("Shows information about your system"), command!(system_target, ("info", ["show", "view"]) => "system_info") @@ -19,10 +31,16 @@ pub fn cmds() -> impl Iterator { let system_name = tokens!(system_target, "name"); let system_name_cmd = [ command!(system_name => "system_show_name").help("Shows the systems name"), - command!(system_name, ("clear", ["c"]) => "system_clear_name") - .help("Clears the system's name"), - command!(system_name, ("name", OpaqueString) => "system_rename") - .help("Renames a given system"), + ] + .into_iter(); + + let system_name_self = tokens!(system, "name"); + let system_name_self_cmd = [ + command!(system_name_self => "system_show_name_self").help("Shows your system's name"), + command!(system_name_self, ("clear", ["c"]) => "system_clear_name") + .help("Clears your system's name"), + command!(system_name_self, ("name", OpaqueString) => "system_rename") + .help("Renames your system"), ] .into_iter(); @@ -30,23 +48,96 @@ pub fn cmds() -> impl Iterator { let system_server_name_cmd = [ command!(system_server_name => "system_show_server_name") .help("Shows the system's server name"), - command!(system_server_name, ("clear", ["c"]) => "system_clear_server_name") - .help("Clears the system's server name"), - command!(system_server_name, ("name", OpaqueString) => "system_rename_server_name") - .help("Renames the system's server name"), ] .into_iter(); - let system_new = tokens!(system, ("new", ["n"])); - let system_new_cmd = [ - command!(system_new => "system_new").help("Creates a new system"), - command!(system_new, ("name", OpaqueString) => "system_new_name") - .help("Creates a new system (using the provided name)"), + let system_server_name_self = tokens!(system, ("servername", ["sn", "guildname"])); + let system_server_name_self_cmd = [ + command!(system_server_name_self => "system_show_server_name_self") + .help("Shows your system's server name"), + command!(system_server_name_self, ("clear", ["c"]) => "system_clear_server_name") + .help("Clears your system's server name"), + command!(system_server_name_self, ("name", OpaqueString) => "system_rename_server_name") + .help("Renames your system's server name"), ] .into_iter(); - system_info_cmd + let system_description = tokens!(system_target, ("description", ["desc", "d"])); + let system_description_cmd = [ + command!(system_description => "system_show_description").help("Shows the system's description"), + ] + .into_iter(); + + let system_description_self = tokens!(system, ("description", ["desc", "d"])); + let system_description_self_cmd = [ + command!(system_description_self => "system_show_description_self").help("Shows your system's description"), + command!(system_description_self, ("clear", ["c"]) => "system_clear_description") + .help("Clears your system's description"), + command!(system_description_self, ("description", OpaqueString) => "system_change_description") + .help("Changes your system's description"), + ] + .into_iter(); + + let system_color = tokens!(system_target, ("color", ["colour"])); + let system_color_cmd = [ + 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_cmd = [ + command!(system_color_self => "system_show_color_self").help("Shows your system's color"), + command!(system_color_self, ("clear", ["c"]) => "system_clear_color") + .help("Clears your system's color"), + command!(system_color_self, ("color", OpaqueString) => "system_change_color") + .help("Changes your system's color"), + ] + .into_iter(); + + let system_tag = tokens!(system_target, ("tag", ["suffix"])); + let system_tag_cmd = [ + command!(system_tag => "system_show_tag").help("Shows the system's tag"), + ] + .into_iter(); + + let system_tag_self = tokens!(system, ("tag", ["suffix"])); + let system_tag_self_cmd = [ + command!(system_tag_self => "system_show_tag_self").help("Shows your system's tag"), + command!(system_tag_self, ("clear", ["c"]) => "system_clear_tag") + .help("Clears your system's tag"), + command!(system_tag_self, ("tag", OpaqueString) => "system_change_tag") + .help("Changes your system's tag"), + ] + .into_iter(); + + let system_server_tag = tokens!(system_target, ("servertag", ["st", "guildtag"])); + let system_server_tag_cmd = [ + command!(system_server_tag => "system_show_server_tag").help("Shows the system's server tag"), + ] + .into_iter(); + + let system_server_tag_self = tokens!(system, ("servertag", ["st", "guildtag"])); + let system_server_tag_self_cmd = [ + command!(system_server_tag_self => "system_show_server_tag_self").help("Shows your system's server tag"), + command!(system_server_tag_self, ("clear", ["c"]) => "system_clear_server_tag") + .help("Clears your system's server tag"), + command!(system_server_tag_self, ("tag", OpaqueString) => "system_change_server_tag") + .help("Changes your system's server tag"), + ] + .into_iter(); + + system_new_cmd + .chain(system_name_self_cmd) + .chain(system_server_name_self_cmd) + .chain(system_description_self_cmd) + .chain(system_color_self_cmd) + .chain(system_tag_self_cmd) + .chain(system_server_tag_self_cmd) .chain(system_name_cmd) .chain(system_server_name_cmd) - .chain(system_new_cmd) -} + .chain(system_description_cmd) + .chain(system_color_cmd) + .chain(system_tag_cmd) + .chain(system_server_tag_cmd) + .chain(system_info_cmd) +} \ No newline at end of file