Add server-specific system tag

This commit is contained in:
spiral 2021-08-02 17:22:06 -04:00
parent 28bcb35bb2
commit 9d4006b056
No known key found for this signature in database
GPG Key ID: A6059F0CA0E1BD31
11 changed files with 163 additions and 7 deletions

View File

@ -15,6 +15,7 @@ namespace PluralKit.Bot
public static Command SystemDesc = new Command("system description", "system description [description]", "Changes your system's description");
public static Command SystemColor = new Command("system color", "system color [color]", "Changes your system's color");
public static Command SystemTag = new Command("system tag", "system tag [tag]", "Changes your system's tag");
public static Command SystemServerTag = new Command("system servertag", "system servertag [tag|enable|disable]", "Changes your system's tag in the current server");
public static Command SystemAvatar = new Command("system icon", "system icon [url|@mention]", "Changes your system's icon");
public static Command SystemBannerImage = new Command("system banner", "system banner [url]", "Set the system's banner image");
public static Command SystemDelete = new Command("system delete", "system delete", "Deletes your system");
@ -243,6 +244,8 @@ namespace PluralKit.Bot
await ctx.Execute<SystemEdit>(SystemRename, m => m.Name(ctx));
else if (ctx.Match("tag"))
await ctx.Execute<SystemEdit>(SystemTag, m => m.Tag(ctx));
else if (ctx.Match("servertag"))
await ctx.Execute<SystemEdit>(SystemServerTag, m => m.ServerTag(ctx));
else if (ctx.Match("description", "desc", "bio"))
await ctx.Execute<SystemEdit>(SystemDesc, m => m.Description(ctx));
else if (ctx.Match("color", "colour"))

View File

@ -157,7 +157,7 @@ namespace PluralKit.Bot
var newTag = ctx.RemainderOrNull(skipFlags: false);
if (newTag != null)
if (newTag.Length > Limits.MaxSystemTagLength)
throw Errors.SystemNameTooLongError(newTag.Length);
throw Errors.SystemTagTooLongError(newTag.Length);
var patch = new SystemPatch {Tag = newTag};
await _db.Execute(conn => _repo.UpdateSystem(conn, ctx.System.Id, patch));
@ -165,6 +165,107 @@ namespace PluralKit.Bot
await ctx.Reply($"{Emojis.Success} System tag changed. Member names will now end with {newTag.AsCode()} when proxied.");
}
}
public async Task ServerTag(Context ctx)
{
ctx.CheckSystem().CheckGuildContext();
var setDisabledWarning = $"{Emojis.Warn} Your system tag is currently **disabled** in this server. No tag will be applied when proxying.\nTo re-enable the system tag in the current server, type `pk;s servertag -enable`.";
async Task Show()
{
if (ctx.MessageContext.SystemGuildTag != null)
{
var msg = $"Your current system tag in '{ctx.Guild.Name}' is {ctx.MessageContext.SystemGuildTag.AsCode()}";
if (!ctx.MessageContext.TagEnabled)
msg += ", but it is currently **disabled**. To re-enable it, type `pk;s servertag -enable`.";
else
msg += ". To change it, type `pk;s tag <tag>`. To clear it, type `pk;s tag -clear`.";
await ctx.Reply(msg);
return;
}
else if (!ctx.MessageContext.TagEnabled)
await ctx.Reply($"Your global system tag is {ctx.System.Tag}, but it is **disabled** in this server. To re-enable it, type `pk;s servertag -enable`");
else
await ctx.Reply($"You currently have no system tag specific to the server '{ctx.Guild.Name}'. To set one, type `pk;s servertag <tag>`. To disable the system tag in the current server, type `pk;s servertag -disable`.");
}
async Task Set()
{
var newTag = ctx.RemainderOrNull(skipFlags: false);
if (newTag != null && newTag.Length > Limits.MaxSystemTagLength)
throw Errors.SystemTagTooLongError(newTag.Length);
var patch = new SystemGuildPatch {Tag = newTag};
await _db.Execute(conn => _repo.UpsertSystemGuild(conn, ctx.System.Id, ctx.Guild.Id, patch));
await ctx.Reply($"{Emojis.Success} System server tag changed. Member names will now end with {newTag.AsCode()} when proxied in the current server '{ctx.Guild.Name}'.");
if (!ctx.MessageContext.TagEnabled)
await ctx.Reply(setDisabledWarning);
}
async Task Clear()
{
var patch = new SystemGuildPatch {Tag = null};
await _db.Execute(conn => _repo.UpsertSystemGuild(conn, ctx.System.Id, ctx.Guild.Id, patch));
await ctx.Reply($"{Emojis.Success} System server tag cleared. Member names will now end with the global system tag, if there is one set.");
if (!ctx.MessageContext.TagEnabled)
await ctx.Reply(setDisabledWarning);
}
async Task EnableDisable(bool newValue)
{
var patch = new SystemGuildPatch {TagEnabled = newValue};
await _db.Execute(conn => _repo.UpsertSystemGuild(conn, ctx.System.Id, ctx.Guild.Id, patch));
await ctx.Reply(PrintEnableDisableResult(newValue, newValue != ctx.MessageContext.TagEnabled));
}
string PrintEnableDisableResult(bool newValue, bool changedValue)
{
var opStr = newValue ? "enabled" : "disabled";
var str = "";
if (!changedValue)
str = $"{Emojis.Note} The system tag is already {opStr} in this server.";
else
str = $"{Emojis.Success} System tag {opStr} in this server.";
if (newValue == true)
{
if (ctx.MessageContext.TagEnabled)
if (ctx.MessageContext.SystemGuildTag == null)
str += $" However, you do not have a system tag specific to this server. Messages will be proxied using your global system tag, if there is one set.";
else
str += $" Your current system tag in '{ctx.Guild.Name}' is {ctx.MessageContext.SystemGuildTag.AsCode()}.";
else
{
if (ctx.MessageContext.SystemGuildTag != null)
str += $" Member names will now end with the server-specific tag {ctx.MessageContext.SystemGuildTag.AsCode()} when proxied in the current server '{ctx.Guild.Name}'.";
else
str += $" Member names will now end with the global system tag when proxied in the current server, if there is one set.";
}
}
return str;
}
if (await ctx.MatchClear("your system's server tag"))
await Clear();
else if (ctx.Match("disable") || ctx.MatchFlag("disable"))
await EnableDisable(false);
else if (ctx.Match("enable") || ctx.MatchFlag("enable"))
await EnableDisable(true);
else if (!ctx.HasNext(skipFlags: false))
await Show();
else
await Set();
}
public async Task Avatar(Context ctx)
{

View File

@ -84,6 +84,12 @@ namespace PluralKit.Bot {
if (system.Tag != null)
eb.Field(new("Tag", system.Tag.EscapeMarkdown(), true));
if (cctx.MessageContext.SystemGuildTag != null && cctx.MessageContext.TagEnabled)
eb.Field(new($"Tag (in server '{cctx.Guild.Name}')", cctx.MessageContext.SystemGuildTag.EscapeMarkdown(), true));
if (!cctx.MessageContext.TagEnabled)
eb.Field(new($"Tag (in server '{cctx.Guild.Name}')", "*(tag is disabled in this server)*"));
if (!system.Color.EmptyOrNull()) eb.Field(new("Color", $"#{system.Color}", true));
eb.Field(new("Linked accounts", string.Join("\n", users).Truncate(1000), true));

View File

@ -23,6 +23,8 @@ namespace PluralKit.Core
public MemberId[] LastSwitchMembers { get; } = new MemberId[0];
public Instant? LastSwitchTimestamp { get; }
public string? SystemTag { get; }
public string? SystemGuildTag { get; }
public bool TagEnabled { get; }
public string? SystemAvatar { get; }
public bool AllowAutoproxy { get; }
public int? LatchTimeout { get; }

View File

@ -23,10 +23,18 @@ namespace PluralKit.Core
public bool AllowAutoproxy { get; }
public string? Color { get; }
public string ProxyName(MessageContext ctx) => ctx.SystemTag != null
? $"{ServerName ?? DisplayName ?? Name} {ctx.SystemTag}"
: ServerName ?? DisplayName ?? Name;
public string ProxyName(MessageContext ctx)
{
var memberName = ServerName ?? DisplayName ?? Name;
if (!ctx.TagEnabled)
return memberName;
if (ctx.SystemGuildTag != null)
return $"{memberName} {ctx.SystemGuildTag}";
else if (ctx.SystemTag != null)
return $"{memberName} {ctx.SystemTag}";
else return memberName;
}
public string? ProxyAvatar(MessageContext ctx) => ServerAvatar ?? Avatar ?? ctx.SystemAvatar;
public ProxyMember() { }

View File

@ -14,6 +14,8 @@
last_switch_members int[],
last_switch_timestamp timestamp,
system_tag text,
system_guild_tag text,
tag_enabled bool,
system_avatar text,
allow_autoproxy bool,
latch_timeout integer
@ -21,7 +23,10 @@
as $$
-- CTEs to query "static" (accessible only through args) data
with
system as (select systems.*, allow_autoproxy as account_autoproxy from accounts inner join systems on systems.id = accounts.system where accounts.uid = account_id),
system as (select systems.*, system_guild.tag as guild_tag, system_guild.tag_enabled as tag_enabled, allow_autoproxy as account_autoproxy from accounts
left join systems on systems.id = accounts.system
left join system_guild on system_guild.system = accounts.system and system_guild.guild = guild_id
where accounts.uid = account_id),
guild as (select * from servers where id = guild_id),
last_message as (select * from messages where messages.guild = guild_id and messages.sender = account_id order by mid desc limit 1)
select
@ -39,6 +44,8 @@ as $$
system_last_switch.members as last_switch_members,
system_last_switch.timestamp as last_switch_timestamp,
system.tag as system_tag,
system.guild_tag as system_guild_tag,
system.tag_enabled as tag_enabled,
system.avatar_url as system_avatar,
system.account_autoproxy as allow_autoproxy,
system.latch_timeout as latch_timeout

View File

@ -0,0 +1,7 @@
-- SCHEMA VERSION 16: 2021-08-02 --
-- Add server-specific system tag --
alter table system_guild add column tag text default null;
alter table system_guild add column tag_enabled bool not null default true;
update info set schema_version = 16;

View File

@ -12,7 +12,7 @@ namespace PluralKit.Core
internal class DatabaseMigrator
{
private const string RootPath = "PluralKit.Core.Database"; // "resource path" root for SQL files
private const int TargetSchemaVersion = 15;
private const int TargetSchemaVersion = 16;
private readonly ILogger _logger;
public DatabaseMigrator(ILogger logger)

View File

@ -6,10 +6,14 @@ namespace PluralKit.Core
public Partial<bool> ProxyEnabled { get; set; }
public Partial<AutoproxyMode> AutoproxyMode { get; set; }
public Partial<MemberId?> AutoproxyMember { get; set; }
public Partial<string?> Tag { get; set; }
public Partial<bool?> TagEnabled { get; set; }
public override UpdateQueryBuilder Apply(UpdateQueryBuilder b) => b
.With("proxy_enabled", ProxyEnabled)
.With("autoproxy_mode", AutoproxyMode)
.With("autoproxy_member", AutoproxyMember);
.With("autoproxy_member", AutoproxyMember)
.With("tag", Tag)
.With("tag_enabled", TagEnabled);
}
}

View File

@ -42,6 +42,7 @@ Some arguments indicate the use of specific Discord features. These include:
- `pk;system privacy` - Displays your system's current privacy settings.
- `pk;system privacy <subject> <public|private>` - Changes your systems privacy settings.
- `pk;system tag [tag]` - Changes the system tag of your system.
- `pk;system servertag [tag|-enable|-disable]` - Changes your system's tag in the current server, or disables it for the current server.
- `pk;system timezone [location]` - Changes the time zone of your system.
- `pk;system proxy [server id] [on|off]` - Toggles message proxying for a specific server.
- `pk;system delete` - Deletes your system.

View File

@ -74,6 +74,23 @@ If you want to remove your system tag, just type `pk;system tag` with no extra p
to bump it over that limit. PluralKit will warn you if you have a member name/tag combination that will bring the combined username above the limit.
You can either make the member name or the system tag shorter to solve this.
### System server tags
If you'd like to set a system tag (as above), but only for a specific server, you can set the *system server tag*. This will override the global system tag, but only in the server you set it in. For example:
```
pk;system servertag 🛰️
```
The server tag applies to the same server you run the command in, so this command doesn't function in DMs.
To remove an existing server-specific system tag, use the command `pk;system servertag -clear`.
::: tip
It is possible to disable the system tag for a specific server. Use the command `pk;system servertag -disable`.
To re-enable it, use the command `pk;system servertag -enable`.
:::
### Adding or removing Discord accounts to the system
If you have multiple Discord accounts you want to use the same system on, you don't need to create multiple systems.
Instead, you can *link* the same system to multiple accounts.