mirror of
https://github.com/PluralKit/PluralKit.git
synced 2026-02-15 18:20:11 +00:00
feat: per-server keepproxy toggling (#574)
Merges PluralKit/PluralKit#574
This commit is contained in:
parent
8a59ef5f50
commit
22ce250b56
11 changed files with 131 additions and 15 deletions
|
|
@ -55,6 +55,7 @@ public partial class CommandTree
|
||||||
public static Command MemberAutoproxy = new Command("member autoproxy", "member <member> autoproxy [on|off]", "Sets whether a member will be autoproxied when autoproxy is set to latch or front mode.");
|
public static Command MemberAutoproxy = new Command("member autoproxy", "member <member> autoproxy [on|off]", "Sets whether a member will be autoproxied when autoproxy is set to latch or front mode.");
|
||||||
public static Command MemberKeepProxy = new Command("member keepproxy", "member <member> keepproxy [on|off]", "Sets whether to include a member's proxy tags when proxying");
|
public static Command MemberKeepProxy = new Command("member keepproxy", "member <member> keepproxy [on|off]", "Sets whether to include a member's proxy tags when proxying");
|
||||||
public static Command MemberTts = new Command("member text-to-speech", "member <member> text-to-speech [on|off]", "Sets whether to send a member's messages as text-to-speech messages.");
|
public static Command MemberTts = new Command("member text-to-speech", "member <member> text-to-speech [on|off]", "Sets whether to send a member's messages as text-to-speech messages.");
|
||||||
|
public static Command MemberServerKeepProxy = new Command("member server keepproxy", "member <member> serverkeepproxy [on|off]", "Sets whether to include a member's proxy tags when proxying in the current server.");
|
||||||
public static Command MemberRandom = new Command("system random", "system [system] random", "Shows the info card of a randomly selected member in a system.");
|
public static Command MemberRandom = new Command("system random", "system [system] random", "Shows the info card of a randomly selected member in a system.");
|
||||||
public static Command MemberId = new Command("member id", "member [member] id", "Prints a member's id.");
|
public static Command MemberId = new Command("member id", "member [member] id", "Prints a member's id.");
|
||||||
public static Command MemberPrivacy = new Command("member privacy", "member <member> privacy <name|description|birthday|pronouns|metadata|visibility|all> <public|private>", "Changes a members's privacy settings");
|
public static Command MemberPrivacy = new Command("member privacy", "member <member> privacy <name|description|birthday|pronouns|metadata|visibility|all> <public|private>", "Changes a members's privacy settings");
|
||||||
|
|
@ -153,4 +154,4 @@ public partial class CommandTree
|
||||||
public static Command[] LogCommands = { LogChannel, LogChannelClear, LogEnable, LogDisable, LogShow };
|
public static Command[] LogCommands = { LogChannel, LogChannelClear, LogEnable, LogDisable, LogShow };
|
||||||
|
|
||||||
public static Command[] BlacklistCommands = { BlacklistAdd, BlacklistRemove, BlacklistShow };
|
public static Command[] BlacklistCommands = { BlacklistAdd, BlacklistRemove, BlacklistShow };
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -338,6 +338,8 @@ public partial class CommandTree
|
||||||
await ctx.Execute<MemberEdit>(MemberKeepProxy, m => m.KeepProxy(ctx, target));
|
await ctx.Execute<MemberEdit>(MemberKeepProxy, m => m.KeepProxy(ctx, target));
|
||||||
else if (ctx.Match("texttospeech", "text-to-speech", "tts"))
|
else if (ctx.Match("texttospeech", "text-to-speech", "tts"))
|
||||||
await ctx.Execute<MemberEdit>(MemberTts, m => m.Tts(ctx, target));
|
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"))
|
else if (ctx.Match("privacy"))
|
||||||
|
|
@ -538,4 +540,4 @@ public partial class CommandTree
|
||||||
// todo: maybe add the list of configuration keys here?
|
// todo: maybe add the list of configuration keys here?
|
||||||
return ctx.Reply($"{Emojis.Error} Could not find a setting with that name. Please see `pk;commands config` for the list of possible config settings.");
|
return ctx.Reply($"{Emojis.Error} Could not find a setting with that name. Please see `pk;commands config` for the list of possible config settings.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -494,6 +494,7 @@ public class MemberEdit
|
||||||
public async Task KeepProxy(Context ctx, PKMember target)
|
public async Task KeepProxy(Context ctx, PKMember target)
|
||||||
{
|
{
|
||||||
ctx.CheckSystem().CheckOwnMember(target);
|
ctx.CheckSystem().CheckOwnMember(target);
|
||||||
|
var memberGuildConfig = await ctx.Repository.GetMemberGuild(ctx.Guild.Id, target.Id);
|
||||||
|
|
||||||
bool newValue;
|
bool newValue;
|
||||||
if (ctx.Match("on", "enabled", "true", "yes"))
|
if (ctx.Match("on", "enabled", "true", "yes"))
|
||||||
|
|
@ -510,12 +511,19 @@ public class MemberEdit
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
string keepProxyStatusMessage = "";
|
||||||
|
|
||||||
if (target.KeepProxy)
|
if (target.KeepProxy)
|
||||||
await ctx.Reply(
|
keepProxyStatusMessage += "This member has keepproxy **enabled**. Proxy tags will be **included** in the resulting message when proxying.";
|
||||||
"This member has keepproxy **enabled**, which means proxy tags will be **included** in the resulting message when proxying.");
|
|
||||||
else
|
else
|
||||||
await ctx.Reply(
|
keepProxyStatusMessage += "This member has keepproxy **disabled**. Proxy tags will **not** be included in the resulting message when proxying.";
|
||||||
"This member has keepproxy **disabled**, which means proxy tags will **not** be included in the resulting message when proxying.");
|
|
||||||
|
if (memberGuildConfig.KeepProxy.HasValue && 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.";
|
||||||
|
else if (memberGuildConfig.KeepProxy.HasValue && !memberGuildConfig.KeepProxy.Value)
|
||||||
|
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.";
|
||||||
|
|
||||||
|
await ctx.Reply(keepProxyStatusMessage);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -524,12 +532,88 @@ public class MemberEdit
|
||||||
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);
|
||||||
|
|
||||||
|
string keepProxyUpdateMessage = "";
|
||||||
|
|
||||||
if (newValue)
|
if (newValue)
|
||||||
await ctx.Reply(
|
keepProxyUpdateMessage += $"{Emojis.Success} this member now has keepproxy **enabled**. Member proxy tags will be **included** in the resulting message when proxying.";
|
||||||
$"{Emojis.Success} Member proxy tags will now be included in the resulting message when proxying.");
|
|
||||||
else
|
else
|
||||||
await ctx.Reply(
|
keepProxyUpdateMessage += $"{Emojis.Success} this member now has keepproxy **disabled**. Member proxy tags will be **included** in the resulting message when proxying.";
|
||||||
$"{Emojis.Success} Member proxy tags will now not be included in the resulting message when proxying.");
|
|
||||||
|
if (memberGuildConfig.KeepProxy.HasValue && 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.";
|
||||||
|
else if (memberGuildConfig.KeepProxy.HasValue && !memberGuildConfig.KeepProxy.Value)
|
||||||
|
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.";
|
||||||
|
|
||||||
|
await ctx.Reply(keepProxyUpdateMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task ServerKeepProxy(Context ctx, PKMember target)
|
||||||
|
{
|
||||||
|
ctx.CheckGuildContext();
|
||||||
|
ctx.CheckSystem().CheckOwnMember(target);
|
||||||
|
|
||||||
|
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\" or \"off\".");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (memberGuildConfig.KeepProxy.HasValue)
|
||||||
|
if (memberGuildConfig.KeepProxy.Value)
|
||||||
|
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.");
|
||||||
|
else
|
||||||
|
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.");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var noServerKeepProxySetMessage = "This member does not have a server keepproxy override set.";
|
||||||
|
if (target.KeepProxy)
|
||||||
|
noServerKeepProxySetMessage += " The global keepproxy is **enabled**, which means proxy tags will be **included** when proxying.";
|
||||||
|
else
|
||||||
|
noServerKeepProxySetMessage += " The global keepproxy is **disabled**, which means proxy tags will **not** be included when proxying.";
|
||||||
|
|
||||||
|
await ctx.Reply(noServerKeepProxySetMessage);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var patch = new MemberGuildPatch { KeepProxy = Partial<bool?>.Present(newValue) };
|
||||||
|
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**.");
|
||||||
|
else
|
||||||
|
await ctx.Reply(
|
||||||
|
$"{Emojis.Success} Member proxy tags will now **not** be included in the resulting message when proxying **in the current server**.");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var serverKeepProxyClearedMessage = $"{Emojis.Success} Cleared server keepproxy settings for this member.";
|
||||||
|
|
||||||
|
if (target.KeepProxy)
|
||||||
|
serverKeepProxyClearedMessage += " Member proxy tags will now be **included** in the resulting message when proxying.";
|
||||||
|
else
|
||||||
|
serverKeepProxyClearedMessage += " Member proxy tags will now **not** be included in the resulting message when proxying.";
|
||||||
|
|
||||||
|
await ctx.Reply(serverKeepProxyClearedMessage);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task Tts(Context ctx, PKMember target)
|
public async Task Tts(Context ctx, PKMember target)
|
||||||
|
|
|
||||||
|
|
@ -9,13 +9,22 @@ public struct ProxyMatch
|
||||||
public string? Content;
|
public string? Content;
|
||||||
public ProxyTag? ProxyTags;
|
public ProxyTag? ProxyTags;
|
||||||
|
|
||||||
|
private bool ShouldKeepProxy()
|
||||||
|
{
|
||||||
|
if (Member.ServerKeepProxy != null && Member.ServerKeepProxy.Value)
|
||||||
|
return true;
|
||||||
|
else if (Member.KeepProxy && !(Member.ServerKeepProxy != null && !Member.ServerKeepProxy.Value))
|
||||||
|
return true;
|
||||||
|
else return false;
|
||||||
|
}
|
||||||
|
|
||||||
public string? ProxyContent
|
public string? ProxyContent
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
// Add the proxy tags into the proxied message if that option is enabled
|
// Add the proxy tags into the proxied message if that option is enabled
|
||||||
// Also check if the member has any proxy tags - some cases autoproxy can return a member with no tags
|
// Also check if the member has any proxy tags - some cases autoproxy can return a member with no tags
|
||||||
if (Member.KeepProxy && Content != null && ProxyTags != null)
|
if (ShouldKeepProxy() && ProxyTags != null && Content != null)
|
||||||
return $"{ProxyTags.Value.Prefix}{Content}{ProxyTags.Value.Suffix}";
|
return $"{ProxyTags.Value.Prefix}{Content}{ProxyTags.Value.Suffix}";
|
||||||
|
|
||||||
return Content;
|
return Content;
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ public class ProxyMember
|
||||||
public IReadOnlyCollection<ProxyTag> ProxyTags { get; } = new ProxyTag[0];
|
public IReadOnlyCollection<ProxyTag> ProxyTags { get; } = new ProxyTag[0];
|
||||||
public bool KeepProxy { get; }
|
public bool KeepProxy { get; }
|
||||||
public bool Tts { get; }
|
public bool Tts { get; }
|
||||||
|
public bool? ServerKeepProxy { get; }
|
||||||
|
|
||||||
public string? ServerName { get; }
|
public string? ServerName { get; }
|
||||||
public string? DisplayName { get; }
|
public string? DisplayName { get; }
|
||||||
|
|
@ -44,4 +45,4 @@ public class ProxyMember
|
||||||
}
|
}
|
||||||
|
|
||||||
public string? ProxyAvatar(MessageContext ctx) => ServerAvatar ?? WebhookAvatar ?? Avatar ?? ctx.SystemGuildAvatar ?? ctx.SystemAvatar;
|
public string? ProxyAvatar(MessageContext ctx) => ServerAvatar ?? WebhookAvatar ?? Avatar ?? ctx.SystemGuildAvatar ?? ctx.SystemAvatar;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -69,6 +69,7 @@ create function proxy_members(account_id bigint, guild_id bigint)
|
||||||
proxy_tags proxy_tag[],
|
proxy_tags proxy_tag[],
|
||||||
keep_proxy bool,
|
keep_proxy bool,
|
||||||
tts bool,
|
tts bool,
|
||||||
|
server_keep_proxy bool,
|
||||||
|
|
||||||
server_name text,
|
server_name text,
|
||||||
display_name text,
|
display_name text,
|
||||||
|
|
@ -89,6 +90,7 @@ as $$
|
||||||
members.proxy_tags as proxy_tags,
|
members.proxy_tags as proxy_tags,
|
||||||
members.keep_proxy as keep_proxy,
|
members.keep_proxy as keep_proxy,
|
||||||
members.tts as tts,
|
members.tts as tts,
|
||||||
|
member_guild.keep_proxy as server_keep_proxy,
|
||||||
|
|
||||||
-- Name info
|
-- Name info
|
||||||
member_guild.display_name as server_name,
|
member_guild.display_name as server_name,
|
||||||
|
|
@ -154,4 +156,4 @@ begin
|
||||||
if not exists (select 1 from groups where hid = new_hid) then return new_hid; end if;
|
if not exists (select 1 from groups where hid = new_hid) then return new_hid; end if;
|
||||||
end loop;
|
end loop;
|
||||||
end
|
end
|
||||||
$$ language plpgsql volatile;
|
$$ language plpgsql volatile;
|
||||||
|
|
|
||||||
6
PluralKit.Core/Database/Migrations/40.sql
Normal file
6
PluralKit.Core/Database/Migrations/40.sql
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
-- database version 40
|
||||||
|
-- add per-server keepproxy toggle
|
||||||
|
|
||||||
|
alter table member_guild add column keep_proxy bool default null;
|
||||||
|
|
||||||
|
update info set schema_version = 40;
|
||||||
|
|
@ -9,7 +9,7 @@ namespace PluralKit.Core;
|
||||||
internal class DatabaseMigrator
|
internal class DatabaseMigrator
|
||||||
{
|
{
|
||||||
private const string RootPath = "PluralKit.Core.Database"; // "resource path" root for SQL files
|
private const string RootPath = "PluralKit.Core.Database"; // "resource path" root for SQL files
|
||||||
private const int TargetSchemaVersion = 39;
|
private const int TargetSchemaVersion = 40;
|
||||||
private readonly ILogger _logger;
|
private readonly ILogger _logger;
|
||||||
|
|
||||||
public DatabaseMigrator(ILogger logger)
|
public DatabaseMigrator(ILogger logger)
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ public class MemberGuildSettings
|
||||||
public ulong Guild { get; }
|
public ulong Guild { get; }
|
||||||
public string? DisplayName { get; }
|
public string? DisplayName { get; }
|
||||||
public string? AvatarUrl { get; }
|
public string? AvatarUrl { get; }
|
||||||
|
public bool? KeepProxy { get; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class MemberGuildExt
|
public static class MemberGuildExt
|
||||||
|
|
@ -19,6 +20,7 @@ public static class MemberGuildExt
|
||||||
|
|
||||||
o.Add("display_name", settings.DisplayName);
|
o.Add("display_name", settings.DisplayName);
|
||||||
o.Add("avatar_url", settings.AvatarUrl);
|
o.Add("avatar_url", settings.AvatarUrl);
|
||||||
|
o.Add("keep_proxy", settings.KeepProxy);
|
||||||
|
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,10 +10,12 @@ public class MemberGuildPatch: PatchObject
|
||||||
{
|
{
|
||||||
public Partial<string?> DisplayName { get; set; }
|
public Partial<string?> DisplayName { get; set; }
|
||||||
public Partial<string?> AvatarUrl { get; set; }
|
public Partial<string?> AvatarUrl { get; set; }
|
||||||
|
public Partial<bool?> KeepProxy { get; set; }
|
||||||
|
|
||||||
public override Query Apply(Query q) => q.ApplyPatch(wrapper => wrapper
|
public override Query Apply(Query q) => q.ApplyPatch(wrapper => wrapper
|
||||||
.With("display_name", DisplayName)
|
.With("display_name", DisplayName)
|
||||||
.With("avatar_url", AvatarUrl)
|
.With("avatar_url", AvatarUrl)
|
||||||
|
.With("keep_proxy", KeepProxy)
|
||||||
);
|
);
|
||||||
|
|
||||||
public new void AssertIsValid()
|
public new void AssertIsValid()
|
||||||
|
|
@ -36,6 +38,9 @@ public class MemberGuildPatch: PatchObject
|
||||||
if (o.ContainsKey("avatar_url"))
|
if (o.ContainsKey("avatar_url"))
|
||||||
patch.AvatarUrl = o.Value<string>("avatar_url").NullIfEmpty();
|
patch.AvatarUrl = o.Value<string>("avatar_url").NullIfEmpty();
|
||||||
|
|
||||||
|
if (o.ContainsKey("keep_proxy"))
|
||||||
|
patch.KeepProxy = o.Value<bool>("keep_proxy");
|
||||||
|
|
||||||
return patch;
|
return patch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -51,6 +56,9 @@ public class MemberGuildPatch: PatchObject
|
||||||
if (AvatarUrl.IsPresent)
|
if (AvatarUrl.IsPresent)
|
||||||
o.Add("avatar_url", AvatarUrl.Value);
|
o.Add("avatar_url", AvatarUrl.Value);
|
||||||
|
|
||||||
|
if (KeepProxy.IsPresent)
|
||||||
|
o.Add("keep_proxy", KeepProxy.Value);
|
||||||
|
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -92,6 +92,7 @@ You can have a space after `pk;`, e.g. `pk;system` and `pk; system` will do the
|
||||||
- `pk;member <member> proxy remove [tags]` - Removes a proxy tag from a member.
|
- `pk;member <member> proxy remove [tags]` - Removes a proxy tag from a member.
|
||||||
- `pk;member <member> autoproxy [on|off]` - Sets whether a member will be autoproxied when autoproxy is set to latch or front mode.
|
- `pk;member <member> autoproxy [on|off]` - Sets whether a member will be autoproxied when autoproxy is set to latch or front mode.
|
||||||
- `pk;member <member> keepproxy [on|off]` - Sets whether to include a member's proxy tags in the proxied message.
|
- `pk;member <member> keepproxy [on|off]` - Sets whether to include a member's proxy tags in the proxied message.
|
||||||
|
- `pk;member <member> serverkeepproxy [on|off]` - Sets whether to include a member's proxy tag in the proxied message in a specific server.
|
||||||
- `pk;member <member> tts [on|off]` - Sets whether to send a member's messages as text-to-speech messages.
|
- `pk;member <member> tts [on|off]` - Sets whether to send a member's messages as text-to-speech messages.
|
||||||
- `pk;member <member> pronouns [pronouns]` - Changes the pronouns of a member.
|
- `pk;member <member> pronouns [pronouns]` - Changes the pronouns of a member.
|
||||||
- `pk;member <member> color [color]` - Changes the color of a member.
|
- `pk;member <member> color [color]` - Changes the color of a member.
|
||||||
|
|
@ -180,4 +181,4 @@ You can have a space after `pk;`, e.g. `pk;system` and `pk; system` will do the
|
||||||
- `pk;system help` - Lists system-related commands.
|
- `pk;system help` - Lists system-related commands.
|
||||||
- `pk;member help` - Lists member-related commands.
|
- `pk;member help` - Lists member-related commands.
|
||||||
- `pk;switch help` - Lists switch-related commands.
|
- `pk;switch help` - Lists switch-related commands.
|
||||||
- `pk;commands` - Shows inline command documentation, or directs you to this page.
|
- `pk;commands` - Shows inline command documentation, or directs you to this page.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue