implement the rest of the config commands

This commit is contained in:
dusk 2025-10-04 19:32:58 +00:00
parent a268f75d32
commit 0f26a69f1b
No known key found for this signature in database
11 changed files with 480 additions and 296 deletions

View file

@ -70,12 +70,45 @@ public partial class CommandTree
Commands.MemberGroupAdd(var param, _) => ctx.Execute<GroupMember>(MemberGroupAdd, m => m.AddRemoveGroups(ctx, param.target, param.groups, Groups.AddRemoveOperation.Add)), Commands.MemberGroupAdd(var param, _) => ctx.Execute<GroupMember>(MemberGroupAdd, m => m.AddRemoveGroups(ctx, param.target, param.groups, Groups.AddRemoveOperation.Add)),
Commands.MemberGroupRemove(var param, _) => ctx.Execute<GroupMember>(MemberGroupRemove, m => m.AddRemoveGroups(ctx, param.target, param.groups, Groups.AddRemoveOperation.Remove)), Commands.MemberGroupRemove(var param, _) => ctx.Execute<GroupMember>(MemberGroupRemove, m => m.AddRemoveGroups(ctx, param.target, param.groups, Groups.AddRemoveOperation.Remove)),
Commands.MemberId(var param, _) => ctx.Execute<Member>(MemberId, m => m.DisplayId(ctx, param.target)), Commands.MemberId(var param, _) => ctx.Execute<Member>(MemberId, m => m.DisplayId(ctx, param.target)),
Commands.CfgShow => ctx.Execute<Config>(null, m => m.ShowConfig(ctx)),
Commands.CfgApAccountShow => ctx.Execute<Config>(null, m => m.ViewAutoproxyAccount(ctx)), Commands.CfgApAccountShow => ctx.Execute<Config>(null, m => m.ViewAutoproxyAccount(ctx)),
Commands.CfgApAccountUpdate(var param, _) => ctx.Execute<Config>(null, m => m.EditAutoproxyAccount(ctx, param.toggle)), Commands.CfgApAccountUpdate(var param, _) => ctx.Execute<Config>(null, m => m.EditAutoproxyAccount(ctx, param.toggle)),
Commands.CfgApTimeoutShow => ctx.Execute<Config>(null, m => m.ViewAutoproxyTimeout(ctx)), Commands.CfgApTimeoutShow => ctx.Execute<Config>(null, m => m.ViewAutoproxyTimeout(ctx)),
Commands.CfgApTimeoutOff => ctx.Execute<Config>(null, m => m.DisableAutoproxyTimeout(ctx)), Commands.CfgApTimeoutOff => ctx.Execute<Config>(null, m => m.DisableAutoproxyTimeout(ctx)),
Commands.CfgApTimeoutReset => ctx.Execute<Config>(null, m => m.ResetAutoproxyTimeout(ctx)), Commands.CfgApTimeoutReset => ctx.Execute<Config>(null, m => m.ResetAutoproxyTimeout(ctx)),
Commands.CfgApTimeoutUpdate(var param, _) => ctx.Execute<Config>(null, m => m.EditAutoproxyTimeout(ctx, param.timeout)), Commands.CfgApTimeoutUpdate(var param, _) => ctx.Execute<Config>(null, m => m.EditAutoproxyTimeout(ctx, param.timeout)),
Commands.CfgTimezoneShow => ctx.Execute<Config>(null, m => m.ViewSystemTimezone(ctx)),
Commands.CfgTimezoneReset => ctx.Execute<Config>(null, m => m.ResetSystemTimezone(ctx)),
Commands.CfgTimezoneUpdate(var param, _) => ctx.Execute<Config>(null, m => m.EditSystemTimezone(ctx, param.timezone)),
Commands.CfgPingShow => ctx.Execute<Config>(null, m => m.ViewSystemPing(ctx)),
Commands.CfgPingUpdate(var param, _) => ctx.Execute<Config>(null, m => m.EditSystemPing(ctx, param.toggle)),
Commands.CfgMemberPrivacyShow => ctx.Execute<Config>(null, m => m.ViewMemberDefaultPrivacy(ctx)),
Commands.CfgMemberPrivacyUpdate(var param, _) => ctx.Execute<Config>(null, m => m.EditMemberDefaultPrivacy(ctx, param.toggle)),
Commands.CfgGroupPrivacyShow => ctx.Execute<Config>(null, m => m.ViewGroupDefaultPrivacy(ctx)),
Commands.CfgGroupPrivacyUpdate(var param, _) => ctx.Execute<Config>(null, m => m.EditGroupDefaultPrivacy(ctx, param.toggle)),
Commands.CfgShowPrivateInfoShow => ctx.Execute<Config>(null, m => m.ViewShowPrivateInfo(ctx)),
Commands.CfgShowPrivateInfoUpdate(var param, _) => ctx.Execute<Config>(null, m => m.EditShowPrivateInfo(ctx, param.toggle)),
Commands.CfgCaseSensitiveProxyTagsShow => ctx.Execute<Config>(null, m => m.ViewCaseSensitiveProxyTags(ctx)),
Commands.CfgCaseSensitiveProxyTagsUpdate(var param, _) => ctx.Execute<Config>(null, m => m.EditCaseSensitiveProxyTags(ctx, param.toggle)),
Commands.CfgProxyErrorMessageShow => ctx.Execute<Config>(null, m => m.ViewProxyErrorMessageEnabled(ctx)),
Commands.CfgProxyErrorMessageUpdate(var param, _) => ctx.Execute<Config>(null, m => m.EditProxyErrorMessageEnabled(ctx, param.toggle)),
Commands.CfgHidSplitShow => ctx.Execute<Config>(null, m => m.ViewHidDisplaySplit(ctx)),
Commands.CfgHidSplitUpdate(var param, _) => ctx.Execute<Config>(null, m => m.EditHidDisplaySplit(ctx, param.toggle)),
Commands.CfgHidCapsShow => ctx.Execute<Config>(null, m => m.ViewHidDisplayCaps(ctx)),
Commands.CfgHidCapsUpdate(var param, _) => ctx.Execute<Config>(null, m => m.EditHidDisplayCaps(ctx, param.toggle)),
Commands.CfgHidPaddingShow => ctx.Execute<Config>(null, m => m.ViewHidListPadding(ctx)),
Commands.CfgHidPaddingUpdate(var param, _) => ctx.Execute<Config>(null, m => m.EditHidListPadding(ctx, param.padding)),
Commands.CfgCardShowColorHexShow => ctx.Execute<Config>(null, m => m.ViewCardShowColorHex(ctx)),
Commands.CfgCardShowColorHexUpdate(var param, _) => ctx.Execute<Config>(null, m => m.EditCardShowColorHex(ctx, param.toggle)),
Commands.CfgProxySwitchShow => ctx.Execute<Config>(null, m => m.ViewProxySwitch(ctx)),
Commands.CfgProxySwitchUpdate(var param, _) => ctx.Execute<Config>(null, m => m.EditProxySwitch(ctx, param.proxy_switch_action)),
Commands.CfgNameFormatShow => ctx.Execute<Config>(null, m => m.ViewNameFormat(ctx)),
Commands.CfgNameFormatReset => ctx.Execute<Config>(null, m => m.ResetNameFormat(ctx)),
Commands.CfgNameFormatUpdate(var param, _) => ctx.Execute<Config>(null, m => m.EditNameFormat(ctx, param.format)),
Commands.CfgServerNameFormatShow(_, var flags) => ctx.Execute<Config>(null, m => m.ViewServerNameFormat(ctx, flags.GetReplyFormat())),
Commands.CfgServerNameFormatReset => ctx.Execute<Config>(null, m => m.ResetServerNameFormat(ctx)),
Commands.CfgServerNameFormatUpdate(var param, _) => ctx.Execute<Config>(null, m => m.EditServerNameFormat(ctx, param.format)),
Commands.CfgLimitsUpdate => ctx.Execute<Config>(null, m => m.LimitUpdate(ctx)),
Commands.FunThunder => ctx.Execute<Fun>(null, m => m.Thunder(ctx)), Commands.FunThunder => ctx.Execute<Fun>(null, m => m.Thunder(ctx)),
Commands.FunMeow => ctx.Execute<Fun>(null, m => m.Meow(ctx)), Commands.FunMeow => ctx.Execute<Fun>(null, m => m.Meow(ctx)),
Commands.FunPokemon => ctx.Execute<Fun>(null, m => m.Mn(ctx)), Commands.FunPokemon => ctx.Execute<Fun>(null, m => m.Mn(ctx)),
@ -187,8 +220,8 @@ public partial class CommandTree
? ctx.Execute<Random>(GroupRandom, m => m.Group(ctx, param.target, flags.all, flags.show_embed)) ? ctx.Execute<Random>(GroupRandom, m => m.Group(ctx, param.target, flags.all, flags.show_embed))
: 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 => ctx.Execute<SystemLink>(Link, m => m.LinkSystem(ctx)), 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.target)), Commands.SystemUnlink(var param, _) => ctx.Execute<SystemLink>(Unlink, m => m.UnlinkAccount(ctx, param.account)),
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)),
@ -279,8 +312,6 @@ public partial class CommandTree
}; };
if (ctx.Match("commands", "cmd", "c")) if (ctx.Match("commands", "cmd", "c"))
return CommandHelpRoot(ctx); return CommandHelpRoot(ctx);
if (ctx.Match("config", "cfg", "configure"))
return HandleConfigCommand(ctx);
if (ctx.Match("serverconfig", "guildconfig", "scfg")) if (ctx.Match("serverconfig", "guildconfig", "scfg"))
return HandleServerConfigCommand(ctx); return HandleServerConfigCommand(ctx);
if (ctx.Match("log")) if (ctx.Match("log"))
@ -371,49 +402,6 @@ public partial class CommandTree
} }
} }
private Task HandleConfigCommand(Context ctx)
{
if (ctx.System == null)
return ctx.Reply($"{Emojis.Error} {Errors.NoSystemError(ctx.DefaultPrefix).Message}");
if (!ctx.HasNext())
return ctx.Execute<Config>(null, m => m.ShowConfig(ctx));
if (ctx.Match("timezone", "zone", "tz"))
return ctx.Execute<Config>(null, m => m.SystemTimezone(ctx));
if (ctx.Match("ping"))
return ctx.Execute<Config>(null, m => m.SystemPing(ctx));
if (ctx.MatchMultiple(new[] { "private" }, new[] { "member" }) || ctx.Match("mp"))
return ctx.Execute<Config>(null, m => m.MemberDefaultPrivacy(ctx));
if (ctx.MatchMultiple(new[] { "private" }, new[] { "group" }) || ctx.Match("gp"))
return ctx.Execute<Config>(null, m => m.GroupDefaultPrivacy(ctx));
if (ctx.MatchMultiple(new[] { "show" }, new[] { "private" }) || ctx.Match("sp"))
return ctx.Execute<Config>(null, m => m.ShowPrivateInfo(ctx));
if (ctx.MatchMultiple(new[] { "proxy" }, new[] { "case" }))
return ctx.Execute<Config>(null, m => m.CaseSensitiveProxyTags(ctx));
if (ctx.MatchMultiple(new[] { "proxy" }, new[] { "error" }) || ctx.Match("pe"))
return ctx.Execute<Config>(null, m => m.ProxyErrorMessageEnabled(ctx));
if (ctx.MatchMultiple(new[] { "split" }, new[] { "id", "ids" }) || ctx.Match("sid", "sids"))
return ctx.Execute<Config>(null, m => m.HidDisplaySplit(ctx));
if (ctx.MatchMultiple(new[] { "cap", "caps", "capitalize", "capitalise" }, new[] { "id", "ids" }) || ctx.Match("capid", "capids"))
return ctx.Execute<Config>(null, m => m.HidDisplayCaps(ctx));
if (ctx.MatchMultiple(new[] { "pad" }, new[] { "id", "ids" }) || ctx.MatchMultiple(new[] { "id" }, new[] { "pad", "padding" }) || ctx.Match("idpad", "padid", "padids"))
return ctx.Execute<Config>(null, m => m.HidListPadding(ctx));
if (ctx.MatchMultiple(new[] { "show" }, new[] { "color", "colour", "colors", "colours" }) || ctx.Match("showcolor", "showcolour", "showcolors", "showcolours", "colorcode", "colorhex"))
return ctx.Execute<Config>(null, m => m.CardShowColorHex(ctx));
if (ctx.MatchMultiple(new[] { "name" }, new[] { "format" }) || ctx.Match("nameformat", "nf"))
return ctx.Execute<Config>(null, m => m.NameFormat(ctx));
if (ctx.MatchMultiple(new[] { "member", "group" }, new[] { "limit" }) || ctx.Match("limit"))
return ctx.Execute<Config>(null, m => m.LimitUpdate(ctx));
if (ctx.MatchMultiple(new[] { "proxy" }, new[] { "switch" }) || ctx.Match("proxyswitch", "ps"))
return ctx.Execute<Config>(null, m => m.ProxySwitch(ctx));
if (ctx.MatchMultiple(new[] { "server" }, new[] { "name" }, new[] { "format" }) || ctx.MatchMultiple(new[] { "server", "servername" }, new[] { "format", "nameformat", "nf" }) || ctx.Match("snf", "servernf", "servernameformat", "snameformat"))
return ctx.Execute<Config>(null, m => m.ServerNameFormat(ctx));
// todo: maybe add the list of configuration keys here?
return ctx.Reply($"{Emojis.Error} Could not find a setting with that name. Please see `{ctx.DefaultPrefix}commands config` for the list of possible config settings.");
}
private Task HandleServerConfigCommand(Context ctx) private Task HandleServerConfigCommand(Context ctx)
{ {
if (!ctx.HasNext()) if (!ctx.HasNext())

View file

@ -101,6 +101,14 @@ public static class ContextParametersExt
); );
} }
public static async Task<SystemConfig.ProxySwitchAction?> ParamResolveProxySwitchAction(this Context ctx, string param_name)
{
return await ctx.Parameters.ResolveParameter(
ctx, param_name,
param => (param as Parameter.ProxySwitchAction)?.action
);
}
public static async Task<bool?> ParamResolveToggle(this Context ctx, string param_name) public static async Task<bool?> ParamResolveToggle(this Context ctx, string param_name)
{ {
return await ctx.Parameters.ResolveParameter( return await ctx.Parameters.ResolveParameter(

View file

@ -26,6 +26,7 @@ public abstract record Parameter()
public record Opaque(string value): Parameter; public record Opaque(string value): Parameter;
public record Number(int value): Parameter; public record Number(int value): Parameter;
public record Avatar(ParsedImage avatar): Parameter; public record Avatar(ParsedImage avatar): Parameter;
public record ProxySwitchAction(SystemConfig.ProxySwitchAction action): Parameter;
} }
public class Parameters public class Parameters
@ -122,6 +123,19 @@ public class Parameters
return new Parameter.SystemPrivacyTarget(systemPrivacy); return new Parameter.SystemPrivacyTarget(systemPrivacy);
case uniffi.commands.Parameter.PrivacyLevel privacyLevel: case uniffi.commands.Parameter.PrivacyLevel privacyLevel:
return new Parameter.PrivacyLevel(privacyLevel.level == "public" ? PrivacyLevel.Public : privacyLevel.level == "private" ? PrivacyLevel.Private : throw new PKError($"Invalid privacy level {privacyLevel.level}")); return new Parameter.PrivacyLevel(privacyLevel.level == "public" ? PrivacyLevel.Public : privacyLevel.level == "private" ? PrivacyLevel.Private : throw new PKError($"Invalid privacy level {privacyLevel.level}"));
case uniffi.commands.Parameter.ProxySwitchAction(var action):
SystemConfig.ProxySwitchAction newVal;
if (action.Equals("off", StringComparison.InvariantCultureIgnoreCase))
newVal = SystemConfig.ProxySwitchAction.Off;
else if (action.Equals("new", StringComparison.InvariantCultureIgnoreCase) || action.Equals("n", StringComparison.InvariantCultureIgnoreCase) || action.Equals("on", StringComparison.InvariantCultureIgnoreCase))
newVal = SystemConfig.ProxySwitchAction.New;
else if (action.Equals("add", StringComparison.InvariantCultureIgnoreCase) || action.Equals("a", StringComparison.InvariantCultureIgnoreCase))
newVal = SystemConfig.ProxySwitchAction.Add;
else
throw new PKError("You must pass either \"new\", \"add\", or \"off\" to this command.");
return new Parameter.ProxySwitchAction(newVal);
case uniffi.commands.Parameter.Toggle toggle: case uniffi.commands.Parameter.Toggle toggle:
return new Parameter.Toggle(toggle.toggle); return new Parameter.Toggle(toggle.toggle);
case uniffi.commands.Parameter.OpaqueString opaque: case uniffi.commands.Parameter.OpaqueString opaque:

View file

@ -273,25 +273,26 @@ public class Config
await ctx.Reply($"{Emojis.Success} Latch timeout set to {newTimeout.ToTimeSpan().Humanize(4)}."); await ctx.Reply($"{Emojis.Success} Latch timeout set to {newTimeout.ToTimeSpan().Humanize(4)}.");
} }
public async Task SystemTimezone(Context ctx) public async Task ViewSystemTimezone(Context ctx)
{ {
if (ctx.System == null) throw Errors.NoSystemError(ctx.DefaultPrefix); if (ctx.System == null) throw Errors.NoSystemError(ctx.DefaultPrefix);
if (ctx.MatchClear()) await ctx.Reply(
{ $"Your current system time zone is set to **{ctx.Config.UiTz}**. It is currently **{SystemClock.Instance.GetCurrentInstant().FormatZoned(ctx.Config.Zone)}** in that time zone. To change your system time zone, type `{ctx.DefaultPrefix}config tz <zone>`.");
await ctx.Repository.UpdateSystemConfig(ctx.System.Id, new() { UiTz = "UTC" }); }
await ctx.Reply($"{Emojis.Success} System time zone cleared (set to UTC)."); public async Task ResetSystemTimezone(Context ctx)
return; {
} if (ctx.System == null) throw Errors.NoSystemError(ctx.DefaultPrefix);
var zoneStr = ctx.RemainderOrNull(); await ctx.Repository.UpdateSystemConfig(ctx.System.Id, new() { UiTz = "UTC" });
if (zoneStr == null)
{ await ctx.Reply($"{Emojis.Success} System time zone cleared (set to UTC).");
await ctx.Reply( }
$"Your current system time zone is set to **{ctx.Config.UiTz}**. It is currently **{SystemClock.Instance.GetCurrentInstant().FormatZoned(ctx.Config.Zone)}** in that time zone. To change your system time zone, type `{ctx.DefaultPrefix}config tz <zone>`.");
return; public async Task EditSystemTimezone(Context ctx, string zoneStr)
} {
if (ctx.System == null) throw Errors.NoSystemError(ctx.DefaultPrefix);
var zone = await FindTimeZone(ctx, zoneStr); var zone = await FindTimeZone(ctx, zoneStr);
if (zone == null) throw Errors.InvalidTimeZone(zoneStr); if (zone == null) throw Errors.InvalidTimeZone(zoneStr);
@ -365,27 +366,24 @@ public class Config
}); });
} }
public async Task SystemPing(Context ctx) public async Task ViewSystemPing(Context ctx)
{ {
// note: this is here because this is also used in `pk;system ping`, which does not CheckSystem // note: this is here because this is also used in `pk;system ping`, which does not CheckSystem
ctx.CheckSystem(); ctx.CheckSystem();
// todo: move all the other config settings to this format await ctx.Reply($"Reaction pings are currently **{EnabledDisabled(ctx.Config.PingsEnabled)}** for your system. " +
$"To {EnabledDisabled(!ctx.Config.PingsEnabled)[..^1]} reaction pings, type `{ctx.DefaultPrefix}config ping {EnabledDisabled(!ctx.Config.PingsEnabled)[..^1]}`.");
}
String Response(bool isError, bool val) public async Task EditSystemPing(Context ctx, bool value)
=> $"Reaction pings are {(isError ? "already" : "currently")} **{EnabledDisabled(val)}** for your system. " {
+ $"To {EnabledDisabled(!val)[..^1]} reaction pings, type `{ctx.DefaultPrefix}config ping {EnabledDisabled(!val)[..^1]}`."; ctx.CheckSystem();
if (!ctx.HasNext())
{
await ctx.Reply(Response(false, ctx.Config.PingsEnabled));
return;
}
var value = ctx.MatchToggle(true);
if (ctx.Config.PingsEnabled == value) if (ctx.Config.PingsEnabled == value)
await ctx.Reply(Response(true, ctx.Config.PingsEnabled)); {
await ctx.Reply($"Reaction pings are already **{EnabledDisabled(ctx.Config.PingsEnabled)}** for your system. " +
$"To {EnabledDisabled(!value)[..^1]} reaction pings, type `{ctx.DefaultPrefix}config ping {EnabledDisabled(!value)[..^1]}`.");
}
else else
{ {
await ctx.Repository.UpdateSystemConfig(ctx.System.Id, new() { PingsEnabled = value }); await ctx.Repository.UpdateSystemConfig(ctx.System.Id, new() { PingsEnabled = value });
@ -393,230 +391,182 @@ public class Config
} }
} }
public async Task MemberDefaultPrivacy(Context ctx) public async Task ViewMemberDefaultPrivacy(Context ctx)
{ {
if (!ctx.HasNext()) if (ctx.Config.MemberDefaultPrivate)
{ await ctx.Reply($"Newly created members will currently have their privacy settings set to private. To change this, type `{ctx.DefaultPrefix}config private member off`");
if (ctx.Config.MemberDefaultPrivate) { await ctx.Reply($"Newly created members will currently have their privacy settings set to private. To change this, type `{ctx.DefaultPrefix}config private member off`"); }
else { await ctx.Reply($"Newly created members will currently have their privacy settings set to public. To automatically set new members' privacy settings to private, type `{ctx.DefaultPrefix}config private member on`"); }
}
else else
{ await ctx.Reply($"Newly created members will currently have their privacy settings set to public. To automatically set new members' privacy settings to private, type `{ctx.DefaultPrefix}config private member on`");
if (ctx.MatchToggle(false))
{
await ctx.Repository.UpdateSystemConfig(ctx.System.Id, new() { MemberDefaultPrivate = true });
await ctx.Reply("Newly created members will now have their privacy settings set to private.");
}
else
{
await ctx.Repository.UpdateSystemConfig(ctx.System.Id, new() { MemberDefaultPrivate = false });
await ctx.Reply("Newly created members will now have their privacy settings set to public.");
}
}
} }
public async Task GroupDefaultPrivacy(Context ctx) public async Task EditMemberDefaultPrivacy(Context ctx, bool value)
{ {
if (!ctx.HasNext()) await ctx.Repository.UpdateSystemConfig(ctx.System.Id, new() { MemberDefaultPrivate = value });
{
if (ctx.Config.GroupDefaultPrivate) { await ctx.Reply($"Newly created groups will currently have their privacy settings set to private. To change this, type `{ctx.DefaultPrefix}config private group off`"); } if (value)
else { await ctx.Reply($"Newly created groups will currently have their privacy settings set to public. To automatically set new groups' privacy settings to private, type `{ctx.DefaultPrefix}config private group on`"); } await ctx.Reply("Newly created members will now have their privacy settings set to private.");
}
else else
{ await ctx.Reply("Newly created members will now have their privacy settings set to public.");
if (ctx.MatchToggle(false))
{
await ctx.Repository.UpdateSystemConfig(ctx.System.Id, new() { GroupDefaultPrivate = true });
await ctx.Reply("Newly created groups will now have their privacy settings set to private.");
}
else
{
await ctx.Repository.UpdateSystemConfig(ctx.System.Id, new() { GroupDefaultPrivate = false });
await ctx.Reply("Newly created groups will now have their privacy settings set to public.");
}
}
} }
public async Task ShowPrivateInfo(Context ctx) public async Task ViewGroupDefaultPrivacy(Context ctx)
{ {
if (!ctx.HasNext()) if (ctx.Config.GroupDefaultPrivate)
{ await ctx.Reply($"Newly created groups will currently have their privacy settings set to private. To change this, type `{ctx.DefaultPrefix}config private group off`");
if (ctx.Config.ShowPrivateInfo) await ctx.Reply("Private information is currently **shown** when looking up your own info. Use the `-public` flag to hide it."); else
else await ctx.Reply("Private information is currently **hidden** when looking up your own info. Use the `-private` flag to show it."); await ctx.Reply($"Newly created groups will currently have their privacy settings set to public. To automatically set new groups' privacy settings to private, type `{ctx.DefaultPrefix}config private group on`");
return; }
}
if (ctx.MatchToggle(true)) public async Task EditGroupDefaultPrivacy(Context ctx, bool value)
{ {
await ctx.Repository.UpdateSystemConfig(ctx.System.Id, new() { ShowPrivateInfo = true }); await ctx.Repository.UpdateSystemConfig(ctx.System.Id, new() { GroupDefaultPrivate = value });
if (value)
await ctx.Reply("Newly created groups will now have their privacy settings set to private.");
else
await ctx.Reply("Newly created groups will now have their privacy settings set to public.");
}
public async Task ViewShowPrivateInfo(Context ctx)
{
if (ctx.Config.ShowPrivateInfo)
await ctx.Reply("Private information is currently **shown** when looking up your own info. Use the `-public` flag to hide it.");
else
await ctx.Reply("Private information is currently **hidden** when looking up your own info. Use the `-private` flag to show it.");
}
public async Task EditShowPrivateInfo(Context ctx, bool value)
{
await ctx.Repository.UpdateSystemConfig(ctx.System.Id, new() { ShowPrivateInfo = value });
if (value)
await ctx.Reply("Private information will now be **shown** when looking up your own info. Use the `-public` flag to hide it."); await ctx.Reply("Private information will now be **shown** when looking up your own info. Use the `-public` flag to hide it.");
}
else else
{
await ctx.Repository.UpdateSystemConfig(ctx.System.Id, new() { ShowPrivateInfo = false });
await ctx.Reply("Private information will now be **hidden** when looking up your own info. Use the `-private` flag to show it."); await ctx.Reply("Private information will now be **hidden** when looking up your own info. Use the `-private` flag to show it.");
}
} }
public async Task CaseSensitiveProxyTags(Context ctx) public async Task ViewCaseSensitiveProxyTags(Context ctx)
{ {
if (!ctx.HasNext()) if (ctx.Config.CaseSensitiveProxyTags)
{ await ctx.Reply("Proxy tags are currently case **sensitive**.");
if (ctx.Config.CaseSensitiveProxyTags) { await ctx.Reply("Proxy tags are currently case **sensitive**."); } else
else { await ctx.Reply("Proxy tags are currently case **insensitive**."); } await ctx.Reply("Proxy tags are currently case **insensitive**.");
return; }
}
if (ctx.MatchToggle(true)) public async Task EditCaseSensitiveProxyTags(Context ctx, bool value)
{ {
await ctx.Repository.UpdateSystemConfig(ctx.System.Id, new() { CaseSensitiveProxyTags = true }); await ctx.Repository.UpdateSystemConfig(ctx.System.Id, new() { CaseSensitiveProxyTags = value });
if (value)
await ctx.Reply("Proxy tags are now case sensitive."); await ctx.Reply("Proxy tags are now case sensitive.");
}
else else
{
await ctx.Repository.UpdateSystemConfig(ctx.System.Id, new() { CaseSensitiveProxyTags = false });
await ctx.Reply("Proxy tags are now case insensitive."); await ctx.Reply("Proxy tags are now case insensitive.");
}
} }
public async Task ProxyErrorMessageEnabled(Context ctx) public async Task ViewProxyErrorMessageEnabled(Context ctx)
{ {
if (!ctx.HasNext()) if (ctx.Config.ProxyErrorMessageEnabled)
{ await ctx.Reply("Proxy error messages are currently **enabled**.");
if (ctx.Config.ProxyErrorMessageEnabled) { await ctx.Reply("Proxy error messages are currently **enabled**."); }
else { await ctx.Reply("Proxy error messages are currently **disabled**. Messages that fail to proxy (due to message or attachment size) will not throw an error message."); }
return;
}
if (ctx.MatchToggle(true))
{
await ctx.Repository.UpdateSystemConfig(ctx.System.Id, new() { ProxyErrorMessageEnabled = true });
await ctx.Reply("Proxy error messages are now enabled.");
}
else else
{ await ctx.Reply("Proxy error messages are currently **disabled**. Messages that fail to proxy (due to message or attachment size) will not throw an error message.");
await ctx.Repository.UpdateSystemConfig(ctx.System.Id, new() { ProxyErrorMessageEnabled = false }); }
public async Task EditProxyErrorMessageEnabled(Context ctx, bool value)
{
await ctx.Repository.UpdateSystemConfig(ctx.System.Id, new() { ProxyErrorMessageEnabled = value });
if (value)
await ctx.Reply("Proxy error messages are now enabled.");
else
await ctx.Reply("Proxy error messages are now disabled. Messages that fail to proxy (due to message or attachment size) will not throw an error message."); await ctx.Reply("Proxy error messages are now disabled. Messages that fail to proxy (due to message or attachment size) will not throw an error message.");
}
} }
public async Task HidDisplaySplit(Context ctx) public async Task ViewHidDisplaySplit(Context ctx)
{ {
if (!ctx.HasNext()) await ctx.Reply($"Splitting of 6-character IDs with a hyphen is currently **{EnabledDisabled(ctx.Config.HidDisplaySplit)}**.");
{
var msg = $"Splitting of 6-character IDs with a hyphen is currently **{EnabledDisabled(ctx.Config.HidDisplaySplit)}**.";
await ctx.Reply(msg);
return;
}
var newVal = ctx.MatchToggle(false);
await ctx.Repository.UpdateSystemConfig(ctx.System.Id, new() { HidDisplaySplit = newVal });
await ctx.Reply($"Splitting of 6-character IDs with a hyphen is now {EnabledDisabled(newVal)}.");
} }
public async Task HidDisplayCaps(Context ctx) public async Task EditHidDisplaySplit(Context ctx, bool value)
{ {
if (!ctx.HasNext()) await ctx.Repository.UpdateSystemConfig(ctx.System.Id, new() { HidDisplaySplit = value });
{ await ctx.Reply($"Splitting of 6-character IDs with a hyphen is now {EnabledDisabled(value)}.");
var msg = $"Displaying IDs as capital letters is currently **{EnabledDisabled(ctx.Config.HidDisplayCaps)}**.";
await ctx.Reply(msg);
return;
}
var newVal = ctx.MatchToggle(false);
await ctx.Repository.UpdateSystemConfig(ctx.System.Id, new() { HidDisplayCaps = newVal });
await ctx.Reply($"Displaying IDs as capital letters is now {EnabledDisabled(newVal)}.");
} }
public async Task HidListPadding(Context ctx) public async Task ViewHidDisplayCaps(Context ctx)
{ {
if (!ctx.HasNext()) await ctx.Reply($"Displaying IDs as capital letters is currently **{EnabledDisabled(ctx.Config.HidDisplayCaps)}**.");
{ }
string message;
switch (ctx.Config.HidListPadding)
{
case SystemConfig.HidPadFormat.None: message = "Padding 5-character IDs in lists is currently disabled."; break;
case SystemConfig.HidPadFormat.Left: message = "5-character IDs displayed in lists will have a padding space added to the beginning."; break;
case SystemConfig.HidPadFormat.Right: message = "5-character IDs displayed in lists will have a padding space added to the end."; break;
default: throw new Exception("unreachable");
}
await ctx.Reply(message);
return;
}
public async Task EditHidDisplayCaps(Context ctx, bool value)
{
await ctx.Repository.UpdateSystemConfig(ctx.System.Id, new() { HidDisplayCaps = value });
await ctx.Reply($"Displaying IDs as capital letters is now {EnabledDisabled(value)}.");
}
public async Task ViewHidListPadding(Context ctx)
{
string message = ctx.Config.HidListPadding switch
{
SystemConfig.HidPadFormat.None => "Padding 5-character IDs in lists is currently disabled.",
SystemConfig.HidPadFormat.Left => "5-character IDs displayed in lists will have a padding space added to the beginning.",
SystemConfig.HidPadFormat.Right => "5-character IDs displayed in lists will have a padding space added to the end.",
_ => throw new Exception("unreachable")
};
await ctx.Reply(message);
}
public async Task EditHidListPadding(Context ctx, string padding)
{
var badInputError = "Valid padding settings are `left`, `right`, or `off`."; var badInputError = "Valid padding settings are `left`, `right`, or `off`.";
var toggleOff = ctx.MatchToggleOrNull(false); if (padding.Equals("off", StringComparison.InvariantCultureIgnoreCase))
switch (toggleOff)
{ {
case true: throw new PKError(badInputError); await ctx.Repository.UpdateSystemConfig(ctx.System.Id, new() { HidListPadding = SystemConfig.HidPadFormat.None });
case false: await ctx.Reply("Padding 5-character IDs in lists has been disabled.");
{
await ctx.Repository.UpdateSystemConfig(ctx.System.Id, new() { HidListPadding = SystemConfig.HidPadFormat.None });
await ctx.Reply("Padding 5-character IDs in lists has been disabled.");
return;
}
} }
else if (padding.Equals("left", StringComparison.InvariantCultureIgnoreCase) || padding.Equals("l", StringComparison.InvariantCultureIgnoreCase))
if (ctx.Match("left", "l"))
{ {
await ctx.Repository.UpdateSystemConfig(ctx.System.Id, new() { HidListPadding = SystemConfig.HidPadFormat.Left }); await ctx.Repository.UpdateSystemConfig(ctx.System.Id, new() { HidListPadding = SystemConfig.HidPadFormat.Left });
await ctx.Reply("5-character IDs displayed in lists will now have a padding space added to the beginning."); await ctx.Reply("5-character IDs displayed in lists will now have a padding space added to the beginning.");
} }
else if (ctx.Match("right", "r")) else if (padding.Equals("right", StringComparison.InvariantCultureIgnoreCase) || padding.Equals("r", StringComparison.InvariantCultureIgnoreCase))
{ {
await ctx.Repository.UpdateSystemConfig(ctx.System.Id, new() { HidListPadding = SystemConfig.HidPadFormat.Right }); await ctx.Repository.UpdateSystemConfig(ctx.System.Id, new() { HidListPadding = SystemConfig.HidPadFormat.Right });
await ctx.Reply("5-character IDs displayed in lists will now have a padding space added to the end."); await ctx.Reply("5-character IDs displayed in lists will now have a padding space added to the end.");
} }
else throw new PKError(badInputError); else
{
throw new PKError(badInputError);
}
} }
public async Task CardShowColorHex(Context ctx) public async Task ViewCardShowColorHex(Context ctx)
{ {
if (!ctx.HasNext()) await ctx.Reply($"Showing color codes on system/member/group cards is currently **{EnabledDisabled(ctx.Config.CardShowColorHex)}**.");
{
var msg = $"Showing color codes on system/member/group cards is currently **{EnabledDisabled(ctx.Config.CardShowColorHex)}**.";
await ctx.Reply(msg);
return;
}
var newVal = ctx.MatchToggle(false);
await ctx.Repository.UpdateSystemConfig(ctx.System.Id, new() { CardShowColorHex = newVal });
await ctx.Reply($"Showing color codes on system/member/group cards is now {EnabledDisabled(newVal)}.");
} }
public async Task ProxySwitch(Context ctx) public async Task EditCardShowColorHex(Context ctx, bool value)
{ {
if (!ctx.HasNext()) await ctx.Repository.UpdateSystemConfig(ctx.System.Id, new() { CardShowColorHex = value });
await ctx.Reply($"Showing color codes on system/member/group cards is now {EnabledDisabled(value)}.");
}
public async Task ViewProxySwitch(Context ctx)
{
string msg = ctx.Config.ProxySwitch switch
{ {
string msg = ctx.Config.ProxySwitch switch SystemConfig.ProxySwitchAction.Off => "Currently, when you proxy as a member, no switches are logged or changed.",
{ SystemConfig.ProxySwitchAction.New => "When you proxy as a member, currently it makes a new switch.",
SystemConfig.ProxySwitchAction.Off => "Currently, when you proxy as a member, no switches are logged or changed.", SystemConfig.ProxySwitchAction.Add => "When you proxy as a member, currently it adds them to the current switch.",
SystemConfig.ProxySwitchAction.New => "When you proxy as a member, currently it makes a new switch.", _ => throw new Exception("unreachable"),
SystemConfig.ProxySwitchAction.Add => "When you proxy as a member, currently it adds them to the current switch.", };
_ => throw new Exception("unreachable"), await ctx.Reply(msg);
}; }
await ctx.Reply(msg);
return;
}
// toggle = false means off, toggle = true means new, otherwise if they said add that means add or if they said new they mean new. If none of those, error public async Task EditProxySwitch(Context ctx, SystemConfig.ProxySwitchAction action)
var toggle = ctx.MatchToggleOrNull(false); {
var newVal = toggle == false ? SystemConfig.ProxySwitchAction.Off : toggle == true ? SystemConfig.ProxySwitchAction.New : ctx.Match("add", "a") ? SystemConfig.ProxySwitchAction.Add : ctx.Match("new", "n") ? SystemConfig.ProxySwitchAction.New : throw new PKError("You must pass either \"new\", \"add\", or \"off\" to this command."); await ctx.Repository.UpdateSystemConfig(ctx.System.Id, new() { ProxySwitch = action });
switch (action)
await ctx.Repository.UpdateSystemConfig(ctx.System.Id, new() { ProxySwitch = newVal });
switch (newVal)
{ {
case SystemConfig.ProxySwitchAction.Off: await ctx.Reply("Now when you proxy as a member, no switches are logged or changed."); break; case SystemConfig.ProxySwitchAction.Off: await ctx.Reply("Now when you proxy as a member, no switches are logged or changed."); break;
case SystemConfig.ProxySwitchAction.New: await ctx.Reply("When you proxy as a member, it now makes a new switch."); break; case SystemConfig.ProxySwitchAction.New: await ctx.Reply("When you proxy as a member, it now makes a new switch."); break;
@ -625,65 +575,61 @@ public class Config
} }
} }
public async Task NameFormat(Context ctx) public async Task ViewNameFormat(Context ctx)
{ {
var clearFlag = ctx.MatchClear(); await ctx.Reply($"Member names are currently formatted as `{ctx.Config.NameFormat ?? ProxyMember.DefaultFormat}`");
if (!ctx.HasNext() && !clearFlag) }
{
await ctx.Reply($"Member names are currently formatted as `{ctx.Config.NameFormat ?? ProxyMember.DefaultFormat}`");
return;
}
string formatString; public async Task ResetNameFormat(Context ctx)
if (clearFlag) {
formatString = ProxyMember.DefaultFormat; await ctx.Repository.UpdateSystemConfig(ctx.System.Id, new() { NameFormat = ProxyMember.DefaultFormat });
else await ctx.Reply($"Member names are now formatted as `{ProxyMember.DefaultFormat}`");
formatString = ctx.RemainderOrNull(); }
public async Task EditNameFormat(Context ctx, string formatString)
{
await ctx.Repository.UpdateSystemConfig(ctx.System.Id, new() { NameFormat = formatString }); await ctx.Repository.UpdateSystemConfig(ctx.System.Id, new() { NameFormat = formatString });
await ctx.Reply($"Member names are now formatted as `{formatString}`"); await ctx.Reply($"Member names are now formatted as `{formatString}`");
} }
public async Task ServerNameFormat(Context ctx) public async Task ViewServerNameFormat(Context ctx, ReplyFormat format)
{ {
ctx.CheckGuildContext(); ctx.CheckGuildContext();
var clearFlag = ctx.MatchClear();
var format = ctx.MatchFormat();
// if there's nothing next or what's next is raw/plaintext and we're not clearing, it's a query var guildCfg = await ctx.Repository.GetSystemGuild(ctx.Guild.Id, ctx.System.Id);
if ((!ctx.HasNext() || format != ReplyFormat.Standard) && !clearFlag) if (guildCfg.NameFormat == null)
{ await ctx.Reply("You do not have a specific name format set for this server and member names are formatted with your global name format.");
var guildCfg = await ctx.Repository.GetSystemGuild(ctx.Guild.Id, ctx.System.Id);
if (guildCfg.NameFormat == null)
await ctx.Reply("You do not have a specific name format set for this server and member names are formatted with your global name format.");
else
switch (format)
{
case ReplyFormat.Raw:
await ctx.Reply($"`{guildCfg.NameFormat}`");
break;
case ReplyFormat.Plaintext:
var eb = new EmbedBuilder()
.Description($"Showing guild Name Format for system {ctx.System.DisplayHid(ctx.Config)}");
await ctx.Reply(guildCfg.NameFormat, eb.Build());
break;
default:
await ctx.Reply($"Your member names in this server are currently formatted as `{guildCfg.NameFormat}`");
break;
}
return;
}
string? formatString = null;
if (!clearFlag)
{
formatString = ctx.RemainderOrNull();
}
await ctx.Repository.UpdateSystemGuild(ctx.System.Id, ctx.Guild.Id, new() { NameFormat = formatString });
if (formatString == null)
await ctx.Reply($"Member names are now formatted with your global name format in this server.");
else else
await ctx.Reply($"Member names are now formatted as `{formatString}` in this server."); switch (format)
{
case ReplyFormat.Raw:
await ctx.Reply($"`{guildCfg.NameFormat}`");
break;
case ReplyFormat.Plaintext:
var eb = new EmbedBuilder()
.Description($"Showing guild Name Format for system {ctx.System.DisplayHid(ctx.Config)}");
await ctx.Reply(guildCfg.NameFormat, eb.Build());
break;
default:
await ctx.Reply($"Your member names in this server are currently formatted as `{guildCfg.NameFormat}`");
break;
}
}
public async Task ResetServerNameFormat(Context ctx)
{
ctx.CheckGuildContext();
await ctx.Repository.UpdateSystemGuild(ctx.System.Id, ctx.Guild.Id, new() { NameFormat = null });
await ctx.Reply($"Member names are now formatted with your global name format in this server.");
}
public async Task EditServerNameFormat(Context ctx, string formatString)
{
ctx.CheckGuildContext();
await ctx.Repository.UpdateSystemGuild(ctx.System.Id, ctx.Guild.Id, new() { NameFormat = formatString });
await ctx.Reply($"Member names are now formatted as `{formatString}` in this server.");
} }
public Task LimitUpdate(Context ctx) public Task LimitUpdate(Context ctx)

