mirror of
https://github.com/PluralKit/PluralKit.git
synced 2026-02-04 04:56:49 +00:00
feat: implement member proxy commands
This commit is contained in:
parent
4a7ee0deb0
commit
1196d87fe7
3 changed files with 159 additions and 149 deletions
|
|
@ -44,6 +44,11 @@ public partial class CommandTree
|
|||
Commands.MemberServerKeepproxyShow(var param, _) => ctx.Execute<MemberEdit>(MemberServerKeepProxy, m => m.ShowServerKeepProxy(ctx, param.target)),
|
||||
Commands.MemberServerKeepproxyUpdate(var param, _) => ctx.Execute<MemberEdit>(MemberServerKeepProxy, m => m.ChangeServerKeepProxy(ctx, param.target, param.value)),
|
||||
Commands.MemberServerKeepproxyClear(var param, var flags) => ctx.Execute<MemberEdit>(MemberServerKeepProxy, m => m.ClearServerKeepProxy(ctx, param.target, flags.yes)),
|
||||
Commands.MemberProxyShow(var param, _) => ctx.Execute<MemberProxy>(MemberProxy, m => m.ShowProxy(ctx, param.target)),
|
||||
Commands.MemberProxyClear(var param, var flags) => ctx.Execute<MemberProxy>(MemberProxy, m => m.ClearProxy(ctx, param.target)),
|
||||
Commands.MemberProxyAdd(var param, _) => ctx.Execute<MemberProxy>(MemberProxy, m => m.AddProxy(ctx, param.target, param.tag)),
|
||||
Commands.MemberProxyRemove(var param, _) => ctx.Execute<MemberProxy>(MemberProxy, m => m.RemoveProxy(ctx, param.target, param.tag)),
|
||||
Commands.MemberProxySet(var param, _) => ctx.Execute<MemberProxy>(MemberProxy, m => m.SetProxy(ctx, param.target, param.tags)),
|
||||
Commands.MemberTtsShow(var param, _) => ctx.Execute<MemberEdit>(MemberTts, m => m.ShowTts(ctx, param.target)),
|
||||
Commands.MemberTtsUpdate(var param, _) => ctx.Execute<MemberEdit>(MemberTts, m => m.ChangeTts(ctx, param.target, param.value)),
|
||||
Commands.MemberAutoproxyShow(var param, _) => ctx.Execute<MemberEdit>(MemberAutoproxy, m => m.ShowAutoproxy(ctx, param.target)),
|
||||
|
|
@ -430,9 +435,7 @@ public partial class CommandTree
|
|||
private async Task HandleMemberCommandTargeted(Context ctx, PKMember target)
|
||||
{
|
||||
// Commands that have a member target (eg. pk;member <member> delete)
|
||||
if (ctx.Match("proxy", "tags", "proxytags", "brackets"))
|
||||
await ctx.Execute<MemberProxy>(MemberProxy, m => m.Proxy(ctx, target));
|
||||
else if (ctx.Match("avatar", "profile", "picture", "icon", "image", "pfp", "pic"))
|
||||
if (ctx.Match("avatar", "profile", "picture", "icon", "image", "pfp", "pic"))
|
||||
await ctx.Execute<MemberAvatar>(MemberAvatar, m => m.Avatar(ctx, target));
|
||||
else if (ctx.Match("proxyavatar", "proxypfp", "webhookavatar", "webhookpfp", "pa", "pavatar", "ppfp"))
|
||||
await ctx.Execute<MemberAvatar>(MemberAvatar, m => m.WebhookAvatar(ctx, target));
|
||||
|
|
|
|||
|
|
@ -6,133 +6,120 @@ namespace PluralKit.Bot;
|
|||
|
||||
public class MemberProxy
|
||||
{
|
||||
public async Task Proxy(Context ctx, PKMember target)
|
||||
public async Task ShowProxy(Context ctx, PKMember target)
|
||||
{
|
||||
if (target.ProxyTags.Count == 0)
|
||||
await ctx.Reply("This member does not have any proxy tags.");
|
||||
else
|
||||
await ctx.Reply($"This member's proxy tags are:\n{target.ProxyTagsString("\n")}");
|
||||
}
|
||||
|
||||
public async Task ClearProxy(Context ctx, PKMember target)
|
||||
{
|
||||
ctx.CheckSystem().CheckOwnMember(target);
|
||||
|
||||
ProxyTag ParseProxyTags(string exampleProxy)
|
||||
// If we already have multiple tags, this would clear everything, so prompt that
|
||||
if (target.ProxyTags.Count > 1)
|
||||
{
|
||||
// // Make sure there's one and only one instance of "text" in the example proxy given
|
||||
var prefixAndSuffix = exampleProxy.Split("text");
|
||||
if (prefixAndSuffix.Length == 1) prefixAndSuffix = prefixAndSuffix[0].Split("TEXT");
|
||||
if (prefixAndSuffix.Length < 2) throw Errors.ProxyMustHaveText;
|
||||
if (prefixAndSuffix.Length > 2) throw Errors.ProxyMultipleText;
|
||||
return new ProxyTag(prefixAndSuffix[0], prefixAndSuffix[1]);
|
||||
}
|
||||
|
||||
async Task<bool> WarnOnConflict(ProxyTag newTag)
|
||||
{
|
||||
var query = "select * from (select *, (unnest(proxy_tags)).prefix as prefix, (unnest(proxy_tags)).suffix as suffix from members where system = @System) as _ where prefix is not distinct from @Prefix and suffix is not distinct from @Suffix and id != @Existing";
|
||||
var conflicts = (await ctx.Database.Execute(conn => conn.QueryAsync<PKMember>(query,
|
||||
new { newTag.Prefix, newTag.Suffix, Existing = target.Id, system = target.System }))).ToList();
|
||||
|
||||
if (conflicts.Count <= 0) return true;
|
||||
|
||||
var conflictList = conflicts.Select(m => $"- **{m.NameFor(ctx)}**");
|
||||
var msg = $"{Emojis.Warn} The following members have conflicting proxy tags:\n{string.Join('\n', conflictList)}\nDo you want to proceed anyway?";
|
||||
return await ctx.PromptYesNo(msg, "Proceed");
|
||||
}
|
||||
|
||||
// "Sub"command: clear flag
|
||||
if (ctx.MatchClear())
|
||||
{
|
||||
// If we already have multiple tags, this would clear everything, so prompt that
|
||||
if (target.ProxyTags.Count > 1)
|
||||
{
|
||||
var msg = $"{Emojis.Warn} You already have multiple proxy tags set: {target.ProxyTagsString()}\nDo you want to clear them all?";
|
||||
if (!await ctx.PromptYesNo(msg, "Clear"))
|
||||
throw Errors.GenericCancelled();
|
||||
}
|
||||
|
||||
var patch = new MemberPatch { ProxyTags = Partial<ProxyTag[]>.Present(new ProxyTag[0]) };
|
||||
await ctx.Repository.UpdateMember(target.Id, patch);
|
||||
|
||||
await ctx.Reply($"{Emojis.Success} Proxy tags cleared.");
|
||||
}
|
||||
// "Sub"command: no arguments; will print proxy tags
|
||||
else if (!ctx.HasNext(false))
|
||||
{
|
||||
if (target.ProxyTags.Count == 0)
|
||||
await ctx.Reply("This member does not have any proxy tags.");
|
||||
else
|
||||
await ctx.Reply($"This member's proxy tags are:\n{target.ProxyTagsString("\n")}");
|
||||
}
|
||||
// Subcommand: "add"
|
||||
else if (ctx.Match("add", "append"))
|
||||
{
|
||||
if (!ctx.HasNext(false))
|
||||
throw new PKSyntaxError("You must pass an example proxy to add (eg. `[text]` or `J:text`).");
|
||||
|
||||
var tagToAdd = ParseProxyTags(ctx.RemainderOrNull(false).NormalizeLineEndSpacing());
|
||||
if (tagToAdd.IsEmpty) throw Errors.EmptyProxyTags(target, ctx);
|
||||
if (target.ProxyTags.Contains(tagToAdd))
|
||||
throw Errors.ProxyTagAlreadyExists(tagToAdd, target);
|
||||
if (tagToAdd.ProxyString.Length > Limits.MaxProxyTagLength)
|
||||
throw new PKError(
|
||||
$"Proxy tag too long ({tagToAdd.ProxyString.Length} > {Limits.MaxProxyTagLength} characters).");
|
||||
|
||||
if (!await WarnOnConflict(tagToAdd))
|
||||
var msg = $"{Emojis.Warn} You already have multiple proxy tags set: {target.ProxyTagsString()}\nDo you want to clear them all?";
|
||||
if (!await ctx.PromptYesNo(msg, "Clear"))
|
||||
throw Errors.GenericCancelled();
|
||||
|
||||
var newTags = target.ProxyTags.ToList();
|
||||
newTags.Add(tagToAdd);
|
||||
var patch = new MemberPatch { ProxyTags = Partial<ProxyTag[]>.Present(newTags.ToArray()) };
|
||||
await ctx.Repository.UpdateMember(target.Id, patch);
|
||||
|
||||
await ctx.Reply($"{Emojis.Success} Added proxy tags {tagToAdd.ProxyString.AsCode()} (using {tagToAdd.ProxyString.Length}/{Limits.MaxProxyTagLength} characters).");
|
||||
}
|
||||
// Subcommand: "remove"
|
||||
else if (ctx.Match("remove", "delete"))
|
||||
|
||||
var patch = new MemberPatch { ProxyTags = Partial<ProxyTag[]>.Present(new ProxyTag[0]) };
|
||||
await ctx.Repository.UpdateMember(target.Id, patch);
|
||||
|
||||
await ctx.Reply($"{Emojis.Success} Proxy tags cleared.");
|
||||
}
|
||||
|
||||
public async Task AddProxy(Context ctx, PKMember target, string proxyString)
|
||||
{
|
||||
ctx.CheckSystem().CheckOwnMember(target);
|
||||
|
||||
var tagToAdd = ParseProxyTag(proxyString);
|
||||
if (tagToAdd.IsEmpty) throw Errors.EmptyProxyTags(target, ctx);
|
||||
if (target.ProxyTags.Contains(tagToAdd))
|
||||
throw Errors.ProxyTagAlreadyExists(tagToAdd, target);
|
||||
if (tagToAdd.ProxyString.Length > Limits.MaxProxyTagLength)
|
||||
throw new PKError(
|
||||
$"Proxy tag too long ({tagToAdd.ProxyString.Length} > {Limits.MaxProxyTagLength} characters).");
|
||||
|
||||
if (!await WarnOnConflict(ctx, target, tagToAdd))
|
||||
throw Errors.GenericCancelled();
|
||||
|
||||
var newTags = target.ProxyTags.ToList();
|
||||
newTags.Add(tagToAdd);
|
||||
var patch = new MemberPatch { ProxyTags = Partial<ProxyTag[]>.Present(newTags.ToArray()) };
|
||||
await ctx.Repository.UpdateMember(target.Id, patch);
|
||||
|
||||
await ctx.Reply($"{Emojis.Success} Added proxy tags {tagToAdd.ProxyString.AsCode()} (using {tagToAdd.ProxyString.Length}/{Limits.MaxProxyTagLength} characters).");
|
||||
}
|
||||
|
||||
public async Task RemoveProxy(Context ctx, PKMember target, string proxyString)
|
||||
{
|
||||
ctx.CheckSystem().CheckOwnMember(target);
|
||||
|
||||
var tagToRemove = ParseProxyTag(proxyString);
|
||||
if (tagToRemove.IsEmpty) throw Errors.EmptyProxyTags(target, ctx);
|
||||
if (!target.ProxyTags.Contains(tagToRemove))
|
||||
throw Errors.ProxyTagDoesNotExist(tagToRemove, target);
|
||||
|
||||
var newTags = target.ProxyTags.ToList();
|
||||
newTags.Remove(tagToRemove);
|
||||
var patch = new MemberPatch { ProxyTags = Partial<ProxyTag[]>.Present(newTags.ToArray()) };
|
||||
await ctx.Repository.UpdateMember(target.Id, patch);
|
||||
|
||||
await ctx.Reply($"{Emojis.Success} Removed proxy tags {tagToRemove.ProxyString.AsCode()}.");
|
||||
}
|
||||
|
||||
public async Task SetProxy(Context ctx, PKMember target, string proxyString)
|
||||
{
|
||||
ctx.CheckSystem().CheckOwnMember(target);
|
||||
|
||||
var requestedTag = ParseProxyTag(proxyString);
|
||||
if (requestedTag.IsEmpty) throw Errors.EmptyProxyTags(target, ctx);
|
||||
|
||||
if (target.ProxyTags.Count > 1)
|
||||
{
|
||||
if (!ctx.HasNext(false))
|
||||
throw new PKSyntaxError("You must pass a proxy tag to remove (eg. `[text]` or `J:text`).");
|
||||
|
||||
var remainder = ctx.RemainderOrNull(false);
|
||||
var tagToRemove = ParseProxyTags(remainder.NormalizeLineEndSpacing());
|
||||
if (tagToRemove.IsEmpty) throw Errors.EmptyProxyTags(target, ctx);
|
||||
if (!target.ProxyTags.Contains(tagToRemove))
|
||||
{
|
||||
// Legacy support for when line endings weren't normalized
|
||||
tagToRemove = ParseProxyTags(remainder);
|
||||
if (!target.ProxyTags.Contains(tagToRemove))
|
||||
throw Errors.ProxyTagDoesNotExist(tagToRemove, target);
|
||||
}
|
||||
|
||||
|
||||
var newTags = target.ProxyTags.ToList();
|
||||
newTags.Remove(tagToRemove);
|
||||
var patch = new MemberPatch { ProxyTags = Partial<ProxyTag[]>.Present(newTags.ToArray()) };
|
||||
await ctx.Repository.UpdateMember(target.Id, patch);
|
||||
|
||||
await ctx.Reply($"{Emojis.Success} Removed proxy tags {tagToRemove.ProxyString.AsCode()}.");
|
||||
}
|
||||
// Subcommand: bare proxy tag given
|
||||
else
|
||||
{
|
||||
var requestedTag = ParseProxyTags(ctx.RemainderOrNull(false).NormalizeLineEndSpacing());
|
||||
if (requestedTag.IsEmpty) throw Errors.EmptyProxyTags(target, ctx);
|
||||
|
||||
// This is mostly a legacy command, so it's gonna warn if there's
|
||||
// already more than one proxy tag.
|
||||
if (target.ProxyTags.Count > 1)
|
||||
{
|
||||
var msg = $"This member already has more than one proxy tag set: {target.ProxyTagsString()}\nDo you want to replace them?";
|
||||
if (!await ctx.PromptYesNo(msg, "Replace"))
|
||||
throw Errors.GenericCancelled();
|
||||
}
|
||||
|
||||
if (requestedTag.ProxyString.Length > Limits.MaxProxyTagLength)
|
||||
throw new PKError(
|
||||
$"Proxy tag too long ({requestedTag.ProxyString.Length} > {Limits.MaxProxyTagLength} characters).");
|
||||
|
||||
if (!await WarnOnConflict(requestedTag))
|
||||
var msg = $"This member already has more than one proxy tag set: {target.ProxyTagsString()}\nDo you want to replace them?";
|
||||
if (!await ctx.PromptYesNo(msg, "Replace"))
|
||||
throw Errors.GenericCancelled();
|
||||
|
||||
var newTags = new[] { requestedTag };
|
||||
var patch = new MemberPatch { ProxyTags = Partial<ProxyTag[]>.Present(newTags) };
|
||||
await ctx.Repository.UpdateMember(target.Id, patch);
|
||||
|
||||
await ctx.Reply($"{Emojis.Success} Member proxy tags set to {requestedTag.ProxyString.AsCode()} (using {requestedTag.ProxyString.Length}/{Limits.MaxProxyTagLength} characters).");
|
||||
}
|
||||
|
||||
if (requestedTag.ProxyString.Length > Limits.MaxProxyTagLength)
|
||||
throw new PKError(
|
||||
$"Proxy tag too long ({requestedTag.ProxyString.Length} > {Limits.MaxProxyTagLength} characters).");
|
||||
|
||||
if (!await WarnOnConflict(ctx, target, requestedTag))
|
||||
throw Errors.GenericCancelled();
|
||||
|
||||
var newTags = new[] { requestedTag };
|
||||
var patch = new MemberPatch { ProxyTags = Partial<ProxyTag[]>.Present(newTags) };
|
||||
await ctx.Repository.UpdateMember(target.Id, patch);
|
||||
|
||||
await ctx.Reply($"{Emojis.Success} Member proxy tags set to {requestedTag.ProxyString.AsCode()} (using {requestedTag.ProxyString.Length}/{Limits.MaxProxyTagLength} characters).");
|
||||
}
|
||||
|
||||
private ProxyTag ParseProxyTag(string proxyString)
|
||||
{
|
||||
// Make sure there's one and only one instance of "text" in the example proxy given
|
||||
var prefixAndSuffix = proxyString.Split("text");
|
||||
if (prefixAndSuffix.Length == 1) prefixAndSuffix = prefixAndSuffix[0].Split("TEXT");
|
||||
if (prefixAndSuffix.Length < 2) throw Errors.ProxyMustHaveText;
|
||||
if (prefixAndSuffix.Length > 2) throw Errors.ProxyMultipleText;
|
||||
return new ProxyTag(prefixAndSuffix[0], prefixAndSuffix[1]);
|
||||
}
|
||||
|
||||
private async Task<bool> WarnOnConflict(Context ctx, PKMember target, ProxyTag newTag)
|
||||
{
|
||||
var query = "select * from (select *, (unnest(proxy_tags)).prefix as prefix, (unnest(proxy_tags)).suffix as suffix from members where system = @System) as _ where prefix is not distinct from @Prefix and suffix is not distinct from @Suffix and id != @Existing";
|
||||
var conflicts = (await ctx.Database.Execute(conn => conn.QueryAsync<PKMember>(query,
|
||||
new { newTag.Prefix, newTag.Suffix, Existing = target.Id, system = target.System }))).ToList();
|
||||
|
||||
if (conflicts.Count <= 0) return true;
|
||||
|
||||
var conflictList = conflicts.Select(m => $"- **{m.NameFor(ctx)}**");
|
||||
var msg = $"{Emojis.Warn} The following members have conflicting proxy tags:\n{string.Join('\n', conflictList)}\nDo you want to proceed anyway?";
|
||||
return await ctx.PromptYesNo(msg, "Proceed");
|
||||
}
|
||||
}
|
||||
|
|
@ -17,20 +17,20 @@ pub fn cmds() -> impl Iterator<Item = Command> {
|
|||
let keep_proxy = ("keepproxy", ["kp"]);
|
||||
let server_keep_proxy = ("serverkeepproxy", ["skp"]);
|
||||
let autoproxy = ("autoproxy", ["ap"]);
|
||||
let proxy = ("proxy", ["tags", "proxytags", "brackets"]);
|
||||
let tts = ("tts", ["texttospeech"]);
|
||||
let delete = ("delete", ["del", "remove"]);
|
||||
|
||||
// Group commands by functionality
|
||||
let member_new_cmd = [
|
||||
command!(member, new, ("name", OpaqueString) => "member_new")
|
||||
.help("Creates a new system member"),
|
||||
].into_iter();
|
||||
]
|
||||
.into_iter();
|
||||
|
||||
let member_info_cmd = [
|
||||
command!(member_target => "member_show")
|
||||
.flag("pt")
|
||||
.help("Shows information about a member"),
|
||||
].into_iter();
|
||||
let member_info_cmd = [command!(member_target => "member_show")
|
||||
.flag("pt")
|
||||
.help("Shows information about a member")]
|
||||
.into_iter();
|
||||
|
||||
let member_name_cmd = {
|
||||
let member_name = tokens!(member_target, name);
|
||||
|
|
@ -38,7 +38,8 @@ pub fn cmds() -> impl Iterator<Item = Command> {
|
|||
command!(member_name => "member_name_show").help("Shows a member's name"),
|
||||
command!(member_name, ("name", OpaqueStringRemainder) => "member_name_update")
|
||||
.help("Changes a member's name"),
|
||||
].into_iter()
|
||||
]
|
||||
.into_iter()
|
||||
};
|
||||
|
||||
let member_description_cmd = {
|
||||
|
|
@ -50,7 +51,8 @@ pub fn cmds() -> impl Iterator<Item = Command> {
|
|||
.help("Clears a member's description"),
|
||||
command!(member_desc, ("description", OpaqueStringRemainder) => "member_desc_update")
|
||||
.help("Changes a member's description"),
|
||||
].into_iter()
|
||||
]
|
||||
.into_iter()
|
||||
};
|
||||
|
||||
let member_privacy_cmd = {
|
||||
|
|
@ -63,7 +65,8 @@ pub fn cmds() -> impl Iterator<Item = Command> {
|
|||
=> "member_privacy_update"
|
||||
)
|
||||
.help("Changes a member's privacy settings"),
|
||||
].into_iter()
|
||||
]
|
||||
.into_iter()
|
||||
};
|
||||
|
||||
let member_pronouns_cmd = {
|
||||
|
|
@ -82,40 +85,40 @@ pub fn cmds() -> impl Iterator<Item = Command> {
|
|||
let member_banner_cmd = {
|
||||
let member_banner = tokens!(member_target, banner);
|
||||
[
|
||||
command!(member_banner => "member_banner_show")
|
||||
.help("Shows a member's banner image"),
|
||||
command!(member_banner => "member_banner_show").help("Shows a member's banner image"),
|
||||
command!(member_banner, ("banner", Avatar) => "member_banner_update")
|
||||
.help("Changes a member's banner image"),
|
||||
command!(member_banner, ("clear", ["c"]) => "member_banner_clear")
|
||||
.flag(("yes", ["y"]))
|
||||
.help("Clears a member's banner image"),
|
||||
].into_iter()
|
||||
]
|
||||
.into_iter()
|
||||
};
|
||||
|
||||
let member_color_cmd = {
|
||||
let member_color = tokens!(member_target, color);
|
||||
[
|
||||
command!(member_color => "member_color_show")
|
||||
.help("Shows a member's color"),
|
||||
command!(member_color => "member_color_show").help("Shows a member's color"),
|
||||
command!(member_color, ("color", OpaqueString) => "member_color_update")
|
||||
.help("Changes a member's color"),
|
||||
command!(member_color, ("clear", ["c"]) => "member_color_clear")
|
||||
.flag(("yes", ["y"]))
|
||||
.help("Clears a member's color"),
|
||||
].into_iter()
|
||||
]
|
||||
.into_iter()
|
||||
};
|
||||
|
||||
let member_birthday_cmd = {
|
||||
let member_birthday = tokens!(member_target, birthday);
|
||||
[
|
||||
command!(member_birthday => "member_birthday_show")
|
||||
.help("Shows a member's birthday"),
|
||||
command!(member_birthday => "member_birthday_show").help("Shows a member's birthday"),
|
||||
command!(member_birthday, ("birthday", OpaqueString) => "member_birthday_update")
|
||||
.help("Changes a member's birthday"),
|
||||
command!(member_birthday, ("clear", ["c"]) => "member_birthday_clear")
|
||||
.flag(("yes", ["y"]))
|
||||
.help("Clears a member's birthday"),
|
||||
].into_iter()
|
||||
]
|
||||
.into_iter()
|
||||
};
|
||||
|
||||
let member_display_name_cmd = {
|
||||
|
|
@ -144,6 +147,23 @@ pub fn cmds() -> impl Iterator<Item = Command> {
|
|||
].into_iter()
|
||||
};
|
||||
|
||||
let member_proxy_cmd = {
|
||||
let member_proxy = tokens!(member_target, proxy);
|
||||
[
|
||||
command!(member_proxy => "member_proxy_show")
|
||||
.help("Shows a member's proxy tags"),
|
||||
command!(member_proxy, ("tags", OpaqueString) => "member_proxy_set")
|
||||
.help("Sets a member's proxy tags"),
|
||||
command!(member_proxy, ("add", ["a"]), ("tag", OpaqueString) => "member_proxy_add")
|
||||
.help("Adds proxy tag to a member"),
|
||||
command!(member_proxy, ("remove", ["r", "rm"]), ("tag", OpaqueString) => "member_proxy_remove")
|
||||
.help("Removes proxy tag from a member"),
|
||||
command!(member_proxy, ("clear", ["c"]) => "member_proxy_clear")
|
||||
.flag(("yes", ["y"]))
|
||||
.help("Clears all proxy tags from a member"),
|
||||
].into_iter()
|
||||
};
|
||||
|
||||
let member_proxy_settings_cmd = {
|
||||
let member_keep_proxy = tokens!(member_target, keep_proxy);
|
||||
let member_server_keep_proxy = tokens!(member_target, server_keep_proxy);
|
||||
|
|
@ -174,17 +194,16 @@ pub fn cmds() -> impl Iterator<Item = Command> {
|
|||
.help("Shows whether a member can be autoproxied"),
|
||||
command!(member_autoproxy, ("value", Toggle) => "member_autoproxy_update")
|
||||
.help("Changes whether a member can be autoproxied"),
|
||||
].into_iter()
|
||||
]
|
||||
.into_iter()
|
||||
};
|
||||
|
||||
let member_delete_cmd = [
|
||||
command!(member_target, delete => "member_delete")
|
||||
.help("Deletes a member"),
|
||||
].into_iter();
|
||||
let member_delete_cmd =
|
||||
[command!(member_target, delete => "member_delete").help("Deletes a member")].into_iter();
|
||||
|
||||
let member_easter_eggs = [
|
||||
command!(member_target, "soulscream" => "member_soulscream").show_in_suggestions(false),
|
||||
].into_iter();
|
||||
let member_easter_eggs =
|
||||
[command!(member_target, "soulscream" => "member_soulscream").show_in_suggestions(false)]
|
||||
.into_iter();
|
||||
|
||||
member_new_cmd
|
||||
.chain(member_info_cmd)
|
||||
|
|
@ -197,6 +216,7 @@ pub fn cmds() -> impl Iterator<Item = Command> {
|
|||
.chain(member_birthday_cmd)
|
||||
.chain(member_display_name_cmd)
|
||||
.chain(member_server_name_cmd)
|
||||
.chain(member_proxy_cmd)
|
||||
.chain(member_proxy_settings_cmd)
|
||||
.chain(member_message_settings_cmd)
|
||||
.chain(member_delete_cmd)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue