From 56eae82b0a92d31b7e4aa6c6733c5b934dff917c Mon Sep 17 00:00:00 2001 From: Ske Date: Thu, 18 Jun 2020 17:08:36 +0200 Subject: [PATCH] Move most references to PKMember.Name to go through helper extepsions for privacy --- PluralKit.API/Controllers/v1/JsonModelExt.cs | 2 +- PluralKit.Bot/CommandSystem/Context.cs | 3 ++ PluralKit.Bot/Commands/Autoproxy.cs | 6 +-- PluralKit.Bot/Commands/Member.cs | 2 +- PluralKit.Bot/Commands/MemberAvatar.cs | 2 +- PluralKit.Bot/Commands/MemberEdit.cs | 41 +++++++++++--------- PluralKit.Bot/Commands/MemberProxy.cs | 2 +- PluralKit.Bot/Commands/Switch.cs | 10 ++--- PluralKit.Bot/Commands/SystemFront.cs | 6 +-- PluralKit.Bot/Commands/SystemList.cs | 2 +- PluralKit.Bot/Errors.cs | 6 +-- PluralKit.Bot/Handlers/ReactionAdded.cs | 4 +- PluralKit.Bot/Lists/LongRenderer.cs | 3 +- PluralKit.Bot/Lists/ShortRenderer.cs | 5 +-- PluralKit.Bot/Lists/SortFilterOptions.cs | 10 ++--- PluralKit.Bot/Services/EmbedService.cs | 22 ++++++----- PluralKit.Bot/Utils/ModelUtils.cs | 13 +++++++ PluralKit.Core/Models/MemberId.cs | 2 + PluralKit.Core/Models/ModelExtensions.cs | 8 ++++ PluralKit.Core/Models/SwitchId.cs | 2 + PluralKit.Core/Models/SystemId.cs | 2 + PluralKit.Core/Utils/BulkImporter.cs | 6 +-- 22 files changed, 97 insertions(+), 62 deletions(-) create mode 100644 PluralKit.Bot/Utils/ModelUtils.cs create mode 100644 PluralKit.Core/Models/ModelExtensions.cs diff --git a/PluralKit.API/Controllers/v1/JsonModelExt.cs b/PluralKit.API/Controllers/v1/JsonModelExt.cs index 9cbb7a00..d8f39a8d 100644 --- a/PluralKit.API/Controllers/v1/JsonModelExt.cs +++ b/PluralKit.API/Controllers/v1/JsonModelExt.cs @@ -44,7 +44,7 @@ namespace PluralKit.API { var o = new JObject(); o.Add("id", member.Hid); - o.Add("name", member.NamePrivacy.CanAccess(ctx) ? member.Name : member.DisplayName ?? member.Name); + o.Add("name", member.NameFor(ctx)); // o.Add("color", member.ColorPrivacy.CanAccess(ctx) ? member.Color : null); o.Add("color", member.Color); o.Add("display_name", member.NamePrivacy.CanAccess(ctx) ? member.DisplayName : null); diff --git a/PluralKit.Bot/CommandSystem/Context.cs b/PluralKit.Bot/CommandSystem/Context.cs index 2502e317..8272178d 100644 --- a/PluralKit.Bot/CommandSystem/Context.cs +++ b/PluralKit.Bot/CommandSystem/Context.cs @@ -279,6 +279,9 @@ namespace PluralKit.Bot public LookupContext LookupContextFor(SystemId systemId) => System?.Id == systemId ? LookupContext.ByOwner : LookupContext.ByNonOwner; + public LookupContext LookupContextFor(PKMember target) => + System?.Id == target.System ? LookupContext.ByOwner : LookupContext.ByNonOwner; + public Context CheckSystemPrivacy(PKSystem target, PrivacyLevel level) { if (level.CanAccess(LookupContextFor(target))) return this; diff --git a/PluralKit.Bot/Commands/Autoproxy.cs b/PluralKit.Bot/Commands/Autoproxy.cs index 1c875ec1..e1c20471 100644 --- a/PluralKit.Bot/Commands/Autoproxy.cs +++ b/PluralKit.Bot/Commands/Autoproxy.cs @@ -76,7 +76,7 @@ namespace PluralKit.Bot ctx.CheckOwnMember(member); await UpdateAutoproxy(ctx, AutoproxyMode.Member, member.Id); - await ctx.Reply($"{Emojis.Success} Autoproxy set to **{member.Name}** in this server."); + await ctx.Reply($"{Emojis.Success} Autoproxy set to **{member.NameFor(ctx)}** in this server."); } private async Task CreateAutoproxyStatusEmbed(Context ctx) @@ -103,14 +103,14 @@ namespace PluralKit.Bot { if (relevantMember == null) throw new ArgumentException("Attempted to print member autoproxy status, but the linked member ID wasn't found in the database. Should be handled appropriately."); - eb.WithDescription($"Autoproxy is currently set to **front mode** in this server. The current (first) fronter is **{relevantMember.Name.EscapeMarkdown()}** (`{relevantMember.Hid}`). To disable, type `pk;autoproxy off`."); + eb.WithDescription($"Autoproxy is currently set to **front mode** in this server. The current (first) fronter is **{relevantMember.NameFor(ctx).EscapeMarkdown()}** (`{relevantMember.Hid}`). To disable, type `pk;autoproxy off`."); } break; } // AutoproxyMember is never null if Mode is Member, this is just to make the compiler shut up case AutoproxyMode.Member when relevantMember != null: { - eb.WithDescription($"Autoproxy is active for member **{relevantMember.Name}** (`{relevantMember.Hid}`) in this server. To disable, type `pk;autoproxy off`."); + eb.WithDescription($"Autoproxy is active for member **{relevantMember.NameFor(ctx)}** (`{relevantMember.Hid}`) in this server. To disable, type `pk;autoproxy off`."); break; } case AutoproxyMode.Latch: diff --git a/PluralKit.Bot/Commands/Member.cs b/PluralKit.Bot/Commands/Member.cs index 4d62607a..31f36ad3 100644 --- a/PluralKit.Bot/Commands/Member.cs +++ b/PluralKit.Bot/Commands/Member.cs @@ -28,7 +28,7 @@ namespace PluralKit.Bot // Warn if there's already a member by this name var existingMember = await _data.GetMemberByName(ctx.System, memberName); if (existingMember != null) { - var msg = await ctx.Reply($"{Emojis.Warn} You already have a member in your system with the name \"{existingMember.Name.SanitizeMentions()}\" (with ID `{existingMember.Hid}`). Do you want to create another member with the same name?"); + var msg = await ctx.Reply($"{Emojis.Warn} You already have a member in your system with the name \"{existingMember.NameFor(ctx).SanitizeMentions()}\" (with ID `{existingMember.Hid}`). Do you want to create another member with the same name?"); if (!await ctx.PromptYesNo(msg)) throw new PKError("Member creation cancelled."); } diff --git a/PluralKit.Bot/Commands/MemberAvatar.cs b/PluralKit.Bot/Commands/MemberAvatar.cs index bfdeb736..c8bfbb19 100644 --- a/PluralKit.Bot/Commands/MemberAvatar.cs +++ b/PluralKit.Bot/Commands/MemberAvatar.cs @@ -61,7 +61,7 @@ namespace PluralKit.Bot } var eb = new DiscordEmbedBuilder() - .WithTitle($"{target.Name.SanitizeMentions()}'s {field}") + .WithTitle($"{target.NameFor(ctx).SanitizeMentions()}'s {field}") .WithImageUrl(currentValue); if (target.System == ctx.System?.Id) eb.WithDescription($"To clear, use `pk;member {target.Hid} {cmd} clear`."); diff --git a/PluralKit.Bot/Commands/MemberEdit.cs b/PluralKit.Bot/Commands/MemberEdit.cs index aa2ccd8f..4641e031 100644 --- a/PluralKit.Bot/Commands/MemberEdit.cs +++ b/PluralKit.Bot/Commands/MemberEdit.cs @@ -35,7 +35,7 @@ namespace PluralKit.Bot // Warn if there's already a member by this name var existingMember = await _data.GetMemberByName(ctx.System, newName); if (existingMember != null) { - var msg = await ctx.Reply($"{Emojis.Warn} You already have a member in your system with the name \"{existingMember.Name.SanitizeMentions()}\" (`{existingMember.Hid}`). Do you want to rename this member to that name too?"); + var msg = await ctx.Reply($"{Emojis.Warn} You already have a member in your system with the name \"{existingMember.NameFor(ctx).SanitizeMentions()}\" (`{existingMember.Hid}`). Do you want to rename this member to that name too?"); if (!await ctx.PromptYesNo(msg)) throw new PKError("Member renaming cancelled."); } @@ -124,7 +124,7 @@ namespace PluralKit.Bot else await ctx.Reply("This member does not have pronouns set."); else - await ctx.Reply($"**{target.Name.SanitizeMentions()}**'s pronouns are **{target.Pronouns.SanitizeMentions()}**." + await ctx.Reply($"**{target.NameFor(ctx).SanitizeMentions()}**'s pronouns are **{target.Pronouns.SanitizeMentions()}**." + (ctx.System?.Id == target.System ? $" To clear them, type `pk;member {target.Hid} pronouns -clear`." : "")); } else @@ -223,6 +223,8 @@ namespace PluralKit.Bot private async Task CreateMemberNameInfoEmbed(Context ctx, PKMember target) { + var lcx = ctx.LookupContextFor(target); + MemberGuildSettings memberGuildConfig = null; if (ctx.Guild != null) memberGuildConfig = await _db.Execute(c => c.QueryOrInsertMemberGuildConfig(ctx.Guild.Id, target.Id)); @@ -231,14 +233,17 @@ namespace PluralKit.Bot .WithFooter($"Member ID: {target.Hid} | Active name in bold. Server name overrides display name, which overrides base name."); if (target.DisplayName == null && memberGuildConfig?.DisplayName == null) - eb.AddField($"Name", $"**{target.Name}**"); + eb.AddField("Name", $"**{target.NameFor(ctx)}**"); else - eb.AddField("Name", target.Name); - - if (target.DisplayName != null && memberGuildConfig?.DisplayName == null) - eb.AddField($"Display Name", $"**{target.DisplayName}**"); - else - eb.AddField("Display Name", target.DisplayName ?? "*(none)*"); + eb.AddField("Name", target.NameFor(ctx)); + + if (target.NamePrivacy.CanAccess(lcx)) + { + if (target.DisplayName != null && memberGuildConfig?.DisplayName == null) + eb.AddField("Display Name", $"**{target.DisplayName}**"); + else + eb.AddField("Display Name", target.DisplayName ?? "*(none)*"); + } if (ctx.Guild != null) { @@ -272,7 +277,7 @@ namespace PluralKit.Bot target.DisplayName = null; await _data.SaveMember(target); - await PrintSuccess($"{Emojis.Success} Member display name cleared. This member will now be proxied using their member name \"{target.Name.SanitizeMentions()}\"."); + await PrintSuccess($"{Emojis.Success} Member display name cleared. This member will now be proxied using their member name \"{target.NameFor(ctx).SanitizeMentions()}\"."); } else if (!ctx.HasNext()) { @@ -309,7 +314,7 @@ namespace PluralKit.Bot if (target.DisplayName != null) await ctx.Reply($"{Emojis.Success} Member server name cleared. This member will now be proxied using their global display name \"{target.DisplayName.SanitizeMentions()}\" in this server ({ctx.Guild.Name.SanitizeMentions()})."); else - await ctx.Reply($"{Emojis.Success} Member server name cleared. This member will now be proxied using their member name \"{target.Name.SanitizeMentions()}\" in this server ({ctx.Guild.Name.SanitizeMentions()})."); + await ctx.Reply($"{Emojis.Success} Member server name cleared. This member will now be proxied using their member name \"{target.NameFor(ctx).SanitizeMentions()}\" in this server ({ctx.Guild.Name.SanitizeMentions()})."); } else if (!ctx.HasNext()) { @@ -360,7 +365,7 @@ namespace PluralKit.Bot await ctx.Reply($"{Emojis.Success} Member proxy tags will now not be included in the resulting message when proxying."); } - private DiscordEmbed CreatePrivacyEmbed(PKMember member) + private DiscordEmbed CreatePrivacyEmbed(Context ctx, PKMember member) { string PrivacyLevelString(PrivacyLevel level) => level switch { @@ -370,7 +375,7 @@ namespace PluralKit.Bot }; var eb = new DiscordEmbedBuilder() - .WithTitle($"Current privacy settings for {member.Name}") + .WithTitle($"Current privacy settings for {member.NameFor(ctx)}") .AddField("Name (replaces name with display name if member has one)",PrivacyLevelString(member.NamePrivacy)) .AddField("Description", PrivacyLevelString(member.DescriptionPrivacy)) .AddField("Birthday", PrivacyLevelString(member.BirthdayPrivacy)) @@ -390,7 +395,7 @@ namespace PluralKit.Bot // Display privacy settings if (!ctx.HasNext() && newValueFromCommand == null) { - await ctx.Reply(embed: CreatePrivacyEmbed(target)); + await ctx.Reply(embed: CreatePrivacyEmbed(ctx, target)); return; } @@ -440,7 +445,7 @@ namespace PluralKit.Bot (MemberPrivacySubject.Visibility, PrivacyLevel.Public) => "This member is no longer hidden from member lists.", }; - await ctx.Reply($"{Emojis.Success} {target.Name.SanitizeMentions()}'s {subject.Name()} has been set to **{newLevel.Name()}**. {explanation}"); + await ctx.Reply($"{Emojis.Success} {target.NameFor(ctx).SanitizeMentions()}'s {subject.Name()} has been set to **{newLevel.Name()}**. {explanation}"); } else if (ctx.Match("all") || newValueFromCommand != null) { @@ -449,9 +454,9 @@ namespace PluralKit.Bot await _data.SaveMember(target); if(newLevel == PrivacyLevel.Private) - await ctx.Reply($"All {target.Name.SanitizeMentions()}'s privacy settings have been set to **{newLevel.Name()}**. Other accounts will now see nothing on the member card."); + await ctx.Reply($"All {target.NameFor(ctx).SanitizeMentions()}'s privacy settings have been set to **{newLevel.Name()}**. Other accounts will now see nothing on the member card."); else - await ctx.Reply($"All {target.Name.SanitizeMentions()}'s privacy settings have been set to **{newLevel.Name()}**. Other accounts will now see everything on the member card."); + await ctx.Reply($"All {target.NameFor(ctx).SanitizeMentions()}'s privacy settings have been set to **{newLevel.Name()}**. Other accounts will now see everything on the member card."); } else { @@ -469,7 +474,7 @@ namespace PluralKit.Bot if (ctx.System == null) throw Errors.NoSystemError; if (target.System != ctx.System.Id) throw Errors.NotOwnMemberError; - await ctx.Reply($"{Emojis.Warn} Are you sure you want to delete \"{target.Name.SanitizeMentions()}\"? If so, reply to this message with the member's ID (`{target.Hid}`). __***This cannot be undone!***__"); + await ctx.Reply($"{Emojis.Warn} Are you sure you want to delete \"{target.NameFor(ctx).SanitizeMentions()}\"? If so, reply to this message with the member's ID (`{target.Hid}`). __***This cannot be undone!***__"); if (!await ctx.ConfirmWithReply(target.Hid)) throw Errors.MemberDeleteCancelled; await _data.DeleteMember(target); await ctx.Reply($"{Emojis.Success} Member deleted."); diff --git a/PluralKit.Bot/Commands/MemberProxy.cs b/PluralKit.Bot/Commands/MemberProxy.cs index f01f3989..2c6c7d10 100644 --- a/PluralKit.Bot/Commands/MemberProxy.cs +++ b/PluralKit.Bot/Commands/MemberProxy.cs @@ -36,7 +36,7 @@ namespace PluralKit.Bot if (conflicts.Count <= 0) return true; - var conflictList = conflicts.Select(m => $"- **{m.Name}**"); + var conflictList = conflicts.Select(m => $"- **{m.NameFor(ctx)}**"); var msg = await ctx.Reply( $"{Emojis.Warn} The following members have conflicting proxy tags:\n{string.Join('\n', conflictList)}\nDo you want to proceed anyway?"); return await ctx.PromptYesNo(msg); diff --git a/PluralKit.Bot/Commands/Switch.cs b/PluralKit.Bot/Commands/Switch.cs index e0086a3e..e32f1825 100644 --- a/PluralKit.Bot/Commands/Switch.cs +++ b/PluralKit.Bot/Commands/Switch.cs @@ -62,7 +62,7 @@ namespace PluralKit.Bot var lastSwitchMembers = _data.GetSwitchMembers(lastSwitch); // Make sure the requested switch isn't identical to the last one if (await lastSwitchMembers.Select(m => m.Id).SequenceEqualAsync(members.Select(m => m.Id).ToAsyncEnumerable())) - throw Errors.SameSwitch(members); + throw Errors.SameSwitch(members, ctx.LookupContextFor(ctx.System)); } await _data.AddSwitch(ctx.System.Id, members); @@ -70,7 +70,7 @@ namespace PluralKit.Bot if (members.Count == 0) await ctx.Reply($"{Emojis.Success} Switch-out registered."); else - await ctx.Reply($"{Emojis.Success} Switch registered. Current fronter is now {string.Join(", ", members.Select(m => m.Name)).SanitizeMentions()}."); + await ctx.Reply($"{Emojis.Success} Switch registered. Current fronter is now {string.Join(", ", members.Select(m => m.NameFor(ctx))).SanitizeMentions()}."); } public async Task SwitchMove(Context ctx) @@ -102,7 +102,7 @@ namespace PluralKit.Bot // Now we can actually do the move, yay! // But, we do a prompt to confirm. var lastSwitchMembers = _data.GetSwitchMembers(lastTwoSwitches[0]); - var lastSwitchMemberStr = string.Join(", ", await lastSwitchMembers.Select(m => m.Name).ToListAsync()); + var lastSwitchMemberStr = string.Join(", ", await lastSwitchMembers.Select(m => m.NameFor(ctx)).ToListAsync()); var lastSwitchTimeStr = DateTimeFormats.ZonedDateTimeFormat.Format(lastTwoSwitches[0].Timestamp.InZone(ctx.System.Zone)); var lastSwitchDeltaStr = DateTimeFormats.DurationFormat.Format(SystemClock.Instance.GetCurrentInstant() - lastTwoSwitches[0].Timestamp); var newSwitchTimeStr = DateTimeFormats.ZonedDateTimeFormat.Format(time); @@ -137,7 +137,7 @@ namespace PluralKit.Bot if (lastTwoSwitches.Count == 0) throw Errors.NoRegisteredSwitches; var lastSwitchMembers = _data.GetSwitchMembers(lastTwoSwitches[0]); - var lastSwitchMemberStr = string.Join(", ", await lastSwitchMembers.Select(m => m.Name).ToListAsync()); + var lastSwitchMemberStr = string.Join(", ", await lastSwitchMembers.Select(m => m.NameFor(ctx)).ToListAsync()); var lastSwitchDeltaStr = DateTimeFormats.DurationFormat.Format(SystemClock.Instance.GetCurrentInstant() - lastTwoSwitches[0].Timestamp); DiscordMessage msg; @@ -149,7 +149,7 @@ namespace PluralKit.Bot else { var secondSwitchMembers = _data.GetSwitchMembers(lastTwoSwitches[1]); - var secondSwitchMemberStr = string.Join(", ", await secondSwitchMembers.Select(m => m.Name).ToListAsync()); + var secondSwitchMemberStr = string.Join(", ", await secondSwitchMembers.Select(m => m.NameFor(ctx)).ToListAsync()); var secondSwitchDeltaStr = DateTimeFormats.DurationFormat.Format(SystemClock.Instance.GetCurrentInstant() - lastTwoSwitches[1].Timestamp); msg = await ctx.Reply( $"{Emojis.Warn} This will delete the latest switch ({lastSwitchMemberStr.SanitizeMentions()}, {lastSwitchDeltaStr} ago). The next latest switch is {secondSwitchMemberStr.SanitizeMentions()} ({secondSwitchDeltaStr} ago). Is this okay?"); diff --git a/PluralKit.Bot/Commands/SystemFront.cs b/PluralKit.Bot/Commands/SystemFront.cs index b48d2e69..ed9138d6 100644 --- a/PluralKit.Bot/Commands/SystemFront.cs +++ b/PluralKit.Bot/Commands/SystemFront.cs @@ -39,7 +39,7 @@ namespace PluralKit.Bot var sw = await _data.GetLatestSwitch(system.Id); if (sw == null) throw Errors.NoRegisteredSwitches; - await ctx.Reply(embed: await _embeds.CreateFronterEmbed(sw, system.Zone)); + await ctx.Reply(embed: await _embeds.CreateFronterEmbed(sw, system.Zone, ctx.LookupContextFor(system))); } public async Task SystemFrontHistory(Context ctx, PKSystem system) @@ -68,7 +68,7 @@ namespace PluralKit.Bot var sw = entry.ThisSwitch; // Fetch member list and format var members = await _data.GetSwitchMembers(sw).ToListAsync(); - var membersStr = members.Any() ? string.Join(", ", members.Select(m => m.Name)) : "no fronter"; + var membersStr = members.Any() ? string.Join(", ", members.Select(m => m.NameFor(ctx))) : "no fronter"; var switchSince = SystemClock.Instance.GetCurrentInstant() - sw.Timestamp; @@ -113,7 +113,7 @@ namespace PluralKit.Bot if (rangeStart.Value.ToInstant() > now) throw Errors.FrontPercentTimeInFuture; var frontpercent = await _data.GetFrontBreakdown(system, rangeStart.Value.ToInstant(), now); - await ctx.Reply(embed: await _embeds.CreateFrontPercentEmbed(frontpercent, system.Zone)); + await ctx.Reply(embed: await _embeds.CreateFrontPercentEmbed(frontpercent, system.Zone, ctx.LookupContextFor(system))); } } } \ No newline at end of file diff --git a/PluralKit.Bot/Commands/SystemList.cs b/PluralKit.Bot/Commands/SystemList.cs index 2a4ca989..57e3e6b2 100644 --- a/PluralKit.Bot/Commands/SystemList.cs +++ b/PluralKit.Bot/Commands/SystemList.cs @@ -24,7 +24,7 @@ namespace PluralKit.Bot var renderer = GetRendererFor(ctx); var opts = GetOptions(ctx, target); - var members = (await _db.Execute(c => opts.Execute(c, target))).ToList(); + var members = (await _db.Execute(c => opts.Execute(c, target, ctx.LookupContextFor(target)))).ToList(); await ctx.Paginate( members.ToAsyncEnumerable(), members.Count, diff --git a/PluralKit.Bot/Errors.cs b/PluralKit.Bot/Errors.cs index 5156db2e..b25e91d7 100644 --- a/PluralKit.Bot/Errors.cs +++ b/PluralKit.Bot/Errors.cs @@ -68,11 +68,11 @@ namespace PluralKit.Bot { public static PKError MemberLinkCancelled => new PKError("Member link cancelled."); public static PKError MemberUnlinkCancelled => new PKError("Member unlink cancelled."); - public static PKError SameSwitch(ICollection members) + public static PKError SameSwitch(ICollection members, LookupContext ctx) { if (members.Count == 0) return new PKError("There's already no one in front."); - if (members.Count == 1) return new PKError($"Member {members.First().Name.SanitizeMentions()} is already fronting."); - return new PKError($"Members {string.Join(", ", members.Select(m => m.Name.SanitizeMentions()))} are already fronting."); + if (members.Count == 1) return new PKError($"Member {members.First().NameFor(ctx).SanitizeMentions()} is already fronting."); + return new PKError($"Members {string.Join(", ", members.Select(m => m.NameFor(ctx).SanitizeMentions()))} are already fronting."); } public static PKError DuplicateSwitchMembers => new PKError("Duplicate members in member list."); diff --git a/PluralKit.Bot/Handlers/ReactionAdded.cs b/PluralKit.Bot/Handlers/ReactionAdded.cs index 34c8005a..8dec0d53 100644 --- a/PluralKit.Bot/Handlers/ReactionAdded.cs +++ b/PluralKit.Bot/Handlers/ReactionAdded.cs @@ -105,14 +105,14 @@ namespace PluralKit.Bot { // If the system has pings enabled, go ahead var embed = new DiscordEmbedBuilder().WithDescription($"[Jump to pinged message]({evt.Message.JumpLink})"); - await evt.Channel.SendMessageAsync($"Psst, **{msg.Member.DisplayName ?? msg.Member.Name}** (<@{msg.Message.Sender}>), you have been pinged by <@{evt.User.Id}>.", embed: embed.Build()); + await evt.Channel.SendMessageAsync($"Psst, **{msg.Member.DisplayName()}** (<@{msg.Message.Sender}>), you have been pinged by <@{evt.User.Id}>.", embed: embed.Build()); } else { // If not, tell them in DMs (if we can) try { - await guildUser.SendMessageAsync($"{Emojis.Error} {msg.Member.DisplayName ?? msg.Member.Name}'s system has disabled reaction pings. If you want to mention them anyway, you can copy/paste the following message:"); + await guildUser.SendMessageAsync($"{Emojis.Error} {msg.Member.DisplayName()}'s system has disabled reaction pings. If you want to mention them anyway, you can copy/paste the following message:"); await guildUser.SendMessageAsync($"`<@{msg.Message.Sender}>`"); } catch (UnauthorizedException) { } diff --git a/PluralKit.Bot/Lists/LongRenderer.cs b/PluralKit.Bot/Lists/LongRenderer.cs index 5b3b528e..1f9cd318 100644 --- a/PluralKit.Bot/Lists/LongRenderer.cs +++ b/PluralKit.Bot/Lists/LongRenderer.cs @@ -38,8 +38,7 @@ namespace PluralKit.Bot if (_fields.ShowPrivacy && m.MemberVisibility == PrivacyLevel.Private) profile += "\n*(this member is hidden)*"; - var memberName = m.NamePrivacy.CanAccess(ctx) ? m.Name : (m.DisplayName ?? m.Name); - eb.AddField(memberName, profile.Truncate(1024)); + eb.AddField(m.NameFor(ctx), profile.Truncate(1024)); } } diff --git a/PluralKit.Bot/Lists/ShortRenderer.cs b/PluralKit.Bot/Lists/ShortRenderer.cs index b2d1084b..e35a133e 100644 --- a/PluralKit.Bot/Lists/ShortRenderer.cs +++ b/PluralKit.Bot/Lists/ShortRenderer.cs @@ -22,11 +22,10 @@ namespace PluralKit.Bot var proxyTagsString = m.ProxyTagsString().SanitizeMentions(); if (proxyTagsString.Length > 100) // arbitrary threshold for now, tweak? proxyTagsString = "tags too long, see member card"; - var memberName = m.NamePrivacy.CanAccess(ctx) ? m.Name : (m.DisplayName ?? m.Name); - return $"[`{m.Hid}`] **{memberName.SanitizeMentions()}** *({proxyTagsString})*"; + return $"[`{m.Hid}`] **{m.NameFor(ctx).SanitizeMentions()}** *({proxyTagsString})*"; } - return $"[`{m.Hid}`] **{m.Name.SanitizeMentions()}**"; + return $"[`{m.Hid}`] **{m.NameFor(ctx).SanitizeMentions()}**"; } var buf = new StringBuilder(); diff --git a/PluralKit.Bot/Lists/SortFilterOptions.cs b/PluralKit.Bot/Lists/SortFilterOptions.cs index 69fd2d47..e3644a74 100644 --- a/PluralKit.Bot/Lists/SortFilterOptions.cs +++ b/PluralKit.Bot/Lists/SortFilterOptions.cs @@ -52,10 +52,10 @@ namespace PluralKit.Bot return str.ToString(); } - public async Task> Execute(IPKConnection conn, PKSystem system) + public async Task> Execute(IPKConnection conn, PKSystem system, LookupContext ctx) { var filtered = await QueryWithFilter(conn, system); - return Sort(filtered); + return Sort(filtered, ctx); } private Task> QueryWithFilter(IPKConnection conn, PKSystem system) => @@ -67,7 +67,7 @@ namespace PluralKit.Bot _ => throw new ArgumentOutOfRangeException($"Unknown privacy filter {PrivacyFilter}") }, Filter, SearchInDescription); - private IEnumerable Sort(IEnumerable input) + private IEnumerable Sort(IEnumerable input, LookupContext ctx) { IComparer ReverseMaybe(IComparer c) => Reverse ? Comparer.Create((a, b) => c.Compare(b, a)) : c; @@ -78,7 +78,7 @@ namespace PluralKit.Bot // As for the OrderByDescending HasValue calls: https://www.jerriepelser.com/blog/orderby-with-null-values/ // We want nulls last no matter what, even if orders are reversed SortProperty.Hid => input.OrderBy(m => m.Hid, ReverseMaybe(culture)), - SortProperty.Name => input.OrderBy(m => m.Name, ReverseMaybe(culture)), + SortProperty.Name => input.OrderBy(m => m.NameFor(ctx), ReverseMaybe(culture)), SortProperty.CreationDate => input.OrderBy(m => m.Created, ReverseMaybe(Comparer.Default)), SortProperty.MessageCount => input.OrderByDescending(m => m.MessageCount, ReverseMaybe(Comparer.Default)), SortProperty.DisplayName => input @@ -96,7 +96,7 @@ namespace PluralKit.Bot _ => throw new ArgumentOutOfRangeException($"Unknown sort property {SortProperty}") }) // Lastly, add a by-name fallback order for collisions (generally hits w/ lots of null values) - .ThenBy(m => m.Name, culture); + .ThenBy(m => m.NameFor(ctx), culture); } public static SortFilterOptions FromFlags(Context ctx) diff --git a/PluralKit.Bot/Services/EmbedService.cs b/PluralKit.Bot/Services/EmbedService.cs index 00f44dc7..eaf48dea 100644 --- a/PluralKit.Bot/Services/EmbedService.cs +++ b/PluralKit.Bot/Services/EmbedService.cs @@ -47,7 +47,7 @@ namespace PluralKit.Bot { var switchMembers = await _data.GetSwitchMembers(latestSwitch).ToListAsync(); if (switchMembers.Count > 0) eb.AddField("Fronter".ToQuantity(switchMembers.Count(), ShowQuantityAs.None), - string.Join(", ", switchMembers.Select(m => m.Name))); + string.Join(", ", switchMembers.Select(m => m.NameFor(ctx)))); } if (system.Tag != null) eb.AddField("Tag", system.Tag.EscapeMarkdown()); @@ -70,7 +70,7 @@ namespace PluralKit.Bot { public DiscordEmbed CreateLoggedMessageEmbed(PKSystem system, PKMember member, ulong messageId, ulong originalMsgId, DiscordUser sender, string content, DiscordChannel channel) { // TODO: pronouns in ?-reacted response using this card var timestamp = DiscordUtils.SnowflakeToInstant(messageId); - var name = member.NamePrivacy == PrivacyLevel.Public ? member.Name : member.DisplayName ?? member.Name; + var name = member.NameFor(LookupContext.ByNonOwner); return new DiscordEmbedBuilder() .WithAuthor($"#{channel.Name}: {name}", iconUrl: DiscordUtils.WorkaroundForUrlBug(member.AvatarUrl)) .WithThumbnailUrl(member.AvatarUrl) @@ -85,8 +85,8 @@ namespace PluralKit.Bot { // string FormatTimestamp(Instant timestamp) => DateTimeFormats.ZonedDateTimeFormat.Format(timestamp.InZone(system.Zone)); - var name = member.NamePrivacy.CanAccess(ctx) ? member.Name : member.DisplayName ?? member.Name; - if (system.Name != null) name = $"{member.Name} ({system.Name})"; + var name = member.NameFor(ctx); + if (system.Name != null) name = $"{name} ({system.Name})"; DiscordColor color; try @@ -142,19 +142,21 @@ namespace PluralKit.Bot { return eb.Build(); } - public async Task CreateFronterEmbed(PKSwitch sw, DateTimeZone zone) + public async Task CreateFronterEmbed(PKSwitch sw, DateTimeZone zone, LookupContext ctx) { var members = await _data.GetSwitchMembers(sw).ToListAsync(); var timeSinceSwitch = SystemClock.Instance.GetCurrentInstant() - sw.Timestamp; return new DiscordEmbedBuilder() .WithColor(members.FirstOrDefault()?.Color?.ToDiscordColor() ?? DiscordUtils.Gray) - .AddField($"Current {"fronter".ToQuantity(members.Count, ShowQuantityAs.None)}", members.Count > 0 ? string.Join(", ", members.Select(m => m.Name)) : "*(no fronter)*") + .AddField($"Current {"fronter".ToQuantity(members.Count, ShowQuantityAs.None)}", members.Count > 0 ? string.Join(", ", members.Select(m => m.NameFor(ctx))) : "*(no fronter)*") .AddField("Since", $"{DateTimeFormats.ZonedDateTimeFormat.Format(sw.Timestamp.InZone(zone))} ({DateTimeFormats.DurationFormat.Format(timeSinceSwitch)} ago)") .Build(); } public async Task CreateMessageInfoEmbed(DiscordClient client, FullMessage msg) { + var ctx = LookupContext.ByNonOwner; + var channel = await client.GetChannelAsync(msg.Message.Channel); var serverMsg = channel != null ? await channel.GetMessageAsync(msg.Message.Mid) : null; @@ -177,12 +179,12 @@ namespace PluralKit.Bot { // Put it all together var eb = new DiscordEmbedBuilder() - .WithAuthor(msg.Member.Name, iconUrl: DiscordUtils.WorkaroundForUrlBug(msg.Member.AvatarUrl)) + .WithAuthor(msg.Member.NameFor(ctx), iconUrl: DiscordUtils.WorkaroundForUrlBug(msg.Member.AvatarUrl)) .WithDescription(serverMsg?.Content?.NormalizeLineEndSpacing() ?? "*(message contents deleted or inaccessible)*") .WithImageUrl(serverMsg?.Attachments?.FirstOrDefault()?.Url) .AddField("System", msg.System.Name != null ? $"{msg.System.Name} (`{msg.System.Hid}`)" : $"`{msg.System.Hid}`", true) - .AddField("Member", $"{msg.Member.Name} (`{msg.Member.Hid}`)", true) + .AddField("Member", $"{msg.Member.NameFor(ctx)} (`{msg.Member.Hid}`)", true) .AddField("Sent by", userStr, inline: true) .WithTimestamp(DiscordUtils.SnowflakeToInstant(msg.Message.Mid).ToDateTimeOffset()); @@ -193,7 +195,7 @@ namespace PluralKit.Bot { return eb.Build(); } - public Task CreateFrontPercentEmbed(FrontBreakdown breakdown, DateTimeZone tz) + public Task CreateFrontPercentEmbed(FrontBreakdown breakdown, DateTimeZone tz, LookupContext ctx) { var actualPeriod = breakdown.RangeEnd - breakdown.RangeStart; var eb = new DiscordEmbedBuilder() @@ -212,7 +214,7 @@ namespace PluralKit.Bot { foreach (var pair in membersOrdered) { var frac = pair.Value / actualPeriod; - eb.AddField(pair.Key?.Name ?? "*(no fronter)*", $"{frac*100:F0}% ({DateTimeFormats.DurationFormat.Format(pair.Value)})"); + eb.AddField(pair.Key?.NameFor(ctx) ?? "*(no fronter)*", $"{frac*100:F0}% ({DateTimeFormats.DurationFormat.Format(pair.Value)})"); } if (membersOrdered.Count > maxEntriesToDisplay) diff --git a/PluralKit.Bot/Utils/ModelUtils.cs b/PluralKit.Bot/Utils/ModelUtils.cs new file mode 100644 index 00000000..7e90042e --- /dev/null +++ b/PluralKit.Bot/Utils/ModelUtils.cs @@ -0,0 +1,13 @@ +using PluralKit.Core; + +namespace PluralKit.Bot +{ + public static class ModelUtils + { + public static string NameFor(this PKMember member, Context ctx) => + member.NameFor(ctx.LookupContextFor(member)); + + public static string DisplayName(this PKMember member) => + member.DisplayName ?? member.Name; + } +} \ No newline at end of file diff --git a/PluralKit.Core/Models/MemberId.cs b/PluralKit.Core/Models/MemberId.cs index 2fa90ba6..7bf27ab7 100644 --- a/PluralKit.Core/Models/MemberId.cs +++ b/PluralKit.Core/Models/MemberId.cs @@ -20,5 +20,7 @@ public static bool operator !=(MemberId left, MemberId right) => !left.Equals(right); public int CompareTo(MemberId other) => Value.CompareTo(other.Value); + + public override string ToString() => $"Member #{Value}"; } } \ No newline at end of file diff --git a/PluralKit.Core/Models/ModelExtensions.cs b/PluralKit.Core/Models/ModelExtensions.cs new file mode 100644 index 00000000..55856bf9 --- /dev/null +++ b/PluralKit.Core/Models/ModelExtensions.cs @@ -0,0 +1,8 @@ +namespace PluralKit.Core +{ + public static class ModelExtensions + { + public static string NameFor(this PKMember member, LookupContext ctx) => + member.NamePrivacy.CanAccess(ctx) ? member.Name : member.DisplayName ?? member.Name; + } +} \ No newline at end of file diff --git a/PluralKit.Core/Models/SwitchId.cs b/PluralKit.Core/Models/SwitchId.cs index 11a775a0..6c6f98c3 100644 --- a/PluralKit.Core/Models/SwitchId.cs +++ b/PluralKit.Core/Models/SwitchId.cs @@ -20,5 +20,7 @@ public static bool operator !=(SwitchId left, SwitchId right) => !left.Equals(right); public int CompareTo(SwitchId other) => Value.CompareTo(other.Value); + + public override string ToString() => $"Switch #{Value}"; } } \ No newline at end of file diff --git a/PluralKit.Core/Models/SystemId.cs b/PluralKit.Core/Models/SystemId.cs index 42c1336a..a09afdca 100644 --- a/PluralKit.Core/Models/SystemId.cs +++ b/PluralKit.Core/Models/SystemId.cs @@ -20,5 +20,7 @@ public static bool operator !=(SystemId left, SystemId right) => !left.Equals(right); public int CompareTo(SystemId other) => Value.CompareTo(other.Value); + + public override string ToString() => $"System #{Value}"; } } \ No newline at end of file diff --git a/PluralKit.Core/Utils/BulkImporter.cs b/PluralKit.Core/Utils/BulkImporter.cs index 4defb17a..32edad9c 100644 --- a/PluralKit.Core/Utils/BulkImporter.cs +++ b/PluralKit.Core/Utils/BulkImporter.cs @@ -137,7 +137,7 @@ namespace PluralKit.Core // Otherwise, write to importer await importer.StartRowAsync(); - await importer.WriteAsync(_systemId, NpgsqlDbType.Integer); + await importer.WriteAsync(_systemId.Value, NpgsqlDbType.Integer); await importer.WriteAsync(sw.Timestamp, NpgsqlDbType.Timestamp); // Note that we've imported a switch with this timestamp @@ -170,8 +170,8 @@ namespace PluralKit.Core throw new Exception($"Attempted to import switch with member identifier {memberIdentifier} but could not find an entry in the id map for this! :/"); await importer.StartRowAsync(); - await importer.WriteAsync(justAddedSwitch.Id, NpgsqlDbType.Integer); - await importer.WriteAsync(memberId, NpgsqlDbType.Integer); + await importer.WriteAsync(justAddedSwitch.Id.Value, NpgsqlDbType.Integer); + await importer.WriteAsync(memberId.Value, NpgsqlDbType.Integer); } }