public async Task GroupDescription(Context ctx, PKGroup target) { if (await ctx.MatchClear("this group's description")) { ctx.CheckOwnGroup(target); var patch = new GroupPatch { Description = Partial <string> .Null() }; await _db.Execute(conn => _repo.UpdateGroup(conn, target.Id, patch)); await ctx.Reply($"{Emojis.Success} Group description cleared."); } else if (!ctx.HasNext()) { if (target.Description == null) { if (ctx.System?.Id == target.System) { await ctx.Reply($"This group does not have a description set. To set one, type `pk;group {target.Reference()} description <description>`."); } else { await ctx.Reply("This group does not have a description set."); } } else if (ctx.MatchFlag("r", "raw")) { await ctx.Reply($"```\n{target.Description}\n```"); } else { await ctx.Reply(embed : new DiscordEmbedBuilder() .WithTitle("Group description") .WithDescription(target.Description) .AddField("\u200B", $"To print the description with formatting, type `pk;group {target.Reference()} description -raw`." + (ctx.System?.Id == target.System ? $" To clear it, type `pk;group {target.Reference()} description -clear`." : "")) .Build()); } } else { ctx.CheckOwnGroup(target); var description = ctx.RemainderOrNull().NormalizeLineEndSpacing(); if (description.IsLongerThan(Limits.MaxDescriptionLength)) { throw Errors.DescriptionTooLongError(description.Length); } var patch = new GroupPatch { Description = Partial <string> .Present(description) }; await _db.Execute(conn => _repo.UpdateGroup(conn, target.Id, patch)); await ctx.Reply($"{Emojis.Success} Group description changed."); } }
public async Task Pronouns(Context ctx, PKMember target) { if (await ctx.MatchClear("this member's pronouns")) { ctx.CheckOwnMember(target); var patch = new MemberPatch { Pronouns = Partial <string> .Null() }; await _db.Execute(conn => _repo.UpdateMember(conn, target.Id, patch)); await ctx.Reply($"{Emojis.Success} Member pronouns cleared."); } else if (!ctx.HasNext()) { if (!target.PronounPrivacy.CanAccess(ctx.LookupContextFor(target.System))) { throw Errors.LookupNotAllowed; } if (target.Pronouns == null) { if (ctx.System?.Id == target.System) { await ctx.Reply($"This member does not have pronouns set. To set some, type `pk;member {target.Reference()} pronouns <pronouns>`."); } else { await ctx.Reply("This member does not have pronouns set."); } } else if (ctx.MatchFlag("r", "raw")) { await ctx.Reply($"```\n{target.Pronouns}\n```"); } else { await ctx.Reply($"**{target.NameFor(ctx)}**'s pronouns are **{target.Pronouns}**.\nTo print the pronouns with formatting, type `pk;member {target.Reference()} pronouns -raw`." + (ctx.System?.Id == target.System ? $" To clear them, type `pk;member {target.Reference()} pronouns -clear`." : "")); } } else { ctx.CheckOwnMember(target); var pronouns = ctx.RemainderOrNull().NormalizeLineEndSpacing(); if (pronouns.IsLongerThan(Limits.MaxPronounsLength)) { throw Errors.MemberPronounsTooLongError(pronouns.Length); } var patch = new MemberPatch { Pronouns = Partial <string> .Present(pronouns) }; await _db.Execute(conn => _repo.UpdateMember(conn, target.Id, patch)); await ctx.Reply($"{Emojis.Success} Member pronouns changed."); } }
public async Task DisplayName(Context ctx, PKMember target) { async Task PrintSuccess(string text) { var successStr = text; if (ctx.Guild != null) { var memberGuildConfig = await _db.Execute(c => _repo.GetMemberGuild(c, 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 (await ctx.MatchClear("this member's display name")) { ctx.CheckOwnMember(target); var patch = new MemberPatch { DisplayName = Partial <string> .Null() }; await _db.Execute(conn => _repo.UpdateMember(conn, target.Id, patch)); await PrintSuccess($"{Emojis.Success} Member display name cleared. This member will now be proxied using their member name \"{target.NameFor(ctx)}\"."); } else if (!ctx.HasNext()) { // No perms check, display name isn't covered by member privacy var eb = await CreateMemberNameInfoEmbed(ctx, target); if (ctx.System?.Id == target.System) { eb.Description($"To change display name, type `pk;member {target.Reference()} displayname <display name>`.\nTo clear it, type `pk;member {target.Reference()} displayname -clear`."); } await ctx.Reply(embed : eb.Build()); } else { ctx.CheckOwnMember(target); var newDisplayName = ctx.RemainderOrNull(); var patch = new MemberPatch { DisplayName = Partial <string> .Present(newDisplayName) }; await _db.Execute(conn => _repo.UpdateMember(conn, target.Id, patch)); await PrintSuccess($"{Emojis.Success} Member display name changed. This member will now be proxied using the name \"{newDisplayName}\"."); } }
public async Task Color(Context ctx) { ctx.CheckSystem(); if (await ctx.MatchClear()) { var patch = new SystemPatch { Color = Partial <string> .Null() }; await _db.Execute(conn => _repo.UpdateSystem(conn, ctx.System.Id, patch)); await ctx.Reply($"{Emojis.Success} System color cleared."); } else if (!ctx.HasNext()) { if (ctx.System.Color == null) { await ctx.Reply( $"Your system does not have a color set. To set one, type `pk;system color <color>`."); } else { await ctx.Reply(embed : new EmbedBuilder() .Title("System color") .Color(ctx.System.Color.ToDiscordColor()) .Thumbnail(new($"https://fakeimg.pl/256x256/{ctx.System.Color}/?text=%20")) .Description($"Your system's color is **#{ctx.System.Color}**. To clear it, type `pk;s color -clear`.") .Build()); } } else { var color = ctx.RemainderOrNull(); if (color.StartsWith("#")) { color = color.Substring(1); } if (!Regex.IsMatch(color, "^[0-9a-fA-F]{6}$")) { throw Errors.InvalidColorError(color); } var patch = new SystemPatch { Color = Partial <string> .Present(color.ToLowerInvariant()) }; await _db.Execute(conn => _repo.UpdateSystem(conn, ctx.System.Id, patch)); await ctx.Reply(embed : new EmbedBuilder() .Title($"{Emojis.Success} System color changed.") .Color(color.ToDiscordColor()) .Thumbnail(new($"https://fakeimg.pl/256x256/{color}/?text=%20")) .Build()); } }
public async Task Color(Context ctx, PKSystem target) { var isOwnSystem = ctx.System?.Id == target.Id; if (!ctx.HasNext()) { if (target.Color == null) { await ctx.Reply( "This system does not have a color set." + (isOwnSystem ? " To set one, type `pk;system color <color>`." : "")); } else { await ctx.Reply(embed : new EmbedBuilder() .Title("System color") .Color(target.Color.ToDiscordColor()) .Thumbnail(new Embed.EmbedThumbnail($"https://fakeimg.pl/256x256/{target.Color}/?text=%20")) .Description( $"This system's color is **#{target.Color}**." + (isOwnSystem ? " To clear it, type `pk;s color -clear`." : "")) .Build()); } return; } ctx.CheckSystem().CheckOwnSystem(target); if (await ctx.MatchClear()) { await ctx.Repository.UpdateSystem(target.Id, new SystemPatch { Color = Partial <string> .Null() }); await ctx.Reply($"{Emojis.Success} System color cleared."); } else { var color = ctx.RemainderOrNull(); if (color.StartsWith("#")) { color = color.Substring(1); } if (!Regex.IsMatch(color, "^[0-9a-fA-F]{6}$")) { throw Errors.InvalidColorError(color); } await ctx.Repository.UpdateSystem(target.Id, new SystemPatch { Color = Partial <string> .Present(color.ToLowerInvariant()) }); await ctx.Reply(embed : new EmbedBuilder() .Title($"{Emojis.Success} System color changed.") .Color(color.ToDiscordColor()) .Thumbnail(new Embed.EmbedThumbnail($"https://fakeimg.pl/256x256/{color}/?text=%20")) .Build()); } }
public async Task Birthday(Context ctx, PKMember target) { if (await ctx.MatchClear("this member's birthday")) { ctx.CheckOwnMember(target); var patch = new MemberPatch { Birthday = Partial <LocalDate?> .Null() }; await _db.Execute(conn => _repo.UpdateMember(conn, target.Id, patch)); await ctx.Reply($"{Emojis.Success} Member birthdate cleared."); } else if (!ctx.HasNext()) { if (!target.BirthdayPrivacy.CanAccess(ctx.LookupContextFor(target.System))) { throw Errors.LookupNotAllowed; } if (target.Birthday == null) { await ctx.Reply("This member does not have a birthdate set." + (ctx.System?.Id == target.System ? $" To set one, type `pk;member {target.Reference()} birthdate <birthdate>`." : "")); } else { await ctx.Reply($"This member's birthdate is **{target.BirthdayString}**." + (ctx.System?.Id == target.System ? $" To clear it, type `pk;member {target.Reference()} birthdate -clear`." : "")); } } else { ctx.CheckOwnMember(target); var birthdayStr = ctx.RemainderOrNull(); var birthday = DateUtils.ParseDate(birthdayStr, true); if (birthday == null) { throw Errors.BirthdayParseError(birthdayStr); } var patch = new MemberPatch { Birthday = Partial <LocalDate?> .Present(birthday) }; await _db.Execute(conn => _repo.UpdateMember(conn, target.Id, patch)); await ctx.Reply($"{Emojis.Success} Member birthdate changed."); } }
public async Task GroupDisplayName(Context ctx, PKGroup target) { if (await ctx.MatchClear("this group's display name")) { ctx.CheckOwnGroup(target); var patch = new GroupPatch { DisplayName = Partial <string> .Null() }; await _db.Execute(conn => _repo.UpdateGroup(conn, target.Id, patch)); await ctx.Reply($"{Emojis.Success} Group display name cleared."); } else if (!ctx.HasNext()) { // No perms check, display name isn't covered by member privacy var eb = new DiscordEmbedBuilder() .AddField("Name", target.Name) .AddField("Display Name", target.DisplayName ?? "*(none)*"); if (ctx.System?.Id == target.System) { eb.WithDescription($"To change display name, type `pk;group {target.Reference()} displayname <display name>`.\nTo clear it, type `pk;group {target.Reference()} displayname -clear`."); } await ctx.Reply(embed : eb.Build()); } else { ctx.CheckOwnGroup(target); var newDisplayName = ctx.RemainderOrNull(); var patch = new GroupPatch { DisplayName = Partial <string> .Present(newDisplayName) }; await _db.Execute(conn => _repo.UpdateGroup(conn, target.Id, patch)); await ctx.Reply($"{Emojis.Success} Group display name changed."); } }
public async Task Description(Context ctx, PKMember target) { if (await ctx.MatchClear("this member's description")) { ctx.CheckOwnMember(target); var patch = new MemberPatch { Description = Partial <string> .Null() }; await _db.Execute(conn => _repo.UpdateMember(conn, target.Id, patch)); await ctx.Reply($"{Emojis.Success} Member description cleared."); } else if (!ctx.HasNext()) { if (!target.DescriptionPrivacy.CanAccess(ctx.LookupContextFor(target.System))) { throw Errors.LookupNotAllowed; } if (target.Description == null) { if (ctx.System?.Id == target.System) { await ctx.Reply($"This member does not have a description set. To set one, type `pk;member {target.Reference()} description <description>`."); } else { await ctx.Reply("This member does not have a description set."); } } else if (ctx.MatchFlag("r", "raw")) { await ctx.Reply($"```\n{target.Description}\n```"); } else { await ctx.Reply(embed : new EmbedBuilder() .Title("Member description") .Description(target.Description) .Field(new("\u200B", $"To print the description with formatting, type `pk;member {target.Reference()} description -raw`." + (ctx.System?.Id == target.System ? $" To clear it, type `pk;member {target.Reference()} description -clear`." : ""))) .Build()); } } else { ctx.CheckOwnMember(target); var description = ctx.RemainderOrNull().NormalizeLineEndSpacing(); if (description.IsLongerThan(Limits.MaxDescriptionLength)) { throw Errors.DescriptionTooLongError(description.Length); } var patch = new MemberPatch { Description = Partial <string> .Present(description) }; await _db.Execute(conn => _repo.UpdateMember(conn, target.Id, patch)); await ctx.Reply($"{Emojis.Success} Member description changed."); } }
public async Task Color(Context ctx, PKMember target) { var color = ctx.RemainderOrNull(); if (await ctx.MatchClear()) { ctx.CheckOwnMember(target); var patch = new MemberPatch { Color = Partial <string> .Null() }; await _db.Execute(conn => _repo.UpdateMember(conn, target.Id, patch)); await ctx.Reply($"{Emojis.Success} Member color cleared."); } else if (!ctx.HasNext()) { // if (!target.ColorPrivacy.CanAccess(ctx.LookupContextFor(target.System))) // throw Errors.LookupNotAllowed; if (target.Color == null) { if (ctx.System?.Id == target.System) { await ctx.Reply( $"This member does not have a color set. To set one, type `pk;member {target.Reference()} color <color>`."); } else { await ctx.Reply("This member does not have a color set."); } } else { await ctx.Reply(embed : new EmbedBuilder() .Title("Member color") .Color(target.Color.ToDiscordColor()) .Thumbnail(new($"https://fakeimg.pl/256x256/{target.Color}/?text=%20")) .Description($"This member's color is **#{target.Color}**." + (ctx.System?.Id == target.System ? $" To clear it, type `pk;member {target.Reference()} color -clear`." : "")) .Build()); } } else { ctx.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()) }; await _db.Execute(conn => _repo.UpdateMember(conn, target.Id, patch)); await ctx.Reply(embed : new EmbedBuilder() .Title($"{Emojis.Success} Member color changed.") .Color(color.ToDiscordColor()) .Thumbnail(new($"https://fakeimg.pl/256x256/{color}/?text=%20")) .Build()); } }
public async Task Description(Context ctx, PKMember target) { ctx.CheckSystemPrivacy(target.System, target.DescriptionPrivacy); var noDescriptionSetMessage = "This member does not have a description set."; if (ctx.System?.Id == target.System) { noDescriptionSetMessage += $" To set one, type `pk;member {target.Reference(ctx)} description <description>`."; } if (ctx.MatchRaw()) { if (target.Description == null) { await ctx.Reply(noDescriptionSetMessage); } else { await ctx.Reply($"```\n{target.Description}\n```"); } return; } if (!ctx.HasNext(false)) { if (target.Description == null) { await ctx.Reply(noDescriptionSetMessage); } else { await ctx.Reply(embed : new EmbedBuilder() .Title("Member description") .Description(target.Description) .Field(new Embed.Field("\u200B", $"To print the description with formatting, type `pk;member {target.Reference(ctx)} description -raw`." + (ctx.System?.Id == target.System ? $" To clear it, type `pk;member {target.Reference(ctx)} description -clear`." : ""))) .Build()); } return; } ctx.CheckOwnMember(target); if (await ctx.MatchClear("this member's description")) { var patch = new MemberPatch { Description = Partial <string> .Null() }; await ctx.Repository.UpdateMember(target.Id, patch); await ctx.Reply($"{Emojis.Success} Member description cleared."); } else { var description = ctx.RemainderOrNull(false).NormalizeLineEndSpacing(); if (description.IsLongerThan(Limits.MaxDescriptionLength)) { throw Errors.StringTooLongError("Description", description.Length, Limits.MaxDescriptionLength); } var patch = new MemberPatch { Description = Partial <string> .Present(description) }; await ctx.Repository.UpdateMember(target.Id, patch); await ctx.Reply($"{Emojis.Success} Member description changed."); } }
public async Task Pronouns(Context ctx, PKMember target) { var noPronounsSetMessage = "This member does not have pronouns set."; if (ctx.System?.Id == target.System) { noPronounsSetMessage += $"To set some, type `pk;member {target.Reference(ctx)} pronouns <pronouns>`."; } ctx.CheckSystemPrivacy(target.System, target.PronounPrivacy); if (ctx.MatchRaw()) { if (target.Pronouns == null) { await ctx.Reply(noPronounsSetMessage); } else { await ctx.Reply($"```\n{target.Pronouns}\n```"); } return; } if (!ctx.HasNext(false)) { if (target.Pronouns == null) { await ctx.Reply(noPronounsSetMessage); } else { await ctx.Reply( $"**{target.NameFor(ctx)}**'s pronouns are **{target.Pronouns}**.\nTo print the pronouns with formatting, type `pk;member {target.Reference(ctx)} pronouns -raw`." + (ctx.System?.Id == target.System ? $" To clear them, type `pk;member {target.Reference(ctx)} pronouns -clear`." : "")); } return; } ctx.CheckOwnMember(target); if (await ctx.MatchClear("this member's pronouns")) { var patch = new MemberPatch { Pronouns = Partial <string> .Null() }; await ctx.Repository.UpdateMember(target.Id, patch); await ctx.Reply($"{Emojis.Success} Member pronouns cleared."); } else { var pronouns = ctx.RemainderOrNull(false).NormalizeLineEndSpacing(); if (pronouns.IsLongerThan(Limits.MaxPronounsLength)) { throw Errors.StringTooLongError("Pronouns", pronouns.Length, Limits.MaxPronounsLength); } var patch = new MemberPatch { Pronouns = Partial <string> .Present(pronouns) }; await ctx.Repository.UpdateMember(target.Id, patch); await ctx.Reply($"{Emojis.Success} Member pronouns changed."); } }
public async Task GroupDisplayName(Context ctx, PKGroup target) { var noDisplayNameSetMessage = "This group does not have a display name set."; if (ctx.System?.Id == target.System) { noDisplayNameSetMessage += $" To set one, type `pk;group {target.Reference(ctx)} displayname <display name>`."; } // No perms check, display name isn't covered by member privacy if (ctx.MatchRaw()) { if (target.DisplayName == null) { await ctx.Reply(noDisplayNameSetMessage); } else { await ctx.Reply($"```\n{target.DisplayName}\n```"); } return; } if (!ctx.HasNext(false)) { if (target.DisplayName == null) { await ctx.Reply(noDisplayNameSetMessage); } else { var eb = new EmbedBuilder() .Field(new Embed.Field("Name", target.Name)) .Field(new Embed.Field("Display Name", target.DisplayName)); var reference = target.Reference(ctx); if (ctx.System?.Id == target.System) { eb.Description( $"To change display name, type `pk;group {reference} displayname <display name>`." + $"To clear it, type `pk;group {reference} displayname -clear`." + $"To print the raw display name, type `pk;group {reference} displayname -raw`."); } await ctx.Reply(embed : eb.Build()); } return; } ctx.CheckOwnGroup(target); if (await ctx.MatchClear("this group's display name")) { var patch = new GroupPatch { DisplayName = Partial <string> .Null() }; await ctx.Repository.UpdateGroup(target.Id, patch); await ctx.Reply($"{Emojis.Success} Group display name cleared."); if (target.NamePrivacy == PrivacyLevel.Private) { await ctx.Reply($"{Emojis.Warn} Since this group no longer has a display name set, their name privacy **can no longer take effect**."); } } else { var newDisplayName = ctx.RemainderOrNull(false).NormalizeLineEndSpacing(); var patch = new GroupPatch { DisplayName = Partial <string> .Present(newDisplayName) }; await ctx.Repository.UpdateGroup(target.Id, patch); await ctx.Reply($"{Emojis.Success} Group display name changed."); } }