View file

@ -1,4 +1,5 @@
using Myriad.Extensions; using Myriad.Extensions;
using Myriad.Types;
using PluralKit.Core; using PluralKit.Core;
@ -6,12 +7,10 @@ namespace PluralKit.Bot;
public class SystemLink public class SystemLink
{ {
public async Task LinkSystem(Context ctx) public async Task LinkSystem(Context ctx, User account)
{ {
ctx.CheckSystem(); ctx.CheckSystem();
var account = await ctx.MatchUser() ??
throw new PKSyntaxError("You must pass an account to link with (either ID or @mention).");
var accountIds = await ctx.Repository.GetSystemAccounts(ctx.System.Id); var accountIds = await ctx.Repository.GetSystemAccounts(ctx.System.Id);
if (accountIds.Contains(account.Id)) if (accountIds.Contains(account.Id))
throw Errors.AccountAlreadyLinked; throw Errors.AccountAlreadyLinked;

View file

@ -3,13 +3,85 @@ use command_parser::parameter;
use super::*; use super::*;
pub fn cmds() -> impl Iterator<Item = Command> { pub fn cmds() -> impl Iterator<Item = Command> {
let cfg = ("config", ["cfg"]); let cfg = ("config", ["cfg", "configure"]);
let ap = tokens!(cfg, ("autoproxy", ["ap"])); let ap = tokens!(cfg, ("autoproxy", ["ap"]));
let ap_account = tokens!(ap, ("account", ["ac"])); let ap_account = tokens!(ap, ("account", ["ac"]));
let ap_timeout = tokens!(ap, ("timeout", ["tm"])); let ap_timeout = tokens!(ap, ("timeout", ["tm"]));
let timezone = tokens!(cfg, ("timezone", ["zone", "tz"]));
let ping = tokens!(cfg, ("ping", ["ping"]));
let priv_ = ("private", ["priv"]);
let member_privacy = tokens!(cfg, priv_, ("member", ["mem"]));
let member_privacy_short = tokens!(cfg, ("mp", ["mp"]));
let group_privacy = tokens!(cfg, priv_, ("group", ["grp"]));
let group_privacy_short = tokens!(cfg, ("gp", ["gp"]));
let show = ("show", ["show"]);
let show_private = tokens!(cfg, show, priv_);
let show_private_short = tokens!(cfg, ("sp", ["sp"]));
let proxy = ("proxy", ["px"]);
let proxy_case = tokens!(cfg, proxy, ("case", ["caps", "capitalize", "capitalise"]));
let proxy_error = tokens!(cfg, proxy, ("error", ["errors"]));
let proxy_error_short = tokens!(cfg, ("pe", ["pe"]));
let id = ("id", ["ids"]);
let split_id = tokens!(cfg, ("split", ["split"]), id);
let split_id_short = tokens!(cfg, ("sid", ["sid", "sids"]));
let cap_id = tokens!(cfg, ("cap", ["caps", "capitalize", "capitalise"]), id);
let cap_id_short = tokens!(cfg, ("capid", ["capid", "capids"]));
let pad = ("pad", ["padding"]);
let pad_id = tokens!(cfg, pad, id);
let id_pad = tokens!(cfg, id, pad);
let id_pad_short = tokens!(cfg, ("idpad", ["idpad", "padid", "padids"]));
let show_color = tokens!(cfg, show, ("color", ["colour", "colors", "colours"]));
let show_color_short = tokens!(
cfg,
(
"showcolor",
[
"showcolour",
"showcolors",
"showcolours",
"colorcode",
"colorhex"
]
)
);
let proxy_switch = tokens!(cfg, ("proxy", ["proxy"]), ("switch", ["switch"]));
let proxy_switch_short = tokens!(cfg, ("proxyswitch", ["proxyswitch", "ps"]));
let format = ("format", ["format"]);
let name_format = tokens!(cfg, ("name", ["name"]), format);
let name_format_short = tokens!(cfg, ("nameformat", ["nameformat", "nf"]));
let server = ("server", ["server"]);
let server_name_format = tokens!(cfg, server, ("name", ["name"]), format);
let server_format = tokens!(
cfg,
("server", ["server", "servername"]),
("format", ["format", "nameformat", "nf"])
);
let server_format_short = tokens!(
cfg,
(
"snf",
["snf", "servernf", "servernameformat", "snameformat"]
)
);
let limit_ = ("limit", ["limit", "lim"]);
let member_limit = tokens!(cfg, ("member", ["mem"]), limit_);
let group_limit = tokens!(cfg, ("group", ["grp"]), limit_);
let limit = tokens!(cfg, limit_);
[ [
command!(cfg => "cfg_show").help("Shows the current configuration"),
command!(ap_account => "cfg_ap_account_show") command!(ap_account => "cfg_ap_account_show")
.help("Shows autoproxy status for the account"), .help("Shows autoproxy status for the account"),
command!(ap_account, Toggle => "cfg_ap_account_update") command!(ap_account, Toggle => "cfg_ap_account_update")
@ -20,6 +92,115 @@ pub fn cmds() -> impl Iterator<Item = Command> {
.help("Disables the autoproxy timeout"), .help("Disables the autoproxy timeout"),
command!(ap_timeout, ("timeout", OpaqueString) => "cfg_ap_timeout_update") command!(ap_timeout, ("timeout", OpaqueString) => "cfg_ap_timeout_update")
.help("Sets the autoproxy timeout"), .help("Sets the autoproxy timeout"),
command!(timezone => "cfg_timezone_show").help("Shows the system timezone"),
command!(timezone, RESET => "cfg_timezone_reset").help("Resets the system timezone"),
command!(timezone, ("timezone", OpaqueString) => "cfg_timezone_update")
.help("Sets the system timezone"),
command!(ping => "cfg_ping_show").help("Shows the ping setting"),
command!(ping, Toggle => "cfg_ping_update").help("Updates the ping setting"),
command!(member_privacy => "cfg_member_privacy_show")
.help("Shows the default privacy for new members"),
command!(member_privacy, Toggle => "cfg_member_privacy_update")
.help("Sets the default privacy for new members"),
command!(member_privacy_short => "cfg_member_privacy_show")
.help("Shows the default privacy for new members"),
command!(member_privacy_short, Toggle => "cfg_member_privacy_update")
.help("Sets the default privacy for new members"),
command!(group_privacy => "cfg_group_privacy_show")
.help("Shows the default privacy for new groups"),
command!(group_privacy, Toggle => "cfg_group_privacy_update")
.help("Sets the default privacy for new groups"),
command!(group_privacy_short => "cfg_group_privacy_show")
.help("Shows the default privacy for new groups"),
command!(group_privacy_short, Toggle => "cfg_group_privacy_update")
.help("Sets the default privacy for new groups"),
command!(show_private => "cfg_show_private_info_show")
.help("Shows whether private info is shown"),
command!(show_private, Toggle => "cfg_show_private_info_update")
.help("Toggles showing private info"),
command!(show_private_short => "cfg_show_private_info_show")
.help("Shows whether private info is shown"),
command!(show_private_short, Toggle => "cfg_show_private_info_update")
.help("Toggles showing private info"),
command!(proxy_case => "cfg_case_sensitive_proxy_tags_show")
.help("Shows whether proxy tags are case-sensitive"),
command!(proxy_case, Toggle => "cfg_case_sensitive_proxy_tags_update")
.help("Toggles case sensitivity for proxy tags"),
command!(proxy_error => "cfg_proxy_error_message_show")
.help("Shows whether proxy error messages are enabled"),
command!(proxy_error, Toggle => "cfg_proxy_error_message_update")
.help("Toggles proxy error messages"),
command!(proxy_error_short => "cfg_proxy_error_message_show")
.help("Shows whether proxy error messages are enabled"),
command!(proxy_error_short, Toggle => "cfg_proxy_error_message_update")
.help("Toggles proxy error messages"),
command!(split_id => "cfg_hid_split_show").help("Shows whether IDs are split in lists"),
command!(split_id, Toggle => "cfg_hid_split_update").help("Toggles splitting IDs in lists"),
command!(split_id_short => "cfg_hid_split_show")
.help("Shows whether IDs are split in lists"),
command!(split_id_short, Toggle => "cfg_hid_split_update")
.help("Toggles splitting IDs in lists"),
command!(cap_id => "cfg_hid_caps_show").help("Shows whether IDs are capitalized in lists"),
command!(cap_id, Toggle => "cfg_hid_caps_update")
.help("Toggles capitalization of IDs in lists"),
command!(cap_id_short => "cfg_hid_caps_show")
.help("Shows whether IDs are capitalized in lists"),
command!(cap_id_short, Toggle => "cfg_hid_caps_update")
.help("Toggles capitalization of IDs in lists"),
command!(pad_id => "cfg_hid_padding_show").help("Shows the ID padding for lists"),
command!(pad_id, ("padding", OpaqueString) => "cfg_hid_padding_update")
.help("Sets the ID padding for lists"),
command!(id_pad => "cfg_hid_padding_show").help("Shows the ID padding for lists"),
command!(id_pad, ("padding", OpaqueString) => "cfg_hid_padding_update")
.help("Sets the ID padding for lists"),
command!(id_pad_short => "cfg_hid_padding_show").help("Shows the ID padding for lists"),
command!(id_pad_short, ("padding", OpaqueString) => "cfg_hid_padding_update")
.help("Sets the ID padding for lists"),
command!(show_color => "cfg_card_show_color_hex_show")
.help("Shows whether color hex codes are shown on cards"),
command!(show_color, Toggle => "cfg_card_show_color_hex_update")
.help("Toggles showing color hex codes on cards"),
command!(show_color_short => "cfg_card_show_color_hex_show")
.help("Shows whether color hex codes are shown on cards"),
command!(show_color_short, Toggle => "cfg_card_show_color_hex_update")
.help("Toggles showing color hex codes on cards"),
command!(proxy_switch => "cfg_proxy_switch_show").help("Shows the proxy switch behavior"),
command!(proxy_switch, ProxySwitchAction => "cfg_proxy_switch_update")
.help("Sets the proxy switch behavior"),
command!(proxy_switch_short => "cfg_proxy_switch_show")
.help("Shows the proxy switch behavior"),
command!(proxy_switch_short, ProxySwitchAction => "cfg_proxy_switch_update")
.help("Sets the proxy switch behavior"),
command!(name_format => "cfg_name_format_show").help("Shows the name format"),
command!(name_format, RESET => "cfg_name_format_reset").help("Resets the name format"),
command!(name_format, ("format", OpaqueString) => "cfg_name_format_update")
.help("Sets the name format"),
command!(name_format_short => "cfg_name_format_show").help("Shows the name format"),
command!(name_format_short, RESET => "cfg_name_format_reset")
.help("Resets the name format"),
command!(name_format_short, ("format", OpaqueString) => "cfg_name_format_update")
.help("Sets the name format"),
command!(server_name_format => "cfg_server_name_format_show")
.help("Shows the server name format"),
command!(server_name_format, RESET => "cfg_server_name_format_reset")
.help("Resets the server name format"),
command!(server_name_format, ("format", OpaqueString) => "cfg_server_name_format_update")
.help("Sets the server name format"),
command!(server_format => "cfg_server_name_format_show")
.help("Shows the server name format"),
command!(server_format, RESET => "cfg_server_name_format_reset")
.help("Resets the server name format"),
command!(server_format, ("format", OpaqueString) => "cfg_server_name_format_update")
.help("Sets the server name format"),
command!(server_format_short => "cfg_server_name_format_show")
.help("Shows the server name format"),
command!(server_format_short, RESET => "cfg_server_name_format_reset")
.help("Resets the server name format"),
command!(server_format_short, ("format", OpaqueString) => "cfg_server_name_format_update")
.help("Sets the server name format"),
command!(member_limit => "cfg_limits_update").help("Refreshes member/group limits"),
command!(group_limit => "cfg_limits_update").help("Refreshes member/group limits"),
command!(limit => "cfg_limits_update").help("Refreshes member/group limits"),
] ]
.into_iter() .into_iter()
} }

View file

@ -252,8 +252,8 @@ pub fn edit() -> impl Iterator<Item = Command> {
.into_iter(); .into_iter();
let system_link = [ let system_link = [
command!("link" => "system_link"), command!("link", ("account", UserRef) => "system_link"),
command!("unlink", ("target", OpaqueString) => "system_unlink"), command!("unlink", ("account", OpaqueString) => "system_unlink"),
] ]
.into_iter(); .into_iter();

View file

@ -27,6 +27,7 @@ pub enum ParameterValue {
PrivacyLevel(String), PrivacyLevel(String),
Toggle(bool), Toggle(bool),
Avatar(String), Avatar(String),
ProxySwitchAction(ProxySwitchAction),
Null, Null,
} }
@ -179,6 +180,9 @@ impl Parameter {
.parse::<u64>() .parse::<u64>()
.map(ParameterValue::GuildRef) .map(ParameterValue::GuildRef)
.map_err(|_| SmolStr::new("invalid guild ID")), .map_err(|_| SmolStr::new("invalid guild ID")),
ParameterKind::ProxySwitchAction => ProxySwitchAction::from_str(input)
.map(ParameterValue::ProxySwitchAction)
.map_err(|_| SmolStr::new("invalid proxy switch action, must be new/add/off")),
} }
} }
} }
@ -208,8 +212,9 @@ impl Display for Parameter {
ParameterKind::GroupPrivacyTarget => write!(f, "<privacy target>"), ParameterKind::GroupPrivacyTarget => write!(f, "<privacy target>"),
ParameterKind::SystemPrivacyTarget => write!(f, "<privacy target>"), ParameterKind::SystemPrivacyTarget => write!(f, "<privacy target>"),
ParameterKind::PrivacyLevel => write!(f, "[privacy level]"), ParameterKind::PrivacyLevel => write!(f, "[privacy level]"),
ParameterKind::Toggle => write!(f, "on/off"), ParameterKind::Toggle => write!(f, "<on|off>"),
ParameterKind::Avatar => write!(f, "<url|@mention>"), ParameterKind::Avatar => write!(f, "<url|@mention>"),
ParameterKind::ProxySwitchAction => write!(f, "<new|add|off>"),
} }
} }
} }
@ -290,6 +295,7 @@ pub enum ParameterKind {
PrivacyLevel, PrivacyLevel,
Toggle, Toggle,
Avatar, Avatar,
ProxySwitchAction,
} }
impl ParameterKind { impl ParameterKind {
@ -313,6 +319,7 @@ impl ParameterKind {
ParameterKind::PrivacyLevel => "privacy_level", ParameterKind::PrivacyLevel => "privacy_level",
ParameterKind::Toggle => "toggle", ParameterKind::Toggle => "toggle",
ParameterKind::Avatar => "avatar", ParameterKind::Avatar => "avatar",
ParameterKind::ProxySwitchAction => "proxy_switch_action",
} }
} }
} }
@ -521,3 +528,35 @@ impl Into<bool> for Toggle {
} }
} }
} }
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum ProxySwitchAction {
New,
Add,
Off,
}
impl AsRef<str> for ProxySwitchAction {
fn as_ref(&self) -> &str {
match self {
ProxySwitchAction::New => "new",
ProxySwitchAction::Add => "add",
ProxySwitchAction::Off => "off",
}
}
}
impl FromStr for ProxySwitchAction {
type Err = SmolStr;
fn from_str(s: &str) -> Result<Self, Self::Err> {
[
ProxySwitchAction::New,
ProxySwitchAction::Add,
ProxySwitchAction::Off,
]
.into_iter()
.find(|action| action.as_ref() == s)
.ok_or_else(|| SmolStr::new("invalid proxy switch action, must be new/add/off"))
}
}

View file

@ -276,6 +276,7 @@ fn get_param_ty(kind: ParameterKind) -> &'static str {
ParameterKind::MessageRef => "Message.Reference", ParameterKind::MessageRef => "Message.Reference",
ParameterKind::ChannelRef => "Channel", ParameterKind::ChannelRef => "Channel",
ParameterKind::GuildRef => "Guild", ParameterKind::GuildRef => "Guild",
ParameterKind::ProxySwitchAction => "SystemConfig.ProxySwitchAction",
} }
} }
@ -298,6 +299,7 @@ fn get_param_param_ty(kind: ParameterKind) -> &'static str {
ParameterKind::MessageRef => "Message", ParameterKind::MessageRef => "Message",
ParameterKind::ChannelRef => "Channel", ParameterKind::ChannelRef => "Channel",
ParameterKind::GuildRef => "Guild", ParameterKind::GuildRef => "Guild",
ParameterKind::ProxySwitchAction => "ProxySwitchAction",
} }
} }

View file

@ -25,6 +25,7 @@ interface Parameter {
OpaqueInt(i32 raw); OpaqueInt(i32 raw);
Toggle(boolean toggle); Toggle(boolean toggle);
Avatar(string avatar); Avatar(string avatar);
ProxySwitchAction(string action);
Null(); Null();
}; };
dictionary ParsedCommand { dictionary ParsedCommand {

View file

@ -75,6 +75,9 @@ pub enum Parameter {
Avatar { Avatar {
avatar: String, avatar: String,
}, },
ProxySwitchAction {
action: String,
},
Null, Null,
} }
@ -103,6 +106,9 @@ impl From<ParameterValue> for Parameter {
ParameterValue::ChannelRef(channel_id) => Self::ChannelRef { channel_id }, ParameterValue::ChannelRef(channel_id) => Self::ChannelRef { channel_id },
ParameterValue::GuildRef(guild_id) => Self::GuildRef { guild_id }, ParameterValue::GuildRef(guild_id) => Self::GuildRef { guild_id },
ParameterValue::Null => Self::Null, ParameterValue::Null => Self::Null,
ParameterValue::ProxySwitchAction(action) => Self::ProxySwitchAction {
action: action.as_ref().to_string(),
},
} }
} }
} }