mirror of
https://github.com/PluralKit/PluralKit.git
synced 2026-02-15 18:20:11 +00:00
feat: implement member edit commands
This commit is contained in:
parent
aa397137f2
commit
4a7ee0deb0
3 changed files with 794 additions and 641 deletions
|
|
@ -16,6 +16,41 @@ public partial class CommandTree
|
||||||
Commands.MemberShow(var param, _) => ctx.Execute<Member>(MemberInfo, m => m.ViewMember(ctx, param.target)),
|
Commands.MemberShow(var param, _) => ctx.Execute<Member>(MemberInfo, m => m.ViewMember(ctx, param.target)),
|
||||||
Commands.MemberNew(var param, _) => ctx.Execute<Member>(MemberNew, m => m.NewMember(ctx, param.name)),
|
Commands.MemberNew(var param, _) => ctx.Execute<Member>(MemberNew, m => m.NewMember(ctx, param.name)),
|
||||||
Commands.MemberSoulscream(var param, _) => ctx.Execute<Member>(MemberInfo, m => m.Soulscream(ctx, param.target)),
|
Commands.MemberSoulscream(var param, _) => ctx.Execute<Member>(MemberInfo, m => m.Soulscream(ctx, param.target)),
|
||||||
|
Commands.MemberPronounsShow(var param, var flags) => ctx.Execute<MemberEdit>(MemberPronouns, m => m.ShowPronouns(ctx, param.target, flags.GetReplyFormat())),
|
||||||
|
Commands.MemberPronounsClear(var param, var flags) => ctx.Execute<MemberEdit>(MemberPronouns, m => m.ClearPronouns(ctx, param.target, flags.yes)),
|
||||||
|
Commands.MemberPronounsUpdate(var param, _) => ctx.Execute<MemberEdit>(MemberPronouns, m => m.ChangePronouns(ctx, param.target, param.pronouns)),
|
||||||
|
Commands.MemberDescShow(var param, var flags) => ctx.Execute<MemberEdit>(MemberDesc, m => m.ShowDescription(ctx, param.target, flags.GetReplyFormat())),
|
||||||
|
Commands.MemberDescClear(var param, var flags) => ctx.Execute<MemberEdit>(MemberDesc, m => m.ClearDescription(ctx, param.target, flags.yes)),
|
||||||
|
Commands.MemberDescUpdate(var param, _) => ctx.Execute<MemberEdit>(MemberDesc, m => m.ChangeDescription(ctx, param.target, param.description)),
|
||||||
|
Commands.MemberNameShow(var param, var flags) => ctx.Execute<MemberEdit>(MemberInfo, m => m.ShowName(ctx, param.target, flags.GetReplyFormat())),
|
||||||
|
Commands.MemberNameUpdate(var param, _) => ctx.Execute<MemberEdit>(MemberInfo, m => m.ChangeName(ctx, param.target, param.name)),
|
||||||
|
Commands.MemberBannerShow(var param, var flags) => ctx.Execute<MemberEdit>(MemberBannerImage, m => m.ShowBannerImage(ctx, param.target, flags.GetReplyFormat())),
|
||||||
|
Commands.MemberBannerClear(var param, var flags) => ctx.Execute<MemberEdit>(MemberBannerImage, m => m.ClearBannerImage(ctx, param.target, flags.yes)),
|
||||||
|
Commands.MemberBannerUpdate(var param, _) => ctx.Execute<MemberEdit>(MemberBannerImage, m => m.ChangeBannerImage(ctx, param.target, param.banner)),
|
||||||
|
Commands.MemberColorShow(var param, var flags) => ctx.Execute<MemberEdit>(MemberColor, m => m.ShowColor(ctx, param.target, flags.GetReplyFormat())),
|
||||||
|
Commands.MemberColorClear(var param, var flags) => ctx.Execute<MemberEdit>(MemberColor, m => m.ClearColor(ctx, param.target, flags.yes)),
|
||||||
|
Commands.MemberColorUpdate(var param, _) => ctx.Execute<MemberEdit>(MemberColor, m => m.ChangeColor(ctx, param.target, param.color)),
|
||||||
|
Commands.MemberBirthdayShow(var param, var flags) => ctx.Execute<MemberEdit>(MemberBirthday, m => m.ShowBirthday(ctx, param.target, flags.GetReplyFormat())),
|
||||||
|
Commands.MemberBirthdayClear(var param, var flags) => ctx.Execute<MemberEdit>(MemberBirthday, m => m.ClearBirthday(ctx, param.target, flags.yes)),
|
||||||
|
Commands.MemberBirthdayUpdate(var param, _) => ctx.Execute<MemberEdit>(MemberBirthday, m => m.ChangeBirthday(ctx, param.target, param.birthday)),
|
||||||
|
Commands.MemberDisplaynameShow(var param, var flags) => ctx.Execute<MemberEdit>(MemberDisplayName, m => m.ShowDisplayName(ctx, param.target, flags.GetReplyFormat())),
|
||||||
|
Commands.MemberDisplaynameClear(var param, var flags) => ctx.Execute<MemberEdit>(MemberDisplayName, m => m.ClearDisplayName(ctx, param.target, flags.yes)),
|
||||||
|
Commands.MemberDisplaynameUpdate(var param, _) => ctx.Execute<MemberEdit>(MemberDisplayName, m => m.ChangeDisplayName(ctx, param.target, param.name)),
|
||||||
|
Commands.MemberServernameShow(var param, var flags) => ctx.Execute<MemberEdit>(MemberServerName, m => m.ShowServerName(ctx, param.target, flags.GetReplyFormat())),
|
||||||
|
Commands.MemberServernameClear(var param, var flags) => ctx.Execute<MemberEdit>(MemberServerName, m => m.ClearServerName(ctx, param.target, flags.yes)),
|
||||||
|
Commands.MemberServernameUpdate(var param, _) => ctx.Execute<MemberEdit>(MemberServerName, m => m.ChangeServerName(ctx, param.target, param.name)),
|
||||||
|
Commands.MemberKeepproxyShow(var param, _) => ctx.Execute<MemberEdit>(MemberKeepProxy, m => m.ShowKeepProxy(ctx, param.target)),
|
||||||
|
Commands.MemberKeepproxyUpdate(var param, _) => ctx.Execute<MemberEdit>(MemberKeepProxy, m => m.ChangeKeepProxy(ctx, param.target, param.value)),
|
||||||
|
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.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)),
|
||||||
|
Commands.MemberAutoproxyUpdate(var param, _) => ctx.Execute<MemberEdit>(MemberAutoproxy, m => m.ChangeAutoproxy(ctx, param.target, param.value)),
|
||||||
|
Commands.MemberDelete(var param, _) => ctx.Execute<MemberEdit>(MemberDelete, m => m.Delete(ctx, param.target)),
|
||||||
|
Commands.MemberPrivacyShow(var param, _) => ctx.Execute<MemberEdit>(MemberPrivacy, m => m.ShowPrivacy(ctx, param.target)),
|
||||||
|
Commands.MemberPrivacyUpdate(var param, _) => ctx.Execute<MemberEdit>(MemberPrivacy, m => m.ChangePrivacy(ctx, param.target, param.member_privacy_target, param.new_privacy_level)),
|
||||||
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)),
|
||||||
|
|
@ -378,45 +413,29 @@ public partial class CommandTree
|
||||||
private async Task HandleMemberCommand(Context ctx)
|
private async Task HandleMemberCommand(Context ctx)
|
||||||
{
|
{
|
||||||
// TODO: implement
|
// TODO: implement
|
||||||
// if (ctx.Match("new", "n", "add", "create", "register"))
|
if (ctx.Match("list"))
|
||||||
// await ctx.Execute<Member>(MemberNew, m => m.NewMember(ctx));
|
await ctx.Execute<SystemList>(SystemList, m => m.MemberList(ctx, ctx.System));
|
||||||
// else if (ctx.Match("list"))
|
else if (ctx.Match("commands", "help"))
|
||||||
// await ctx.Execute<SystemList>(SystemList, m => m.MemberList(ctx, ctx.System));
|
await PrintCommandList(ctx, "members", MemberCommands);
|
||||||
// else if (ctx.Match("commands", "help"))
|
else if (await ctx.MatchMember() is PKMember target)
|
||||||
// await PrintCommandList(ctx, "members", MemberCommands);
|
await HandleMemberCommandTargeted(ctx, target);
|
||||||
// else if (await ctx.MatchMember() is PKMember target)
|
else if (!ctx.HasNext())
|
||||||
// await HandleMemberCommandTargeted(ctx, target);
|
await PrintCommandExpectedError(ctx, MemberNew, MemberInfo, MemberRename, MemberDisplayName,
|
||||||
// else if (!ctx.HasNext())
|
MemberServerName, MemberDesc, MemberPronouns,
|
||||||
// await PrintCommandExpectedError(ctx, MemberNew, MemberInfo, MemberRename, MemberDisplayName,
|
MemberColor, MemberBirthday, MemberProxy, MemberDelete, MemberAvatar);
|
||||||
// MemberServerName, MemberDesc, MemberPronouns,
|
else
|
||||||
// MemberColor, MemberBirthday, MemberProxy, MemberDelete, MemberAvatar);
|
await ctx.Reply($"{Emojis.Error} {ctx.CreateNotFoundError("Member", ctx.PopArgument())}");
|
||||||
// else
|
|
||||||
// await ctx.Reply($"{Emojis.Error} {ctx.CreateNotFoundError("Member", ctx.PopArgument())}");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task HandleMemberCommandTargeted(Context ctx, PKMember target)
|
private async Task HandleMemberCommandTargeted(Context ctx, PKMember target)
|
||||||
{
|
{
|
||||||
// Commands that have a member target (eg. pk;member <member> delete)
|
// Commands that have a member target (eg. pk;member <member> delete)
|
||||||
if (ctx.Match("rename", "name", "changename", "setname", "rn"))
|
if (ctx.Match("proxy", "tags", "proxytags", "brackets"))
|
||||||
await ctx.Execute<MemberEdit>(MemberRename, m => m.Name(ctx, target));
|
|
||||||
else if (ctx.Match("description", "desc", "describe", "d", "bio", "info", "text", "intro"))
|
|
||||||
await ctx.Execute<MemberEdit>(MemberDesc, m => m.Description(ctx, target));
|
|
||||||
else if (ctx.Match("pronouns", "pronoun", "prns", "pn"))
|
|
||||||
await ctx.Execute<MemberEdit>(MemberPronouns, m => m.Pronouns(ctx, target));
|
|
||||||
else if (ctx.Match("color", "colour"))
|
|
||||||
await ctx.Execute<MemberEdit>(MemberColor, m => m.Color(ctx, target));
|
|
||||||
else if (ctx.Match("birthday", "birth", "bday", "birthdate", "cakeday", "bdate", "bd"))
|
|
||||||
await ctx.Execute<MemberEdit>(MemberBirthday, m => m.Birthday(ctx, target));
|
|
||||||
else if (ctx.Match("proxy", "tags", "proxytags", "brackets"))
|
|
||||||
await ctx.Execute<MemberProxy>(MemberProxy, m => m.Proxy(ctx, target));
|
await ctx.Execute<MemberProxy>(MemberProxy, m => m.Proxy(ctx, target));
|
||||||
else if (ctx.Match("delete", "remove", "destroy", "erase", "yeet"))
|
|
||||||
await ctx.Execute<MemberEdit>(MemberDelete, m => m.Delete(ctx, target));
|
|
||||||
else if (ctx.Match("avatar", "profile", "picture", "icon", "image", "pfp", "pic"))
|
else if (ctx.Match("avatar", "profile", "picture", "icon", "image", "pfp", "pic"))
|
||||||
await ctx.Execute<MemberAvatar>(MemberAvatar, m => m.Avatar(ctx, target));
|
await ctx.Execute<MemberAvatar>(MemberAvatar, m => m.Avatar(ctx, target));
|
||||||
else if (ctx.Match("proxyavatar", "proxypfp", "webhookavatar", "webhookpfp", "pa", "pavatar", "ppfp"))
|
else if (ctx.Match("proxyavatar", "proxypfp", "webhookavatar", "webhookpfp", "pa", "pavatar", "ppfp"))
|
||||||
await ctx.Execute<MemberAvatar>(MemberAvatar, m => m.WebhookAvatar(ctx, target));
|
await ctx.Execute<MemberAvatar>(MemberAvatar, m => m.WebhookAvatar(ctx, target));
|
||||||
else if (ctx.Match("banner", "splash", "cover"))
|
|
||||||
await ctx.Execute<MemberEdit>(MemberBannerImage, m => m.BannerImage(ctx, target));
|
|
||||||
else if (ctx.Match("group", "groups", "g"))
|
else if (ctx.Match("group", "groups", "g"))
|
||||||
if (ctx.Match("add", "a"))
|
if (ctx.Match("add", "a"))
|
||||||
await ctx.Execute<GroupMember>(MemberGroupAdd,
|
await ctx.Execute<GroupMember>(MemberGroupAdd,
|
||||||
|
|
@ -429,27 +448,8 @@ public partial class CommandTree
|
||||||
else if (ctx.Match("serveravatar", "sa", "servericon", "serverimage", "serverpfp", "serverpic", "savatar", "spic",
|
else if (ctx.Match("serveravatar", "sa", "servericon", "serverimage", "serverpfp", "serverpic", "savatar", "spic",
|
||||||
"guildavatar", "guildpic", "guildicon", "sicon", "spfp"))
|
"guildavatar", "guildpic", "guildicon", "sicon", "spfp"))
|
||||||
await ctx.Execute<MemberAvatar>(MemberServerAvatar, m => m.ServerAvatar(ctx, target));
|
await ctx.Execute<MemberAvatar>(MemberServerAvatar, m => m.ServerAvatar(ctx, target));
|
||||||
else if (ctx.Match("displayname", "dn", "dname", "nick", "nickname", "dispname"))
|
|
||||||
await ctx.Execute<MemberEdit>(MemberDisplayName, m => m.DisplayName(ctx, target));
|
|
||||||
else if (ctx.Match("servername", "sn", "sname", "snick", "snickname", "servernick", "servernickname",
|
|
||||||
"serverdisplayname", "guildname", "guildnick", "guildnickname", "serverdn"))
|
|
||||||
await ctx.Execute<MemberEdit>(MemberServerName, m => m.ServerName(ctx, target));
|
|
||||||
else if (ctx.Match("autoproxy", "ap"))
|
|
||||||
await ctx.Execute<MemberEdit>(MemberAutoproxy, m => m.MemberAutoproxy(ctx, target));
|
|
||||||
else if (ctx.Match("keepproxy", "keeptags", "showtags", "kp"))
|
|
||||||
await ctx.Execute<MemberEdit>(MemberKeepProxy, m => m.KeepProxy(ctx, target));
|
|
||||||
else if (ctx.Match("texttospeech", "text-to-speech", "tts"))
|
|
||||||
await ctx.Execute<MemberEdit>(MemberTts, m => m.Tts(ctx, target));
|
|
||||||
else if (ctx.Match("serverkeepproxy", "servershowtags", "guildshowtags", "guildkeeptags", "serverkeeptags", "skp"))
|
|
||||||
await ctx.Execute<MemberEdit>(MemberServerKeepProxy, m => m.ServerKeepProxy(ctx, target));
|
|
||||||
else if (ctx.Match("id"))
|
else if (ctx.Match("id"))
|
||||||
await ctx.Execute<Member>(MemberId, m => m.DisplayId(ctx, target));
|
await ctx.Execute<Member>(MemberId, m => m.DisplayId(ctx, target));
|
||||||
else if (ctx.Match("privacy"))
|
|
||||||
await ctx.Execute<MemberEdit>(MemberPrivacy, m => m.Privacy(ctx, target, null));
|
|
||||||
else if (ctx.Match("private", "hidden", "hide"))
|
|
||||||
await ctx.Execute<MemberEdit>(MemberPrivacy, m => m.Privacy(ctx, target, PrivacyLevel.Private));
|
|
||||||
else if (ctx.Match("public", "shown", "show", "unhide", "unhidden"))
|
|
||||||
await ctx.Execute<MemberEdit>(MemberPrivacy, m => m.Privacy(ctx, target, PrivacyLevel.Public));
|
|
||||||
else
|
else
|
||||||
await PrintCommandNotFoundError(ctx, MemberInfo, MemberRename, MemberDisplayName, MemberServerName,
|
await PrintCommandNotFoundError(ctx, MemberInfo, MemberRename, MemberDisplayName, MemberServerName,
|
||||||
MemberDesc, MemberPronouns, MemberColor, MemberBirthday, MemberProxy, MemberDelete, MemberAvatar,
|
MemberDesc, MemberPronouns, MemberColor, MemberBirthday, MemberProxy, MemberDelete, MemberAvatar,
|
||||||
|
|
|
||||||
|
|
@ -21,11 +21,7 @@ public class MemberEdit
|
||||||
_avatarHosting = avatarHosting;
|
_avatarHosting = avatarHosting;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task Name(Context ctx, PKMember target)
|
public async Task ShowName(Context ctx, PKMember target, ReplyFormat format)
|
||||||
{
|
|
||||||
var format = ctx.MatchFormat();
|
|
||||||
|
|
||||||
if (!ctx.HasNext() || format != ReplyFormat.Standard)
|
|
||||||
{
|
{
|
||||||
var lctx = ctx.DirectLookupContextFor(target.System);
|
var lctx = ctx.DirectLookupContextFor(target.System);
|
||||||
switch (format)
|
switch (format)
|
||||||
|
|
@ -46,13 +42,12 @@ public class MemberEdit
|
||||||
await ctx.Reply(replyStrQ);
|
await ctx.Reply(replyStrQ);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task ChangeName(Context ctx, PKMember target, string newName)
|
||||||
|
{
|
||||||
ctx.CheckSystem().CheckOwnMember(target);
|
ctx.CheckSystem().CheckOwnMember(target);
|
||||||
|
|
||||||
var newName = ctx.RemainderOrNull() ?? throw new PKSyntaxError("You must pass a new name for the member.");
|
|
||||||
|
|
||||||
// Hard name length cap
|
// Hard name length cap
|
||||||
if (newName.Length > Limits.MaxMemberNameLength)
|
if (newName.Length > Limits.MaxMemberNameLength)
|
||||||
throw Errors.StringTooLongError("Member name", newName.Length, Limits.MaxMemberNameLength);
|
throw Errors.StringTooLongError("Member name", newName.Length, Limits.MaxMemberNameLength);
|
||||||
|
|
@ -85,7 +80,7 @@ public class MemberEdit
|
||||||
await ctx.Reply(replyStr);
|
await ctx.Reply(replyStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task Description(Context ctx, PKMember target)
|
public async Task ShowDescription(Context ctx, PKMember target, ReplyFormat format)
|
||||||
{
|
{
|
||||||
ctx.CheckSystemPrivacy(target.System, target.DescriptionPrivacy);
|
ctx.CheckSystemPrivacy(target.System, target.DescriptionPrivacy);
|
||||||
|
|
||||||
|
|
@ -94,10 +89,8 @@ public class MemberEdit
|
||||||
noDescriptionSetMessage +=
|
noDescriptionSetMessage +=
|
||||||
$" To set one, type `{ctx.DefaultPrefix}member {target.Reference(ctx)} description <description>`.";
|
$" To set one, type `{ctx.DefaultPrefix}member {target.Reference(ctx)} description <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 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 (format != ReplyFormat.Standard)
|
||||||
if (target.Description == null)
|
if (target.Description == null)
|
||||||
{
|
{
|
||||||
await ctx.Reply(noDescriptionSetMessage);
|
await ctx.Reply(noDescriptionSetMessage);
|
||||||
|
|
@ -117,8 +110,6 @@ public class MemberEdit
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ctx.HasNext(false))
|
|
||||||
{
|
|
||||||
await ctx.Reply(embed: new EmbedBuilder()
|
await ctx.Reply(embed: new EmbedBuilder()
|
||||||
.Title("Member description")
|
.Title("Member description")
|
||||||
.Description(target.Description)
|
.Description(target.Description)
|
||||||
|
|
@ -129,20 +120,27 @@ public class MemberEdit
|
||||||
+ $" Using {target.Description.Length}/{Limits.MaxDescriptionLength} characters."
|
+ $" Using {target.Description.Length}/{Limits.MaxDescriptionLength} characters."
|
||||||
: "")))
|
: "")))
|
||||||
.Build());
|
.Build());
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task ClearDescription(Context ctx, PKMember target, bool confirmYes)
|
||||||
|
{
|
||||||
|
ctx.CheckSystemPrivacy(target.System, target.DescriptionPrivacy);
|
||||||
ctx.CheckOwnMember(target);
|
ctx.CheckOwnMember(target);
|
||||||
|
|
||||||
if (ctx.MatchClear() && await ctx.ConfirmClear("this member's description"))
|
if (await ctx.ConfirmClear("this member's description", confirmYes))
|
||||||
{
|
{
|
||||||
var patch = new MemberPatch { Description = Partial<string>.Null() };
|
var patch = new MemberPatch { Description = Partial<string>.Null() };
|
||||||
await ctx.Repository.UpdateMember(target.Id, patch);
|
await ctx.Repository.UpdateMember(target.Id, patch);
|
||||||
await ctx.Reply($"{Emojis.Success} Member description cleared.");
|
await ctx.Reply($"{Emojis.Success} Member description cleared.");
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
|
|
||||||
|
public async Task ChangeDescription(Context ctx, PKMember target, string _description)
|
||||||
{
|
{
|
||||||
var description = ctx.RemainderOrNull(false).NormalizeLineEndSpacing();
|
ctx.CheckSystemPrivacy(target.System, target.DescriptionPrivacy);
|
||||||
|
ctx.CheckOwnMember(target);
|
||||||
|
|
||||||
|
var description = _description.NormalizeLineEndSpacing();
|
||||||
if (description.IsLongerThan(Limits.MaxDescriptionLength))
|
if (description.IsLongerThan(Limits.MaxDescriptionLength))
|
||||||
throw Errors.StringTooLongError("Description", description.Length, Limits.MaxDescriptionLength);
|
throw Errors.StringTooLongError("Description", description.Length, Limits.MaxDescriptionLength);
|
||||||
|
|
||||||
|
|
@ -151,20 +149,16 @@ public class MemberEdit
|
||||||
|
|
||||||
await ctx.Reply($"{Emojis.Success} Member description changed (using {description.Length}/{Limits.MaxDescriptionLength} characters).");
|
await ctx.Reply($"{Emojis.Success} Member description changed (using {description.Length}/{Limits.MaxDescriptionLength} characters).");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public async Task Pronouns(Context ctx, PKMember target)
|
public async Task ShowPronouns(Context ctx, PKMember target, ReplyFormat format)
|
||||||
{
|
{
|
||||||
|
ctx.CheckSystemPrivacy(target.System, target.PronounPrivacy);
|
||||||
|
|
||||||
var noPronounsSetMessage = "This member does not have pronouns set.";
|
var noPronounsSetMessage = "This member does not have pronouns set.";
|
||||||
if (ctx.System?.Id == target.System)
|
if (ctx.System?.Id == target.System)
|
||||||
noPronounsSetMessage += $" To set some, type `{ctx.DefaultPrefix}member {target.Reference(ctx)} pronouns <pronouns>`.";
|
noPronounsSetMessage += $" To set some, type `{ctx.DefaultPrefix}member {target.Reference(ctx)} pronouns <pronouns>`.";
|
||||||
|
|
||||||
ctx.CheckSystemPrivacy(target.System, target.PronounPrivacy);
|
if (format != ReplyFormat.Standard)
|
||||||
|
|
||||||
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.Pronouns == null)
|
if (target.Pronouns == null)
|
||||||
{
|
{
|
||||||
await ctx.Reply(noPronounsSetMessage);
|
await ctx.Reply(noPronounsSetMessage);
|
||||||
|
|
@ -184,28 +178,31 @@ public class MemberEdit
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ctx.HasNext(false))
|
|
||||||
{
|
|
||||||
await ctx.Reply(
|
await ctx.Reply(
|
||||||
$"**{target.NameFor(ctx)}**'s pronouns are **{target.Pronouns}**.\nTo print the pronouns with formatting, type `{ctx.DefaultPrefix}member {target.Reference(ctx)} pronouns -raw`."
|
$"**{target.NameFor(ctx)}**'s pronouns are **{target.Pronouns}**.\nTo print the pronouns with formatting, type `{ctx.DefaultPrefix}member {target.Reference(ctx)} pronouns -raw`."
|
||||||
+ (ctx.System?.Id == target.System
|
+ (ctx.System?.Id == target.System
|
||||||
? $" To clear them, type `{ctx.DefaultPrefix}member {target.Reference(ctx)} pronouns -clear`."
|
? $" To clear them, type `{ctx.DefaultPrefix}member {target.Reference(ctx)} pronouns -clear`."
|
||||||
+ $" Using {target.Pronouns.Length}/{Limits.MaxPronounsLength} characters."
|
+ $" Using {target.Pronouns.Length}/{Limits.MaxPronounsLength} characters."
|
||||||
: ""));
|
: ""));
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task ClearPronouns(Context ctx, PKMember target, bool confirmYes)
|
||||||
|
{
|
||||||
ctx.CheckOwnMember(target);
|
ctx.CheckOwnMember(target);
|
||||||
|
|
||||||
if (ctx.MatchClear() && await ctx.ConfirmClear("this member's pronouns"))
|
if (await ctx.ConfirmClear("this member's pronouns", confirmYes))
|
||||||
{
|
{
|
||||||
var patch = new MemberPatch { Pronouns = Partial<string>.Null() };
|
var patch = new MemberPatch { Pronouns = Partial<string>.Null() };
|
||||||
await ctx.Repository.UpdateMember(target.Id, patch);
|
await ctx.Repository.UpdateMember(target.Id, patch);
|
||||||
await ctx.Reply($"{Emojis.Success} Member pronouns cleared.");
|
await ctx.Reply($"{Emojis.Success} Member pronouns cleared.");
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
|
|
||||||
|
public async Task ChangePronouns(Context ctx, PKMember target, string pronouns)
|
||||||
{
|
{
|
||||||
var pronouns = ctx.RemainderOrNull(false).NormalizeLineEndSpacing();
|
ctx.CheckOwnMember(target);
|
||||||
|
|
||||||
|
pronouns = pronouns.NormalizeLineEndSpacing();
|
||||||
if (pronouns.IsLongerThan(Limits.MaxPronounsLength))
|
if (pronouns.IsLongerThan(Limits.MaxPronounsLength))
|
||||||
throw Errors.StringTooLongError("Pronouns", pronouns.Length, Limits.MaxPronounsLength);
|
throw Errors.StringTooLongError("Pronouns", pronouns.Length, Limits.MaxPronounsLength);
|
||||||
|
|
||||||
|
|
@ -214,22 +211,58 @@ public class MemberEdit
|
||||||
|
|
||||||
await ctx.Reply($"{Emojis.Success} Member pronouns changed (using {pronouns.Length}/{Limits.MaxPronounsLength} characters).");
|
await ctx.Reply($"{Emojis.Success} Member pronouns changed (using {pronouns.Length}/{Limits.MaxPronounsLength} characters).");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task ShowBannerImage(Context ctx, PKMember target, ReplyFormat format)
|
||||||
|
{
|
||||||
|
ctx.CheckSystemPrivacy(target.System, target.BannerPrivacy);
|
||||||
|
|
||||||
|
var noBannerSetMessage = "This member does not have a banner image set.";
|
||||||
|
if (ctx.System?.Id == target.System)
|
||||||
|
noBannerSetMessage += $" To set one, type `{ctx.DefaultPrefix}member {target.Reference(ctx)} banner <url>` or attach an image.";
|
||||||
|
|
||||||
|
if (format != ReplyFormat.Standard)
|
||||||
|
if (string.IsNullOrWhiteSpace(target.BannerImage))
|
||||||
|
{
|
||||||
|
await ctx.Reply(noBannerSetMessage);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task BannerImage(Context ctx, PKMember target)
|
if (format == ReplyFormat.Raw)
|
||||||
{
|
{
|
||||||
async Task ClearBannerImage()
|
await ctx.Reply($"```\n{target.BannerImage.TryGetCleanCdnUrl()}\n```");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (format == ReplyFormat.Plaintext)
|
||||||
|
{
|
||||||
|
var eb = new EmbedBuilder()
|
||||||
|
.Description($"Showing banner for member {target.NameFor(ctx)} (`{target.DisplayHid(ctx.Config)}`)");
|
||||||
|
await ctx.Reply(text: $"<{target.BannerImage.TryGetCleanCdnUrl()}>", embed: eb.Build());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var embed = new EmbedBuilder()
|
||||||
|
.Title($"{target.NameFor(ctx)}'s banner image")
|
||||||
|
.Image(new Embed.EmbedImage(target.BannerImage.TryGetCleanCdnUrl()));
|
||||||
|
if (target.System == ctx.System?.Id)
|
||||||
|
embed.Description($"To clear, type `{ctx.DefaultPrefix}member {target.Reference(ctx)} banner -clear`.");
|
||||||
|
await ctx.Reply(embed: embed.Build());
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task ClearBannerImage(Context ctx, PKMember target, bool confirmYes)
|
||||||
{
|
{
|
||||||
ctx.CheckOwnMember(target);
|
ctx.CheckOwnMember(target);
|
||||||
await ctx.ConfirmClear("this member's banner image");
|
|
||||||
|
|
||||||
|
if (await ctx.ConfirmClear("this member's banner image", confirmYes))
|
||||||
|
{
|
||||||
await ctx.Repository.UpdateMember(target.Id, new MemberPatch { BannerImage = null });
|
await ctx.Repository.UpdateMember(target.Id, new MemberPatch { BannerImage = null });
|
||||||
await ctx.Reply($"{Emojis.Success} Member banner image cleared.");
|
await ctx.Reply($"{Emojis.Success} Member banner image cleared.");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async Task SetBannerImage(ParsedImage img)
|
public async Task ChangeBannerImage(Context ctx, PKMember target, ParsedImage img)
|
||||||
{
|
{
|
||||||
ctx.CheckOwnMember(target);
|
ctx.CheckOwnMember(target);
|
||||||
|
|
||||||
img = await _avatarHosting.TryRehostImage(img, AvatarHostingService.RehostedImageType.Banner, ctx.Author.Id, ctx.System);
|
img = await _avatarHosting.TryRehostImage(img, AvatarHostingService.RehostedImageType.Banner, ctx.Author.Id, ctx.System);
|
||||||
await _avatarHosting.VerifyAvatarOrThrow(img.Url, true);
|
await _avatarHosting.VerifyAvatarOrThrow(img.Url, true);
|
||||||
|
|
||||||
|
|
@ -252,84 +285,57 @@ public class MemberEdit
|
||||||
: ctx.Reply(msg));
|
: ctx.Reply(msg));
|
||||||
}
|
}
|
||||||
|
|
||||||
async Task ShowBannerImage()
|
public async Task ShowColor(Context ctx, PKMember target, ReplyFormat format)
|
||||||
{
|
|
||||||
ctx.CheckSystemPrivacy(target.System, target.BannerPrivacy);
|
|
||||||
|
|
||||||
if ((target.BannerImage?.Trim() ?? "").Length > 0)
|
|
||||||
switch (ctx.MatchFormat())
|
|
||||||
{
|
|
||||||
case ReplyFormat.Raw:
|
|
||||||
await ctx.Reply($"`{target.BannerImage.TryGetCleanCdnUrl()}`");
|
|
||||||
break;
|
|
||||||
case ReplyFormat.Plaintext:
|
|
||||||
var ebP = new EmbedBuilder()
|
|
||||||
.Description($"Showing banner for member {target.NameFor(ctx)} (`{target.DisplayHid(ctx.Config)}`)");
|
|
||||||
await ctx.Reply(text: $"<{target.BannerImage.TryGetCleanCdnUrl()}>", embed: ebP.Build());
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
var ebS = new EmbedBuilder()
|
|
||||||
.Title($"{target.NameFor(ctx)}'s banner image")
|
|
||||||
.Image(new Embed.EmbedImage(target.BannerImage.TryGetCleanCdnUrl()));
|
|
||||||
if (target.System == ctx.System?.Id)
|
|
||||||
ebS.Description($"To clear, use `{ctx.DefaultPrefix}member {target.Reference(ctx)} banner clear`.");
|
|
||||||
await ctx.Reply(embed: ebS.Build());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
throw new PKSyntaxError(
|
|
||||||
"This member does not have a banner image set." + ((target.System == ctx.System?.Id) ? " Set one by attaching an image to this command, or by passing an image URL." : ""));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ctx.MatchClear())
|
|
||||||
await ClearBannerImage();
|
|
||||||
else if (await ctx.MatchImage() is { } img)
|
|
||||||
await SetBannerImage(img);
|
|
||||||
else
|
|
||||||
await ShowBannerImage();
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task Color(Context ctx, PKMember target)
|
|
||||||
{
|
|
||||||
var isOwnSystem = ctx.System?.Id == target.System;
|
|
||||||
var matchedFormat = ctx.MatchFormat();
|
|
||||||
var matchedClear = ctx.MatchClear();
|
|
||||||
|
|
||||||
if (!isOwnSystem || !(ctx.HasNext() || matchedClear))
|
|
||||||
{
|
{
|
||||||
if (target.Color == null)
|
if (target.Color == null)
|
||||||
|
{
|
||||||
await ctx.Reply(
|
await ctx.Reply(
|
||||||
"This member does not have a color set." + (isOwnSystem ? $" To set one, type `{ctx.DefaultPrefix}member {target.Reference(ctx)} color <color>`." : ""));
|
"This member does not have a color set." + (ctx.System?.Id == target.System ? $" To set one, type `{ctx.DefaultPrefix}member {target.Reference(ctx)} color <color>`." : ""));
|
||||||
else if (matchedFormat == ReplyFormat.Raw)
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (format == ReplyFormat.Raw)
|
||||||
|
{
|
||||||
await ctx.Reply("```\n#" + target.Color + "\n```");
|
await ctx.Reply("```\n#" + target.Color + "\n```");
|
||||||
else if (matchedFormat == ReplyFormat.Plaintext)
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (format == ReplyFormat.Plaintext)
|
||||||
|
{
|
||||||
await ctx.Reply(target.Color);
|
await ctx.Reply(target.Color);
|
||||||
else
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
await ctx.Reply(embed: new EmbedBuilder()
|
await ctx.Reply(embed: new EmbedBuilder()
|
||||||
.Title("Member color")
|
.Title("Member color")
|
||||||
.Color(target.Color.ToDiscordColor())
|
.Color(target.Color.ToDiscordColor())
|
||||||
.Thumbnail(new Embed.EmbedThumbnail($"attachment://color.gif"))
|
.Thumbnail(new Embed.EmbedThumbnail($"attachment://color.gif"))
|
||||||
.Description($"This member's color is **#{target.Color}**."
|
.Description($"This member's color is **#{target.Color}**."
|
||||||
+ (isOwnSystem ? $" To clear it, type `{ctx.DefaultPrefix}member {target.Reference(ctx)} color -clear`." : ""))
|
+ (ctx.System?.Id == target.System ? $" To clear it, type `{ctx.DefaultPrefix}member {target.Reference(ctx)} color -clear`." : ""))
|
||||||
.Build(),
|
.Build(),
|
||||||
files: [MiscUtils.GenerateColorPreview(target.Color)]);
|
files: [MiscUtils.GenerateColorPreview(target.Color)]);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task ClearColor(Context ctx, PKMember target, bool confirmYes)
|
||||||
|
{
|
||||||
ctx.CheckSystem().CheckOwnMember(target);
|
ctx.CheckSystem().CheckOwnMember(target);
|
||||||
|
|
||||||
if (matchedClear)
|
if (await ctx.ConfirmClear("this member's color", confirmYes))
|
||||||
{
|
{
|
||||||
await ctx.Repository.UpdateMember(target.Id, new() { Color = Partial<string>.Null() });
|
await ctx.Repository.UpdateMember(target.Id, new() { Color = Partial<string>.Null() });
|
||||||
|
|
||||||
await ctx.Reply($"{Emojis.Success} Member color cleared.");
|
await ctx.Reply($"{Emojis.Success} Member color cleared.");
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
{
|
|
||||||
var color = ctx.RemainderOrNull();
|
|
||||||
|
|
||||||
if (color.StartsWith("#")) color = color.Substring(1);
|
public async Task ChangeColor(Context ctx, PKMember target, string color)
|
||||||
if (!Regex.IsMatch(color, "^[0-9a-fA-F]{6}$")) throw Errors.InvalidColorError(color);
|
{
|
||||||
|
ctx.CheckSystem().CheckOwnMember(target);
|
||||||
|
|
||||||
|
if (color.StartsWith("#"))
|
||||||
|
color = color.Substring(1);
|
||||||
|
|
||||||
|
if (!Regex.IsMatch(color, "^[0-9a-fA-F]{6}$"))
|
||||||
|
throw Errors.InvalidColorError(color);
|
||||||
|
|
||||||
var patch = new MemberPatch { Color = Partial<string>.Present(color.ToLowerInvariant()) };
|
var patch = new MemberPatch { Color = Partial<string>.Present(color.ToLowerInvariant()) };
|
||||||
await ctx.Repository.UpdateMember(target.Id, patch);
|
await ctx.Repository.UpdateMember(target.Id, patch);
|
||||||
|
|
@ -341,39 +347,57 @@ public class MemberEdit
|
||||||
.Build(),
|
.Build(),
|
||||||
files: [MiscUtils.GenerateColorPreview(color)]);
|
files: [MiscUtils.GenerateColorPreview(color)]);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public async Task Birthday(Context ctx, PKMember target)
|
public async Task ShowBirthday(Context ctx, PKMember target, ReplyFormat format)
|
||||||
{
|
|
||||||
if (ctx.MatchClear() && await ctx.ConfirmClear("this member's birthday"))
|
|
||||||
{
|
|
||||||
ctx.CheckOwnMember(target);
|
|
||||||
|
|
||||||
var patch = new MemberPatch { Birthday = Partial<LocalDate?>.Null() };
|
|
||||||
await ctx.Repository.UpdateMember(target.Id, patch);
|
|
||||||
|
|
||||||
await ctx.Reply($"{Emojis.Success} Member birthdate cleared.");
|
|
||||||
}
|
|
||||||
else if (!ctx.HasNext())
|
|
||||||
{
|
{
|
||||||
ctx.CheckSystemPrivacy(target.System, target.BirthdayPrivacy);
|
ctx.CheckSystemPrivacy(target.System, target.BirthdayPrivacy);
|
||||||
|
|
||||||
|
var noBirthdaySetMessage = "This member does not have a birthdate set.";
|
||||||
|
if (ctx.System?.Id == target.System)
|
||||||
|
noBirthdaySetMessage += $" To set one, type `{ctx.DefaultPrefix}member {target.Reference(ctx)} birthday <birthdate>`.";
|
||||||
|
|
||||||
|
// if what's next is "raw"/"plaintext" we need to check for null
|
||||||
|
if (format != ReplyFormat.Standard)
|
||||||
if (target.Birthday == null)
|
if (target.Birthday == null)
|
||||||
await ctx.Reply("This member does not have a birthdate set."
|
{
|
||||||
+ (ctx.System?.Id == target.System
|
await ctx.Reply(noBirthdaySetMessage);
|
||||||
? $" To set one, type `{ctx.DefaultPrefix}member {target.Reference(ctx)} birthdate <birthdate>`."
|
return;
|
||||||
: ""));
|
}
|
||||||
else
|
|
||||||
|
if (format == ReplyFormat.Raw)
|
||||||
|
{
|
||||||
|
await ctx.Reply($"```\n{target.Birthday}\n```");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (format == ReplyFormat.Plaintext)
|
||||||
|
{
|
||||||
|
var eb = new EmbedBuilder()
|
||||||
|
.Description($"Showing birthday for member {target.NameFor(ctx)} (`{target.DisplayHid(ctx.Config)}`)");
|
||||||
|
await ctx.Reply(target.BirthdayString, embed: eb.Build());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
await ctx.Reply($"This member's birthdate is **{target.BirthdayString}**."
|
await ctx.Reply($"This member's birthdate is **{target.BirthdayString}**."
|
||||||
+ (ctx.System?.Id == target.System
|
+ (ctx.System?.Id == target.System
|
||||||
? $" To clear it, type `{ctx.DefaultPrefix}member {target.Reference(ctx)} birthdate -clear`."
|
? $" To clear it, type `{ctx.DefaultPrefix}member {target.Reference(ctx)} birthday -clear`."
|
||||||
: ""));
|
: ""));
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
public async Task ClearBirthday(Context ctx, PKMember target, bool confirmYes)
|
||||||
{
|
{
|
||||||
ctx.CheckOwnMember(target);
|
ctx.CheckOwnMember(target);
|
||||||
|
|
||||||
var birthdayStr = ctx.RemainderOrNull();
|
if (await ctx.ConfirmClear("this member's birthday", confirmYes))
|
||||||
|
{
|
||||||
|
var patch = new MemberPatch { Birthday = Partial<LocalDate?>.Null() };
|
||||||
|
await ctx.Repository.UpdateMember(target.Id, patch);
|
||||||
|
await ctx.Reply($"{Emojis.Success} Member birthdate cleared.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task ChangeBirthday(Context ctx, PKMember target, string birthdayStr)
|
||||||
|
{
|
||||||
|
ctx.CheckOwnMember(target);
|
||||||
|
|
||||||
LocalDate? birthday;
|
LocalDate? birthday;
|
||||||
if (birthdayStr == "today" || birthdayStr == "now")
|
if (birthdayStr == "today" || birthdayStr == "now")
|
||||||
|
|
@ -381,14 +405,14 @@ public class MemberEdit
|
||||||
else
|
else
|
||||||
birthday = DateUtils.ParseDate(birthdayStr, true);
|
birthday = DateUtils.ParseDate(birthdayStr, true);
|
||||||
|
|
||||||
if (birthday == null) throw Errors.BirthdayParseError(birthdayStr);
|
if (birthday == null)
|
||||||
|
throw Errors.BirthdayParseError(birthdayStr);
|
||||||
|
|
||||||
var patch = new MemberPatch { Birthday = Partial<LocalDate?>.Present(birthday) };
|
var patch = new MemberPatch { Birthday = Partial<LocalDate?>.Present(birthday) };
|
||||||
await ctx.Repository.UpdateMember(target.Id, patch);
|
await ctx.Repository.UpdateMember(target.Id, patch);
|
||||||
|
|
||||||
await ctx.Reply($"{Emojis.Success} Member birthdate changed.");
|
await ctx.Reply($"{Emojis.Success} Member birthdate changed.");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private string boldIf(string str, bool condition) => condition ? $"**{str}**" : str;
|
private string boldIf(string str, bool condition) => condition ? $"**{str}**" : str;
|
||||||
|
|
||||||
|
|
@ -429,33 +453,14 @@ public class MemberEdit
|
||||||
return eb;
|
return eb;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task DisplayName(Context ctx, PKMember target)
|
public async Task ShowDisplayName(Context ctx, PKMember target, ReplyFormat format)
|
||||||
{
|
{
|
||||||
async Task PrintSuccess(string text)
|
|
||||||
{
|
|
||||||
var successStr = text;
|
|
||||||
if (ctx.Guild != null)
|
|
||||||
{
|
|
||||||
var memberGuildConfig = await ctx.Repository.GetMemberGuild(ctx.Guild.Id, target.Id);
|
|
||||||
if (memberGuildConfig.DisplayName != null)
|
|
||||||
successStr +=
|
|
||||||
$" However, this member has a server name set in this server ({ctx.Guild.Name}), and will be proxied using that name, \"{memberGuildConfig.DisplayName}\", here.";
|
|
||||||
}
|
|
||||||
|
|
||||||
await ctx.Reply(successStr);
|
|
||||||
}
|
|
||||||
|
|
||||||
var isOwner = ctx.System?.Id == target.System;
|
var isOwner = ctx.System?.Id == target.System;
|
||||||
var noDisplayNameSetMessage = $"This member does not have a display name set{(isOwner ? "" : " or name is private")}."
|
var noDisplayNameSetMessage = $"This member does not have a display name set{(isOwner ? "" : " or name is private")}."
|
||||||
+ (isOwner ? $" To set one, type `{ctx.DefaultPrefix}member {target.Reference(ctx)} displayname <display name>`." : "");
|
+ (isOwner ? $" To set one, type `{ctx.DefaultPrefix}member {target.Reference(ctx)} displayname <display name>`." : "");
|
||||||
|
|
||||||
// Whether displayname is shown or not should depend on if member name privacy is set.
|
// Whether displayname is shown or not should depend on if member name privacy is set.
|
||||||
// If name privacy is on then displayname should look like name.
|
// If name privacy is on then displayname should look like name.
|
||||||
|
|
||||||
var format = ctx.MatchFormat();
|
|
||||||
|
|
||||||
// if what's next is "raw"/"plaintext" we need to check for null
|
|
||||||
if (format != ReplyFormat.Standard)
|
|
||||||
if (target.DisplayName == null || !target.NamePrivacy.CanAccess(ctx.DirectLookupContextFor(target.System)))
|
if (target.DisplayName == null || !target.NamePrivacy.CanAccess(ctx.DirectLookupContextFor(target.System)))
|
||||||
{
|
{
|
||||||
await ctx.Reply(noDisplayNameSetMessage);
|
await ctx.Reply(noDisplayNameSetMessage);
|
||||||
|
|
@ -469,14 +474,12 @@ public class MemberEdit
|
||||||
}
|
}
|
||||||
if (format == ReplyFormat.Plaintext)
|
if (format == ReplyFormat.Plaintext)
|
||||||
{
|
{
|
||||||
var eb = new EmbedBuilder()
|
var _eb = new EmbedBuilder()
|
||||||
.Description($"Showing displayname for member {target.NameFor(ctx)} (`{target.DisplayHid(ctx.Config)}`)");
|
.Description($"Showing displayname for member {target.NameFor(ctx)} (`{target.DisplayHid(ctx.Config)}`)");
|
||||||
await ctx.Reply(target.DisplayName, embed: eb.Build());
|
await ctx.Reply(target.DisplayName, embed: _eb.Build());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ctx.HasNext(false))
|
|
||||||
{
|
|
||||||
var eb = await CreateMemberNameInfoEmbed(ctx, target);
|
var eb = await CreateMemberNameInfoEmbed(ctx, target);
|
||||||
var reference = target.Reference(ctx);
|
var reference = target.Reference(ctx);
|
||||||
if (ctx.System?.Id == target.System)
|
if (ctx.System?.Id == target.System)
|
||||||
|
|
@ -485,38 +488,59 @@ public class MemberEdit
|
||||||
+ $"To clear it, type `{ctx.DefaultPrefix}member {reference} displayname -clear`.\n"
|
+ $"To clear it, type `{ctx.DefaultPrefix}member {reference} displayname -clear`.\n"
|
||||||
+ $"To print the raw display name, type `{ctx.DefaultPrefix}member {reference} displayname -raw`.");
|
+ $"To print the raw display name, type `{ctx.DefaultPrefix}member {reference} displayname -raw`.");
|
||||||
await ctx.Reply(embed: eb.Build());
|
await ctx.Reply(embed: eb.Build());
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task ClearDisplayName(Context ctx, PKMember target, bool confirmYes)
|
||||||
|
{
|
||||||
ctx.CheckOwnMember(target);
|
ctx.CheckOwnMember(target);
|
||||||
|
|
||||||
if (ctx.MatchClear() && await ctx.ConfirmClear("this member's display name"))
|
if (await ctx.ConfirmClear("this member's display name", confirmYes))
|
||||||
{
|
{
|
||||||
var patch = new MemberPatch { DisplayName = Partial<string>.Null() };
|
var patch = new MemberPatch { DisplayName = Partial<string>.Null() };
|
||||||
await ctx.Repository.UpdateMember(target.Id, patch);
|
await ctx.Repository.UpdateMember(target.Id, patch);
|
||||||
|
|
||||||
await PrintSuccess(
|
var successStr = $"{Emojis.Success} Member display name cleared. This member will now be proxied using their member name \"{target.Name}\".";
|
||||||
$"{Emojis.Success} Member display name cleared. This member will now be proxied using their member name \"{target.Name}\".");
|
|
||||||
|
if (ctx.Guild != null)
|
||||||
|
{
|
||||||
|
var memberGuildConfig = await ctx.Repository.GetMemberGuild(ctx.Guild.Id, target.Id);
|
||||||
|
if (memberGuildConfig.DisplayName != null)
|
||||||
|
successStr +=
|
||||||
|
$" However, this member has a server name set in this server ({ctx.Guild.Name}), and will be proxied using that name, \"{memberGuildConfig.DisplayName}\", here.";
|
||||||
|
}
|
||||||
|
|
||||||
|
await ctx.Reply(successStr);
|
||||||
|
|
||||||
if (target.NamePrivacy == PrivacyLevel.Private)
|
if (target.NamePrivacy == PrivacyLevel.Private)
|
||||||
await ctx.Reply($"{Emojis.Warn} Since this member no longer has a display name set, their name privacy **can no longer take effect**.");
|
await ctx.Reply($"{Emojis.Warn} Since this member no longer has a display name set, their name privacy **can no longer take effect**.");
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
{
|
|
||||||
var newDisplayName = ctx.RemainderOrNull(false).NormalizeLineEndSpacing();
|
|
||||||
|
|
||||||
|
public async Task ChangeDisplayName(Context ctx, PKMember target, string newDisplayName)
|
||||||
|
{
|
||||||
|
ctx.CheckOwnMember(target);
|
||||||
|
|
||||||
|
newDisplayName = newDisplayName.NormalizeLineEndSpacing();
|
||||||
if (newDisplayName.Length > Limits.MaxMemberNameLength)
|
if (newDisplayName.Length > Limits.MaxMemberNameLength)
|
||||||
throw Errors.StringTooLongError("Member display name", newDisplayName.Length, Limits.MaxMemberNameLength);
|
throw Errors.StringTooLongError("Member display name", newDisplayName.Length, Limits.MaxMemberNameLength);
|
||||||
|
|
||||||
var patch = new MemberPatch { DisplayName = Partial<string>.Present(newDisplayName) };
|
var patch = new MemberPatch { DisplayName = Partial<string>.Present(newDisplayName) };
|
||||||
await ctx.Repository.UpdateMember(target.Id, patch);
|
await ctx.Repository.UpdateMember(target.Id, patch);
|
||||||
|
|
||||||
await PrintSuccess(
|
var successStr = $"{Emojis.Success} Member display name changed (using {newDisplayName.Length}/{Limits.MaxMemberNameLength} characters). This member will now be proxied using the name \"{newDisplayName}\".";
|
||||||
$"{Emojis.Success} Member display name changed (using {newDisplayName.Length}/{Limits.MaxMemberNameLength} characters). This member will now be proxied using the name \"{newDisplayName}\".");
|
|
||||||
}
|
if (ctx.Guild != null)
|
||||||
|
{
|
||||||
|
var memberGuildConfig = await ctx.Repository.GetMemberGuild(ctx.Guild.Id, target.Id);
|
||||||
|
if (memberGuildConfig.DisplayName != null)
|
||||||
|
successStr +=
|
||||||
|
$" However, this member has a server name set in this server ({ctx.Guild.Name}), and will be proxied using that name, \"{memberGuildConfig.DisplayName}\", here.";
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task ServerName(Context ctx, PKMember target)
|
await ctx.Reply(successStr);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task ShowServerName(Context ctx, PKMember target, ReplyFormat format)
|
||||||
{
|
{
|
||||||
ctx.CheckGuildContext();
|
ctx.CheckGuildContext();
|
||||||
|
|
||||||
|
|
@ -525,12 +549,8 @@ public class MemberEdit
|
||||||
noServerNameSetMessage +=
|
noServerNameSetMessage +=
|
||||||
$" To set one, type `{ctx.DefaultPrefix}member {target.Reference(ctx)} servername <server name>`.";
|
$" To set one, type `{ctx.DefaultPrefix}member {target.Reference(ctx)} servername <server name>`.";
|
||||||
|
|
||||||
// No perms check, display name isn't covered by member privacy
|
|
||||||
var memberGuildConfig = await ctx.Repository.GetMemberGuild(ctx.Guild.Id, target.Id);
|
var memberGuildConfig = await ctx.Repository.GetMemberGuild(ctx.Guild.Id, target.Id);
|
||||||
|
|
||||||
var format = ctx.MatchFormat();
|
|
||||||
|
|
||||||
// if what's next is "raw"/"plaintext" we need to check for null
|
|
||||||
if (format != ReplyFormat.Standard)
|
if (format != ReplyFormat.Standard)
|
||||||
if (memberGuildConfig.DisplayName == null)
|
if (memberGuildConfig.DisplayName == null)
|
||||||
{
|
{
|
||||||
|
|
@ -545,26 +565,26 @@ public class MemberEdit
|
||||||
}
|
}
|
||||||
if (format == ReplyFormat.Plaintext)
|
if (format == ReplyFormat.Plaintext)
|
||||||
{
|
{
|
||||||
var eb = new EmbedBuilder()
|
var _eb = new EmbedBuilder()
|
||||||
.Description($"Showing servername for member {target.NameFor(ctx)} (`{target.DisplayHid(ctx.Config)}`)");
|
.Description($"Showing servername for member {target.NameFor(ctx)} (`{target.DisplayHid(ctx.Config)}`)");
|
||||||
await ctx.Reply(memberGuildConfig.DisplayName, embed: eb.Build());
|
await ctx.Reply(memberGuildConfig.DisplayName, embed: _eb.Build());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ctx.HasNext(false))
|
|
||||||
{
|
|
||||||
var eb = await CreateMemberNameInfoEmbed(ctx, target);
|
var eb = await CreateMemberNameInfoEmbed(ctx, target);
|
||||||
var reference = target.Reference(ctx);
|
var reference = target.Reference(ctx);
|
||||||
if (ctx.System?.Id == target.System)
|
if (ctx.System?.Id == target.System)
|
||||||
eb.Description(
|
eb.Description(
|
||||||
$"To change server name, type `{ctx.DefaultPrefix}member {reference} servername <server name>`.\nTo clear it, type `{ctx.DefaultPrefix}member {reference} servername -clear`.\nTo print the raw server name, type `{ctx.DefaultPrefix}member {reference} servername -raw`.");
|
$"To change server name, type `{ctx.DefaultPrefix}member {reference} servername <server name>`.\nTo clear it, type `{ctx.DefaultPrefix}member {reference} servername -clear`.\nTo print the raw server name, type `{ctx.DefaultPrefix}member {reference} servername -raw`.");
|
||||||
await ctx.Reply(embed: eb.Build());
|
await ctx.Reply(embed: eb.Build());
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task ClearServerName(Context ctx, PKMember target, bool confirmYes)
|
||||||
|
{
|
||||||
|
ctx.CheckGuildContext();
|
||||||
ctx.CheckOwnMember(target);
|
ctx.CheckOwnMember(target);
|
||||||
|
|
||||||
if (ctx.MatchClear() && await ctx.ConfirmClear("this member's server name"))
|
if (await ctx.ConfirmClear("this member's server name", confirmYes))
|
||||||
{
|
{
|
||||||
await ctx.Repository.UpdateMemberGuild(target.Id, ctx.Guild.Id, new MemberGuildPatch { DisplayName = null });
|
await ctx.Repository.UpdateMemberGuild(target.Id, ctx.Guild.Id, new MemberGuildPatch { DisplayName = null });
|
||||||
|
|
||||||
|
|
@ -575,9 +595,16 @@ public class MemberEdit
|
||||||
await ctx.Reply(
|
await ctx.Reply(
|
||||||
$"{Emojis.Success} Member server name cleared. This member will now be proxied using their member name \"{target.NameFor(ctx)}\" in this server ({ctx.Guild.Name}).");
|
$"{Emojis.Success} Member server name cleared. This member will now be proxied using their member name \"{target.NameFor(ctx)}\" in this server ({ctx.Guild.Name}).");
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
|
|
||||||
|
public async Task ChangeServerName(Context ctx, PKMember target, string newServerName)
|
||||||
{
|
{
|
||||||
var newServerName = ctx.RemainderOrNull(false).NormalizeLineEndSpacing();
|
ctx.CheckGuildContext();
|
||||||
|
ctx.CheckOwnMember(target);
|
||||||
|
|
||||||
|
newServerName = newServerName.NormalizeLineEndSpacing();
|
||||||
|
if (newServerName.Length > Limits.MaxMemberNameLength)
|
||||||
|
throw Errors.StringTooLongError("Server name", newServerName.Length, Limits.MaxMemberNameLength);
|
||||||
|
|
||||||
await ctx.Repository.UpdateMemberGuild(target.Id, ctx.Guild.Id,
|
await ctx.Repository.UpdateMemberGuild(target.Id, ctx.Guild.Id,
|
||||||
new MemberGuildPatch { DisplayName = newServerName });
|
new MemberGuildPatch { DisplayName = newServerName });
|
||||||
|
|
@ -585,31 +612,8 @@ public class MemberEdit
|
||||||
await ctx.Reply(
|
await ctx.Reply(
|
||||||
$"{Emojis.Success} Member server name changed (using {newServerName.Length}/{Limits.MaxMemberNameLength} characters). This member will now be proxied using the name \"{newServerName}\" in this server ({ctx.Guild.Name}).");
|
$"{Emojis.Success} Member server name changed (using {newServerName.Length}/{Limits.MaxMemberNameLength} characters). This member will now be proxied using the name \"{newServerName}\" in this server ({ctx.Guild.Name}).");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public async Task KeepProxy(Context ctx, PKMember target)
|
public async Task ShowKeepProxy(Context ctx, PKMember target)
|
||||||
{
|
|
||||||
ctx.CheckSystem().CheckOwnMember(target);
|
|
||||||
MemberGuildSettings? memberGuildConfig = null;
|
|
||||||
if (ctx.Guild != null)
|
|
||||||
{
|
|
||||||
memberGuildConfig = await ctx.Repository.GetMemberGuild(ctx.Guild.Id, target.Id);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool newValue;
|
|
||||||
if (ctx.Match("on", "enabled", "true", "yes"))
|
|
||||||
{
|
|
||||||
newValue = true;
|
|
||||||
}
|
|
||||||
else if (ctx.Match("off", "disabled", "false", "no"))
|
|
||||||
{
|
|
||||||
newValue = false;
|
|
||||||
}
|
|
||||||
else if (ctx.HasNext())
|
|
||||||
{
|
|
||||||
throw new PKSyntaxError("You must pass either \"on\" or \"off\".");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
string keepProxyStatusMessage = "";
|
string keepProxyStatusMessage = "";
|
||||||
|
|
||||||
|
|
@ -618,16 +622,25 @@ public class MemberEdit
|
||||||
else
|
else
|
||||||
keepProxyStatusMessage += "This member has keepproxy **disabled**. Proxy tags will **not** be included in the resulting message when proxying.";
|
keepProxyStatusMessage += "This member has keepproxy **disabled**. Proxy tags will **not** be included in the resulting message when proxying.";
|
||||||
|
|
||||||
if (memberGuildConfig != null && memberGuildConfig.KeepProxy.HasValue && memberGuildConfig.KeepProxy.Value)
|
if (ctx.Guild != null)
|
||||||
keepProxyStatusMessage += $"\n{Emojis.Warn} This member has keepproxy **enabled in this server**, which means proxy tags will **always** be included when proxying in this server, regardless of the global keepproxy. To clear this setting in this server, type `{ctx.DefaultPrefix}m <member> serverkeepproxy clear`.";
|
{
|
||||||
else if (memberGuildConfig != null && memberGuildConfig.KeepProxy.HasValue && !memberGuildConfig.KeepProxy.Value)
|
var memberGuildConfig = await ctx.Repository.GetMemberGuild(ctx.Guild.Id, target.Id);
|
||||||
keepProxyStatusMessage += $"\n{Emojis.Warn} This member has keepproxy **disabled in this server**, which means proxy tags will **never** be included when proxying in this server, regardless of the global keepproxy. To clear this setting in this server, type `{ctx.DefaultPrefix}m <member> serverkeepproxy clear`.";
|
|
||||||
|
|
||||||
await ctx.Reply(keepProxyStatusMessage);
|
if (memberGuildConfig?.KeepProxy.HasValue == true)
|
||||||
return;
|
{
|
||||||
|
if (memberGuildConfig.KeepProxy.Value)
|
||||||
|
keepProxyStatusMessage += $"\n{Emojis.Warn} This member has keepproxy **enabled in this server**, which means proxy tags will **always** be included when proxying in this server, regardless of the global keepproxy. To clear this setting in this server, type `{ctx.DefaultPrefix}m <member> serverkeepproxy clear`.";
|
||||||
|
else
|
||||||
|
keepProxyStatusMessage += $"\n{Emojis.Warn} This member has keepproxy **disabled in this server**, which means proxy tags will **never** be included when proxying in this server, regardless of the global keepproxy. To clear this setting in this server, type `{ctx.DefaultPrefix}m <member> serverkeepproxy clear`.";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
;
|
await ctx.Reply(keepProxyStatusMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task ChangeKeepProxy(Context ctx, PKMember target, bool newValue)
|
||||||
|
{
|
||||||
|
ctx.CheckSystem().CheckOwnMember(target);
|
||||||
|
|
||||||
var patch = new MemberPatch { KeepProxy = Partial<bool>.Present(newValue) };
|
var patch = new MemberPatch { KeepProxy = Partial<bool>.Present(newValue) };
|
||||||
await ctx.Repository.UpdateMember(target.Id, patch);
|
await ctx.Repository.UpdateMember(target.Id, patch);
|
||||||
|
|
@ -639,47 +652,35 @@ public class MemberEdit
|
||||||
else
|
else
|
||||||
keepProxyUpdateMessage += $"{Emojis.Success} this member now has keepproxy **disabled**. Member proxy tags will **not** be included in the resulting message when proxying.";
|
keepProxyUpdateMessage += $"{Emojis.Success} this member now has keepproxy **disabled**. Member proxy tags will **not** be included in the resulting message when proxying.";
|
||||||
|
|
||||||
if (memberGuildConfig != null && memberGuildConfig.KeepProxy.HasValue && memberGuildConfig.KeepProxy.Value)
|
if (ctx.Guild != null)
|
||||||
|
{
|
||||||
|
var memberGuildConfig = await ctx.Repository.GetMemberGuild(ctx.Guild.Id, target.Id);
|
||||||
|
|
||||||
|
if (memberGuildConfig?.KeepProxy.HasValue == true)
|
||||||
|
{
|
||||||
|
if (memberGuildConfig.KeepProxy.Value)
|
||||||
keepProxyUpdateMessage += $"\n{Emojis.Warn} This member has keepproxy **enabled in this server**, which means proxy tags will **always** be included when proxying in this server, regardless of the global keepproxy. To clear this setting in this server, type `{ctx.DefaultPrefix}m <member> serverkeepproxy clear`.";
|
keepProxyUpdateMessage += $"\n{Emojis.Warn} This member has keepproxy **enabled in this server**, which means proxy tags will **always** be included when proxying in this server, regardless of the global keepproxy. To clear this setting in this server, type `{ctx.DefaultPrefix}m <member> serverkeepproxy clear`.";
|
||||||
else if (memberGuildConfig != null && memberGuildConfig.KeepProxy.HasValue && !memberGuildConfig.KeepProxy.Value)
|
else
|
||||||
keepProxyUpdateMessage += $"\n{Emojis.Warn} This member has keepproxy **disabled in this server**, which means proxy tags will **never** be included when proxying in this server, regardless of the global keepproxy. To clear this setting in this server, type `{ctx.DefaultPrefix}m <member> serverkeepproxy clear`.";
|
keepProxyUpdateMessage += $"\n{Emojis.Warn} This member has keepproxy **disabled in this server**, which means proxy tags will **never** be included when proxying in this server, regardless of the global keepproxy. To clear this setting in this server, type `{ctx.DefaultPrefix}m <member> serverkeepproxy clear`.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
await ctx.Reply(keepProxyUpdateMessage);
|
await ctx.Reply(keepProxyUpdateMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task ServerKeepProxy(Context ctx, PKMember target)
|
public async Task ShowServerKeepProxy(Context ctx, PKMember target)
|
||||||
{
|
{
|
||||||
ctx.CheckGuildContext();
|
ctx.CheckGuildContext();
|
||||||
ctx.CheckSystem().CheckOwnMember(target);
|
|
||||||
|
|
||||||
var memberGuildConfig = await ctx.Repository.GetMemberGuild(ctx.Guild.Id, target.Id);
|
var memberGuildConfig = await ctx.Repository.GetMemberGuild(ctx.Guild.Id, target.Id);
|
||||||
|
|
||||||
bool? newValue;
|
|
||||||
if (ctx.Match("on", "enabled", "true", "yes"))
|
|
||||||
{
|
|
||||||
newValue = true;
|
|
||||||
}
|
|
||||||
else if (ctx.Match("off", "disabled", "false", "no"))
|
|
||||||
{
|
|
||||||
newValue = false;
|
|
||||||
}
|
|
||||||
else if (ctx.MatchClear())
|
|
||||||
{
|
|
||||||
newValue = null;
|
|
||||||
}
|
|
||||||
else if (ctx.HasNext())
|
|
||||||
{
|
|
||||||
throw new PKSyntaxError("You must pass either \"on\", \"off\" or \"clear\".");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (memberGuildConfig.KeepProxy.HasValue)
|
if (memberGuildConfig.KeepProxy.HasValue)
|
||||||
|
{
|
||||||
if (memberGuildConfig.KeepProxy.Value)
|
if (memberGuildConfig.KeepProxy.Value)
|
||||||
await ctx.Reply(
|
await ctx.Reply($"This member has keepproxy **enabled** in the current server, which means proxy tags will be **included** in the resulting message when proxying. To clear this setting in this server, type `{ctx.DefaultPrefix}m <member> serverkeepproxy clear`.");
|
||||||
$"This member has keepproxy **enabled** in the current server, which means proxy tags will be **included** in the resulting message when proxying. To clear this setting in this server, type `{ctx.DefaultPrefix}m <member> serverkeepproxy clear`.");
|
|
||||||
else
|
else
|
||||||
await ctx.Reply(
|
await ctx.Reply($"This member has keepproxy **disabled** in the current server, which means proxy tags will **not** be included in the resulting message when proxying. To clear this setting in this server, type `{ctx.DefaultPrefix}m <member> serverkeepproxy clear`.");
|
||||||
$"This member has keepproxy **disabled** in the current server, which means proxy tags will **not** be included in the resulting message when proxying. To clear this setting in this server, type `{ctx.DefaultPrefix}m <member> serverkeepproxy clear`.");
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var noServerKeepProxySetMessage = "This member does not have a server keepproxy override set.";
|
var noServerKeepProxySetMessage = "This member does not have a server keepproxy override set.";
|
||||||
|
|
@ -690,23 +691,19 @@ public class MemberEdit
|
||||||
|
|
||||||
await ctx.Reply(noServerKeepProxySetMessage);
|
await ctx.Reply(noServerKeepProxySetMessage);
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var patch = new MemberGuildPatch { KeepProxy = Partial<bool?>.Present(newValue) };
|
public async Task ClearServerKeepProxy(Context ctx, PKMember target, bool confirmYes)
|
||||||
|
{
|
||||||
|
ctx.CheckGuildContext();
|
||||||
|
ctx.CheckSystem().CheckOwnMember(target);
|
||||||
|
|
||||||
|
if (await ctx.ConfirmClear("this member's server keepproxy setting", confirmYes))
|
||||||
|
{
|
||||||
|
var patch = new MemberGuildPatch { KeepProxy = Partial<bool?>.Present(null) };
|
||||||
await ctx.Repository.UpdateMemberGuild(target.Id, ctx.Guild.Id, patch);
|
await ctx.Repository.UpdateMemberGuild(target.Id, ctx.Guild.Id, patch);
|
||||||
|
|
||||||
if (newValue.HasValue)
|
|
||||||
if (newValue.Value)
|
|
||||||
await ctx.Reply(
|
|
||||||
$"{Emojis.Success} Member proxy tags will now be **included** in the resulting message when proxying **in the current server**. To clear this setting in this server, type `{ctx.DefaultPrefix}m <member> serverkeepproxy clear`.");
|
|
||||||
else
|
|
||||||
await ctx.Reply(
|
|
||||||
$"{Emojis.Success} Member proxy tags will now **not** be included in the resulting message when proxying **in the current server**. To clear this setting in this server, type `{ctx.DefaultPrefix}m <member> serverkeepproxy clear`.");
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var serverKeepProxyClearedMessage = $"{Emojis.Success} Cleared server keepproxy settings for this member.";
|
var serverKeepProxyClearedMessage = $"{Emojis.Success} Cleared server keepproxy settings for this member.";
|
||||||
|
|
||||||
if (target.KeepProxy)
|
if (target.KeepProxy)
|
||||||
serverKeepProxyClearedMessage += " Member proxy tags will now be **included** in the resulting message when proxying.";
|
serverKeepProxyClearedMessage += " Member proxy tags will now be **included** in the resulting message when proxying.";
|
||||||
else
|
else
|
||||||
|
|
@ -716,24 +713,21 @@ public class MemberEdit
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task Tts(Context ctx, PKMember target)
|
public async Task ChangeServerKeepProxy(Context ctx, PKMember target, bool newValue)
|
||||||
{
|
{
|
||||||
|
ctx.CheckGuildContext();
|
||||||
ctx.CheckSystem().CheckOwnMember(target);
|
ctx.CheckSystem().CheckOwnMember(target);
|
||||||
|
|
||||||
bool newValue;
|
var patch = new MemberGuildPatch { KeepProxy = Partial<bool?>.Present(newValue) };
|
||||||
if (ctx.Match("on", "enabled", "true", "yes"))
|
await ctx.Repository.UpdateMemberGuild(target.Id, ctx.Guild.Id, patch);
|
||||||
{
|
|
||||||
newValue = true;
|
if (newValue)
|
||||||
}
|
await ctx.Reply($"{Emojis.Success} Member proxy tags will now be **included** in the resulting message when proxying **in the current server**. To clear this setting in this server, type `{ctx.DefaultPrefix}m <member> serverkeepproxy clear`.");
|
||||||
else if (ctx.Match("off", "disabled", "false", "no"))
|
|
||||||
{
|
|
||||||
newValue = false;
|
|
||||||
}
|
|
||||||
else if (ctx.HasNext())
|
|
||||||
{
|
|
||||||
throw new PKSyntaxError("You must pass either \"on\" or \"off\".");
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
|
await ctx.Reply($"{Emojis.Success} Member proxy tags will now **not** be included in the resulting message when proxying **in the current server**. To clear this setting in this server, type `{ctx.DefaultPrefix}m <member> serverkeepproxy clear`.");
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task ShowTts(Context ctx, PKMember target)
|
||||||
{
|
{
|
||||||
if (target.Tts)
|
if (target.Tts)
|
||||||
await ctx.Reply(
|
await ctx.Reply(
|
||||||
|
|
@ -741,10 +735,11 @@ public class MemberEdit
|
||||||
else
|
else
|
||||||
await ctx.Reply(
|
await ctx.Reply(
|
||||||
"This member has text-to-speech **disabled**, which means their messages **will not** be sent as text-to-speech messages.");
|
"This member has text-to-speech **disabled**, which means their messages **will not** be sent as text-to-speech messages.");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
;
|
public async Task ChangeTts(Context ctx, PKMember target, bool newValue)
|
||||||
|
{
|
||||||
|
ctx.CheckSystem().CheckOwnMember(target);
|
||||||
|
|
||||||
var patch = new MemberPatch { Tts = Partial<bool>.Present(newValue) };
|
var patch = new MemberPatch { Tts = Partial<bool>.Present(newValue) };
|
||||||
await ctx.Repository.UpdateMember(target.Id, patch);
|
await ctx.Repository.UpdateMember(target.Id, patch);
|
||||||
|
|
@ -757,12 +752,7 @@ public class MemberEdit
|
||||||
$"{Emojis.Success} Member messages will no longer be sent as text-to-speech messages.");
|
$"{Emojis.Success} Member messages will no longer be sent as text-to-speech messages.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task MemberAutoproxy(Context ctx, PKMember target)
|
public async Task ShowAutoproxy(Context ctx, PKMember target)
|
||||||
{
|
|
||||||
if (ctx.System == null) throw Errors.NoSystemError(ctx.DefaultPrefix);
|
|
||||||
if (target.System != ctx.System.Id) throw Errors.NotOwnMemberError;
|
|
||||||
|
|
||||||
if (!ctx.HasNext())
|
|
||||||
{
|
{
|
||||||
if (target.AllowAutoproxy)
|
if (target.AllowAutoproxy)
|
||||||
await ctx.Reply(
|
await ctx.Reply(
|
||||||
|
|
@ -770,10 +760,11 @@ public class MemberEdit
|
||||||
else
|
else
|
||||||
await ctx.Reply(
|
await ctx.Reply(
|
||||||
"Latch/front autoproxy are **disabled** for this member. This member will not be automatically proxied when autoproxy is set to latch or front mode.");
|
"Latch/front autoproxy are **disabled** for this member. This member will not be automatically proxied when autoproxy is set to latch or front mode.");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var newValue = ctx.MatchToggle();
|
public async Task ChangeAutoproxy(Context ctx, PKMember target, bool newValue)
|
||||||
|
{
|
||||||
|
ctx.CheckSystem().CheckOwnMember(target);
|
||||||
|
|
||||||
var patch = new MemberPatch { AllowAutoproxy = Partial<bool>.Present(newValue) };
|
var patch = new MemberPatch { AllowAutoproxy = Partial<bool>.Present(newValue) };
|
||||||
await ctx.Repository.UpdateMember(target.Id, patch);
|
await ctx.Repository.UpdateMember(target.Id, patch);
|
||||||
|
|
@ -784,12 +775,7 @@ public class MemberEdit
|
||||||
await ctx.Reply($"{Emojis.Success} Latch / front autoproxy have been **disabled** for this member.");
|
await ctx.Reply($"{Emojis.Success} Latch / front autoproxy have been **disabled** for this member.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task Privacy(Context ctx, PKMember target, PrivacyLevel? newValueFromCommand)
|
public async Task ShowPrivacy(Context ctx, PKMember target)
|
||||||
{
|
|
||||||
ctx.CheckSystem().CheckOwnMember(target);
|
|
||||||
|
|
||||||
// Display privacy settings
|
|
||||||
if (!ctx.HasNext() && newValueFromCommand == null)
|
|
||||||
{
|
{
|
||||||
await ctx.Reply(embed: new EmbedBuilder()
|
await ctx.Reply(embed: new EmbedBuilder()
|
||||||
.Title($"Current privacy settings for {target.NameFor(ctx)}")
|
.Title($"Current privacy settings for {target.NameFor(ctx)}")
|
||||||
|
|
@ -807,16 +793,12 @@ public class MemberEdit
|
||||||
.Description(
|
.Description(
|
||||||
$"To edit privacy settings, use the command:\n`{ctx.DefaultPrefix}member <member> privacy <subject> <level>`\n\n- `subject` is one of `name`, `description`, `banner`, `avatar`, `birthday`, `pronouns`, `proxies`, `metadata`, `visibility`, or `all`\n- `level` is either `public` or `private`.")
|
$"To edit privacy settings, use the command:\n`{ctx.DefaultPrefix}member <member> privacy <subject> <level>`\n\n- `subject` is one of `name`, `description`, `banner`, `avatar`, `birthday`, `pronouns`, `proxies`, `metadata`, `visibility`, or `all`\n- `level` is either `public` or `private`.")
|
||||||
.Build());
|
.Build());
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get guild settings (mostly for warnings and such)
|
public async Task ChangeAllPrivacy(Context ctx, PKMember target, PrivacyLevel level)
|
||||||
MemberGuildSettings guildSettings = null;
|
|
||||||
if (ctx.Guild != null)
|
|
||||||
guildSettings = await ctx.Repository.GetMemberGuild(ctx.Guild.Id, target.Id);
|
|
||||||
|
|
||||||
async Task SetAll(PrivacyLevel level)
|
|
||||||
{
|
{
|
||||||
|
ctx.CheckSystem().CheckOwnMember(target);
|
||||||
|
|
||||||
await ctx.Repository.UpdateMember(target.Id, new MemberPatch().WithAllPrivacy(level));
|
await ctx.Repository.UpdateMember(target.Id, new MemberPatch().WithAllPrivacy(level));
|
||||||
|
|
||||||
if (level == PrivacyLevel.Private)
|
if (level == PrivacyLevel.Private)
|
||||||
|
|
@ -827,8 +809,10 @@ public class MemberEdit
|
||||||
$"{Emojis.Success} All {target.NameFor(ctx)}'s privacy settings have been set to **{level.LevelName()}**. Other accounts will now see everything on the member card.");
|
$"{Emojis.Success} All {target.NameFor(ctx)}'s privacy settings have been set to **{level.LevelName()}**. Other accounts will now see everything on the member card.");
|
||||||
}
|
}
|
||||||
|
|
||||||
async Task SetLevel(MemberPrivacySubject subject, PrivacyLevel level)
|
public async Task ChangePrivacy(Context ctx, PKMember target, MemberPrivacySubject subject, PrivacyLevel level)
|
||||||
{
|
{
|
||||||
|
ctx.CheckSystem().CheckOwnMember(target);
|
||||||
|
|
||||||
await ctx.Repository.UpdateMember(target.Id, new MemberPatch().WithPrivacy(subject, level));
|
await ctx.Repository.UpdateMember(target.Id, new MemberPatch().WithPrivacy(subject, level));
|
||||||
|
|
||||||
var subjectName = subject switch
|
var subjectName = subject switch
|
||||||
|
|
@ -895,17 +879,14 @@ public class MemberEdit
|
||||||
replyStr += $"\n{Emojis.Warn} This member does not have a display name set, and name privacy **will not take effect**.";
|
replyStr += $"\n{Emojis.Warn} This member does not have a display name set, and name privacy **will not take effect**.";
|
||||||
|
|
||||||
// Avatar privacy doesn't apply when proxying if no server avatar is set
|
// Avatar privacy doesn't apply when proxying if no server avatar is set
|
||||||
if (subject == MemberPrivacySubject.Avatar && level == PrivacyLevel.Private &&
|
if (subject == MemberPrivacySubject.Avatar && level == PrivacyLevel.Private)
|
||||||
guildSettings?.AvatarUrl == null)
|
{
|
||||||
|
var guildSettings = ctx.Guild != null ? await ctx.Repository.GetMemberGuild(ctx.Guild.Id, target.Id) : null;
|
||||||
|
if (guildSettings?.AvatarUrl == null)
|
||||||
replyStr += $"\n{Emojis.Warn} This member does not have a server avatar set, so *proxying* will **still show the member avatar**. If you want to hide your avatar when proxying here, set a server avatar: `{ctx.DefaultPrefix}member {target.Reference(ctx)} serveravatar`";
|
replyStr += $"\n{Emojis.Warn} This member does not have a server avatar set, so *proxying* will **still show the member avatar**. If you want to hide your avatar when proxying here, set a server avatar: `{ctx.DefaultPrefix}member {target.Reference(ctx)} serveravatar`";
|
||||||
|
|
||||||
await ctx.Reply(replyStr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx.Match("all") || newValueFromCommand != null)
|
await ctx.Reply(replyStr);
|
||||||
await SetAll(newValueFromCommand ?? ctx.PopPrivacyLevel());
|
|
||||||
else
|
|
||||||
await SetLevel(ctx.PopMemberPrivacySubject(), ctx.PopPrivacyLevel());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task Delete(Context ctx, PKMember target)
|
public async Task Delete(Context ctx, PKMember target)
|
||||||
|
|
|
||||||
|
|
@ -2,23 +2,60 @@ use super::*;
|
||||||
|
|
||||||
pub fn cmds() -> impl Iterator<Item = Command> {
|
pub fn cmds() -> impl Iterator<Item = Command> {
|
||||||
let member = ("member", ["m"]);
|
let member = ("member", ["m"]);
|
||||||
|
let member_target = tokens!(member, MemberRef);
|
||||||
|
|
||||||
|
let name = ("name", ["n"]);
|
||||||
let description = ("description", ["desc"]);
|
let description = ("description", ["desc"]);
|
||||||
|
let pronouns = ("pronouns", ["pronoun", "prns", "pn"]);
|
||||||
let privacy = ("privacy", ["priv"]);
|
let privacy = ("privacy", ["priv"]);
|
||||||
let new = ("new", ["n"]);
|
let new = ("new", ["n"]);
|
||||||
|
let banner = ("banner", ["bn"]);
|
||||||
|
let color = ("color", ["colour"]);
|
||||||
|
let birthday = ("birthday", ["bday", "bd"]);
|
||||||
|
let display_name = ("displayname", ["dname", "dn"]);
|
||||||
|
let server_name = ("servername", ["sname", "sn"]);
|
||||||
|
let keep_proxy = ("keepproxy", ["kp"]);
|
||||||
|
let server_keep_proxy = ("serverkeepproxy", ["skp"]);
|
||||||
|
let autoproxy = ("autoproxy", ["ap"]);
|
||||||
|
let tts = ("tts", ["texttospeech"]);
|
||||||
|
let delete = ("delete", ["del", "remove"]);
|
||||||
|
|
||||||
let member_target = tokens!(member, MemberRef);
|
// Group commands by functionality
|
||||||
let member_desc = tokens!(member_target, description);
|
let member_new_cmd = [
|
||||||
let member_privacy = tokens!(member_target, privacy);
|
|
||||||
|
|
||||||
[
|
|
||||||
command!(member, new, ("name", OpaqueString) => "member_new")
|
command!(member, new, ("name", OpaqueString) => "member_new")
|
||||||
.help("Creates a new system member"),
|
.help("Creates a new system member"),
|
||||||
|
].into_iter();
|
||||||
|
|
||||||
|
let member_info_cmd = [
|
||||||
command!(member_target => "member_show")
|
command!(member_target => "member_show")
|
||||||
.flag("pt")
|
.flag("pt")
|
||||||
.help("Shows information about a member"),
|
.help("Shows information about a member"),
|
||||||
|
].into_iter();
|
||||||
|
|
||||||
|
let member_name_cmd = {
|
||||||
|
let member_name = tokens!(member_target, name);
|
||||||
|
[
|
||||||
|
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()
|
||||||
|
};
|
||||||
|
|
||||||
|
let member_description_cmd = {
|
||||||
|
let member_desc = tokens!(member_target, description);
|
||||||
|
[
|
||||||
command!(member_desc => "member_desc_show").help("Shows a member's description"),
|
command!(member_desc => "member_desc_show").help("Shows a member's description"),
|
||||||
|
command!(member_desc, ("clear", ["c"]) => "member_desc_clear")
|
||||||
|
.flag(("yes", ["y"]))
|
||||||
|
.help("Clears a member's description"),
|
||||||
command!(member_desc, ("description", OpaqueStringRemainder) => "member_desc_update")
|
command!(member_desc, ("description", OpaqueStringRemainder) => "member_desc_update")
|
||||||
.help("Changes a member's description"),
|
.help("Changes a member's description"),
|
||||||
|
].into_iter()
|
||||||
|
};
|
||||||
|
|
||||||
|
let member_privacy_cmd = {
|
||||||
|
let member_privacy = tokens!(member_target, privacy);
|
||||||
|
[
|
||||||
command!(member_privacy => "member_privacy_show")
|
command!(member_privacy => "member_privacy_show")
|
||||||
.help("Displays a member's current privacy settings"),
|
.help("Displays a member's current privacy settings"),
|
||||||
command!(
|
command!(
|
||||||
|
|
@ -26,7 +63,142 @@ pub fn cmds() -> impl Iterator<Item = Command> {
|
||||||
=> "member_privacy_update"
|
=> "member_privacy_update"
|
||||||
)
|
)
|
||||||
.help("Changes a member's privacy settings"),
|
.help("Changes a member's privacy settings"),
|
||||||
|
].into_iter()
|
||||||
|
};
|
||||||
|
|
||||||
|
let member_pronouns_cmd = {
|
||||||
|
let member_pronouns = tokens!(member_target, pronouns);
|
||||||
|
[
|
||||||
|
command!(member_pronouns => "member_pronouns_show")
|
||||||
|
.help("Shows a member's pronouns"),
|
||||||
|
command!(member_pronouns, ("pronouns", OpaqueStringRemainder) => "member_pronouns_update")
|
||||||
|
.help("Changes a member's pronouns"),
|
||||||
|
command!(member_pronouns, ("clear", ["c"]) => "member_pronouns_clear")
|
||||||
|
.flag(("yes", ["y"]))
|
||||||
|
.help("Clears a member's pronouns"),
|
||||||
|
].into_iter()
|
||||||
|
};
|
||||||
|
|
||||||
|
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, ("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()
|
||||||
|
};
|
||||||
|
|
||||||
|
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, ("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()
|
||||||
|
};
|
||||||
|
|
||||||
|
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, ("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()
|
||||||
|
};
|
||||||
|
|
||||||
|
let member_display_name_cmd = {
|
||||||
|
let member_display_name = tokens!(member_target, display_name);
|
||||||
|
[
|
||||||
|
command!(member_display_name => "member_displayname_show")
|
||||||
|
.help("Shows a member's display name"),
|
||||||
|
command!(member_display_name, ("name", OpaqueStringRemainder) => "member_displayname_update")
|
||||||
|
.help("Changes a member's display name"),
|
||||||
|
command!(member_display_name, ("clear", ["c"]) => "member_displayname_clear")
|
||||||
|
.flag(("yes", ["y"]))
|
||||||
|
.help("Clears a member's display name"),
|
||||||
|
].into_iter()
|
||||||
|
};
|
||||||
|
|
||||||
|
let member_server_name_cmd = {
|
||||||
|
let member_server_name = tokens!(member_target, server_name);
|
||||||
|
[
|
||||||
|
command!(member_server_name => "member_servername_show")
|
||||||
|
.help("Shows a member's server name"),
|
||||||
|
command!(member_server_name, ("name", OpaqueStringRemainder) => "member_servername_update")
|
||||||
|
.help("Changes a member's server name"),
|
||||||
|
command!(member_server_name, ("clear", ["c"]) => "member_servername_clear")
|
||||||
|
.flag(("yes", ["y"]))
|
||||||
|
.help("Clears a member's server name"),
|
||||||
|
].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);
|
||||||
|
[
|
||||||
|
command!(member_keep_proxy => "member_keepproxy_show")
|
||||||
|
.help("Shows a member's keep-proxy setting"),
|
||||||
|
command!(member_keep_proxy, ("value", Toggle) => "member_keepproxy_update")
|
||||||
|
.help("Changes a member's keep-proxy setting"),
|
||||||
|
command!(member_server_keep_proxy => "member_server_keepproxy_show")
|
||||||
|
.help("Shows a member's server-specific keep-proxy setting"),
|
||||||
|
command!(member_server_keep_proxy, ("value", Toggle) => "member_server_keepproxy_update")
|
||||||
|
.help("Changes a member's server-specific keep-proxy setting"),
|
||||||
|
command!(member_server_keep_proxy, ("clear", ["c"]) => "member_server_keepproxy_clear")
|
||||||
|
.flag(("yes", ["y"]))
|
||||||
|
.help("Clears a member's server-specific keep-proxy setting"),
|
||||||
|
].into_iter()
|
||||||
|
};
|
||||||
|
|
||||||
|
let member_message_settings_cmd = {
|
||||||
|
let member_tts = tokens!(member_target, tts);
|
||||||
|
let member_autoproxy = tokens!(member_target, autoproxy);
|
||||||
|
[
|
||||||
|
command!(member_tts => "member_tts_show")
|
||||||
|
.help("Shows whether a member's messages are sent as TTS"),
|
||||||
|
command!(member_tts, ("value", Toggle) => "member_tts_update")
|
||||||
|
.help("Changes whether a member's messages are sent as TTS"),
|
||||||
|
command!(member_autoproxy => "member_autoproxy_show")
|
||||||
|
.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()
|
||||||
|
};
|
||||||
|
|
||||||
|
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),
|
command!(member_target, "soulscream" => "member_soulscream").show_in_suggestions(false),
|
||||||
]
|
].into_iter();
|
||||||
.into_iter()
|
|
||||||
|
member_new_cmd
|
||||||
|
.chain(member_info_cmd)
|
||||||
|
.chain(member_name_cmd)
|
||||||
|
.chain(member_description_cmd)
|
||||||
|
.chain(member_privacy_cmd)
|
||||||
|
.chain(member_pronouns_cmd)
|
||||||
|
.chain(member_banner_cmd)
|
||||||
|
.chain(member_color_cmd)
|
||||||
|
.chain(member_birthday_cmd)
|
||||||
|
.chain(member_display_name_cmd)
|
||||||
|
.chain(member_server_name_cmd)
|
||||||
|
.chain(member_proxy_settings_cmd)
|
||||||
|
.chain(member_message_settings_cmd)
|
||||||
|
.chain(member_delete_cmd)
|
||||||
|
.chain(member_easter_eggs)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue