diff --git a/PluralKit.API/Controllers/MemberController.cs b/PluralKit.API/Controllers/MemberController.cs index 36784db4..158abd02 100644 --- a/PluralKit.API/Controllers/MemberController.cs +++ b/PluralKit.API/Controllers/MemberController.cs @@ -68,6 +68,7 @@ namespace PluralKit.API.Controllers member.Pronouns = newMember.Pronouns; member.Description = newMember.Description; member.ProxyTags = newMember.ProxyTags; + member.KeepProxy = newMember.KeepProxy; await _data.SaveMember(member); return Ok(member); @@ -107,6 +108,7 @@ namespace PluralKit.API.Controllers member.Pronouns = newMember.Pronouns; member.Description = newMember.Description; member.ProxyTags = newMember.ProxyTags; + member.KeepProxy = newMember.KeepProxy; await _data.SaveMember(member); return Ok(member); diff --git a/PluralKit.Bot/Commands/CommandTree.cs b/PluralKit.Bot/Commands/CommandTree.cs index b04a4176..0674f2c9 100644 --- a/PluralKit.Bot/Commands/CommandTree.cs +++ b/PluralKit.Bot/Commands/CommandTree.cs @@ -32,6 +32,7 @@ namespace PluralKit.Bot.Commands public static Command MemberDelete = new Command("member delete", "member delete", "uwu"); public static Command MemberAvatar = new Command("member avatar", "member avatar [url|@mention]", "uwu"); public static Command MemberDisplayName = new Command("member displayname", "member displayname [display name]", "uwu"); + public static Command MemberKeepProxy = new Command("member keepproxy", "member keepproxy [on|off]", "uwu"); public static Command Switch = new Command("switch", "switch [member 2] [member 3...]", "uwu"); public static Command SwitchOut = new Command("switch out", "switch out", "uwu"); public static Command SwitchMove = new Command("switch move", "switch move ", "uwu"); @@ -226,6 +227,8 @@ namespace PluralKit.Bot.Commands await ctx.Execute(MemberAvatar, m => m.MemberAvatar(ctx, target)); else if (ctx.Match("displayname", "dn", "dname", "nick", "nickname")) await ctx.Execute(MemberDisplayName, m => m.MemberDisplayName(ctx, target)); + else if (ctx.Match("keepproxy", "keeptags", "showtags")) + await ctx.Execute(MemberKeepProxy, m => m.MemberKeepProxy(ctx, target)); else if (!ctx.HasNext()) // Bare command await ctx.Execute(MemberInfo, m => m.ViewMember(ctx, target)); else diff --git a/PluralKit.Bot/Commands/MemberCommands.cs b/PluralKit.Bot/Commands/MemberCommands.cs index bcf43fad..37d5d738 100644 --- a/PluralKit.Bot/Commands/MemberCommands.cs +++ b/PluralKit.Bot/Commands/MemberCommands.cs @@ -310,6 +310,27 @@ namespace PluralKit.Bot.Commands await _proxyCache.InvalidateResultsForSystem(ctx.System); } + public async Task MemberKeepProxy(Context ctx, PKMember target) + { + if (ctx.System == null) throw Errors.NoSystemError; + if (target.System != ctx.System.Id) throw Errors.NotOwnMemberError; + + 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 newValue = !target.KeepProxy; + + target.KeepProxy = newValue; + await _data.SaveMember(target); + + if (newValue) + await ctx.Reply($"{Emojis.Success} Member proxy tags will now be included in the resulting message when proxying."); + else + await ctx.Reply($"{Emojis.Success} Member proxy tags will now not be included in the resulting message when proxying."); + await _proxyCache.InvalidateResultsForSystem(ctx.System); + } + public async Task ViewMember(Context ctx, PKMember target) { var system = await _data.GetSystemById(target.System); diff --git a/PluralKit.Bot/Services/ProxyService.cs b/PluralKit.Bot/Services/ProxyService.cs index 4bab18e3..b5e085ad 100644 --- a/PluralKit.Bot/Services/ProxyService.cs +++ b/PluralKit.Bot/Services/ProxyService.cs @@ -17,6 +17,7 @@ namespace PluralKit.Bot class ProxyMatch { public PKMember Member; public PKSystem System; + public ProxyTag ProxyTags; public string InnerText; } @@ -69,7 +70,7 @@ namespace PluralKit.Bot if (message.Length >= prefix.Length + suffix.Length && message.StartsWith(prefix) && message.EndsWith(suffix)) { var inner = message.Substring(prefix.Length, message.Length - prefix.Length - suffix.Length); if (leadingMention != null) inner = $"{leadingMention} {inner}"; - return new ProxyMatch { Member = match.Member, System = match.System, InnerText = inner }; + return new ProxyMatch { Member = match.Member, System = match.System, InnerText = inner, ProxyTags = tag}; } } @@ -102,9 +103,14 @@ namespace PluralKit.Bot // If the name's too long (or short), bail if (proxyName.Length < 2) throw Errors.ProxyNameTooShort(proxyName); if (proxyName.Length > Limits.MaxProxyNameLength) throw Errors.ProxyNameTooLong(proxyName); + + // Add the proxy tags into the proxied message if that option is enabled + var messageContents = match.Member.KeepProxy + ? $"{match.ProxyTags.Prefix}{match.InnerText}{match.ProxyTags.Suffix}" + : match.InnerText; // Sanitize @everyone, but only if the original user wouldn't have permission to - var messageContents = SanitizeEveryoneMaybe(message, match.InnerText); + messageContents = SanitizeEveryoneMaybe(message, messageContents); // Execute the webhook itself var hookMessageId = await _webhookExecutor.ExecuteWebhook( diff --git a/PluralKit.Core/Models.cs b/PluralKit.Core/Models.cs index 41e1e0f7..40d265fc 100644 --- a/PluralKit.Core/Models.cs +++ b/PluralKit.Core/Models.cs @@ -66,6 +66,7 @@ namespace PluralKit [JsonProperty("pronouns")] public string Pronouns { get; set; } [JsonProperty("description")] public string Description { get; set; } [JsonProperty("proxy_tags")] public ICollection ProxyTags { get; set; } + [JsonProperty("keep_proxy")] public bool KeepProxy { get; set; } [JsonProperty("created")] public Instant Created { get; set; } // These are deprecated as fuck, and are kinda hacky diff --git a/PluralKit.Core/Stores.cs b/PluralKit.Core/Stores.cs index fe864edc..320a8730 100644 --- a/PluralKit.Core/Stores.cs +++ b/PluralKit.Core/Stores.cs @@ -495,7 +495,7 @@ namespace PluralKit { public async Task SaveMember(PKMember member) { using (var conn = await _conn.Obtain()) - await conn.ExecuteAsync("update members set name = @Name, display_name = @DisplayName, description = @Description, color = @Color, avatar_url = @AvatarUrl, birthday = @Birthday, pronouns = @Pronouns, proxy_tags = @ProxyTags where id = @Id", member); + await conn.ExecuteAsync("update members set name = @Name, display_name = @DisplayName, description = @Description, color = @Color, avatar_url = @AvatarUrl, birthday = @Birthday, pronouns = @Pronouns, proxy_tags = @ProxyTags, keep_proxy = @KeepProxy where id = @Id", member); _logger.Information("Updated member {@Member}", member); } diff --git a/PluralKit.Core/db_schema.sql b/PluralKit.Core/db_schema.sql index 11b55046..051594f7 100644 --- a/PluralKit.Core/db_schema.sql +++ b/PluralKit.Core/db_schema.sql @@ -32,7 +32,8 @@ create table if not exists members birthday date, pronouns text, description text, - proxy_tags proxy_tag[] not null default array[], -- Rationale on making this an array rather than a separate table - we never need to query them individually, only access them as part of a selected Member struct + proxy_tags proxy_tag[] not null default array[], -- Rationale on making this an array rather than a separate table - we never need to query them individually, only access them as part of a selected Member struct + keep_proxy bool not null default false, created timestamp not null default (current_timestamp at time zone 'utc') );