Add autoproxy management commands
This commit is contained in:
		| @@ -111,6 +111,7 @@ namespace PluralKit.Bot | ||||
|             .AddTransient<HelpCommands>() | ||||
|             .AddTransient<ModCommands>() | ||||
|             .AddTransient<MiscCommands>() | ||||
|             .AddTransient<AutoproxyCommands>() | ||||
|              | ||||
|             .AddTransient<EmbedService>() | ||||
|             .AddTransient<ProxyService>() | ||||
|   | ||||
							
								
								
									
										139
									
								
								PluralKit.Bot/Commands/AutoproxyCommands.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										139
									
								
								PluralKit.Bot/Commands/AutoproxyCommands.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,139 @@ | ||||
| using System; | ||||
| using System.Linq; | ||||
| using System.Threading.Tasks; | ||||
|  | ||||
| using Discord; | ||||
|  | ||||
| using PluralKit.Bot.CommandSystem; | ||||
|  | ||||
| namespace PluralKit.Bot.Commands | ||||
| { | ||||
|     public class AutoproxyCommands | ||||
|     { | ||||
|         private IDataStore _data; | ||||
|  | ||||
|         public AutoproxyCommands(IDataStore data) | ||||
|         { | ||||
|             _data = data; | ||||
|         } | ||||
|  | ||||
|         public async Task Autoproxy(Context ctx) | ||||
|         { | ||||
|             ctx.CheckSystem().CheckGuildContext(); | ||||
|              | ||||
|             if (ctx.Match("off", "stop", "cancel", "no")) | ||||
|                 await AutoproxyOff(ctx); | ||||
|             else if (ctx.Match("latch", "last", "proxy", "stick", "sticky")) | ||||
|                 await AutoproxyLatch(ctx); | ||||
|             else if (ctx.Match("front", "fronter", "switch")) | ||||
|                 await AutoproxyFront(ctx); | ||||
|             else if (ctx.Match("member")) | ||||
|                 throw new PKSyntaxError("Member-mode autoproxy must target a specific member. Use the `pk;autoproxy <member>` command, where `member` is the name or ID of a member in your system."); | ||||
|             else if (await ctx.MatchMember() is PKMember member) | ||||
|                 await AutoproxyMember(ctx, member); | ||||
|             else if (!ctx.HasNext()) | ||||
|                 await ctx.Reply(embed: await CreateAutoproxyStatusEmbed(ctx)); | ||||
|             else | ||||
|                 throw new PKSyntaxError($"Invalid autoproxy mode `{ctx.PopArgument().EscapeMarkdown()}`."); | ||||
|         } | ||||
|  | ||||
|         private async Task AutoproxyOff(Context ctx) | ||||
|         { | ||||
|             var settings = await _data.GetSystemGuildSettings(ctx.System, ctx.Guild.Id); | ||||
|             if (settings.AutoproxyMode == AutoproxyMode.Off) | ||||
|             { | ||||
|                 await ctx.Reply($"{Emojis.Note} Autoproxy is already off in this server."); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 settings.AutoproxyMode = AutoproxyMode.Off; | ||||
|                 settings.AutoproxyMember = null; | ||||
|                 await _data.SetSystemGuildSettings(ctx.System, ctx.Guild.Id, settings); | ||||
|                 await ctx.Reply($"{Emojis.Success} Autoproxy turned off in this server."); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         private async Task AutoproxyLatch(Context ctx) | ||||
|         { | ||||
|             var settings = await _data.GetSystemGuildSettings(ctx.System, ctx.Guild.Id); | ||||
|             if (settings.AutoproxyMode == AutoproxyMode.Latch) | ||||
|             { | ||||
|                 await ctx.Reply($"{Emojis.Note} Autoproxy is already set to latch mode in this server. If you want to disable autoproxying, use `pk;autoproxy off`."); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 settings.AutoproxyMode = AutoproxyMode.Latch; | ||||
|                 settings.AutoproxyMember = null; | ||||
|                 await _data.SetSystemGuildSettings(ctx.System, ctx.Guild.Id, settings); | ||||
|                 await ctx.Reply($"{Emojis.Success} Autoproxy set to latch mode in this server. Messages will now be autoproxied using the *last-proxied member* in this server."); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         private async Task AutoproxyFront(Context ctx) | ||||
|         { | ||||
|             var settings = await _data.GetSystemGuildSettings(ctx.System, ctx.Guild.Id); | ||||
|             if (settings.AutoproxyMode == AutoproxyMode.Front) | ||||
|             { | ||||
|                 await ctx.Reply($"{Emojis.Note} Autoproxy is already set to front mode in this server. If you want to disable autoproxying, use `pk;autoproxy off`."); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 settings.AutoproxyMode = AutoproxyMode.Front; | ||||
|                 settings.AutoproxyMember = null; | ||||
|                 await _data.SetSystemGuildSettings(ctx.System, ctx.Guild.Id, settings); | ||||
|                 await ctx.Reply($"{Emojis.Success} Autoproxy set to front mode in this server. Messages will now be autoproxied using the *current first fronter*, if any."); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         private async Task AutoproxyMember(Context ctx, PKMember member) | ||||
|         { | ||||
|             ctx.CheckOwnMember(member); | ||||
|              | ||||
|             var settings = await _data.GetSystemGuildSettings(ctx.System, ctx.Guild.Id); | ||||
|             settings.AutoproxyMode = AutoproxyMode.Member; | ||||
|             settings.AutoproxyMember = member.Id; | ||||
|             await _data.SetSystemGuildSettings(ctx.System, ctx.Guild.Id, settings); | ||||
|  | ||||
|             await ctx.Reply($"{Emojis.Success} Autoproxy set to **{member.Name}** in this server."); | ||||
|         } | ||||
|  | ||||
|         private async Task<Embed> CreateAutoproxyStatusEmbed(Context ctx) | ||||
|         { | ||||
|             var settings = await _data.GetSystemGuildSettings(ctx.System, ctx.Guild.Id); | ||||
|  | ||||
|             var commandList = "**pk;autoproxy latch** - Autoproxies as last-proxied member\n**pk;autoproxy front** - Autoproxies as current (first) fronter\n**pk;autoproxy <member>** - Autoproxies as a specific member"; | ||||
|             var eb = new EmbedBuilder().WithTitle($"Current autoproxy status (for {ctx.Guild.Name.EscapeMarkdown()})"); | ||||
|  | ||||
|             switch (settings.AutoproxyMode) { | ||||
|                 case AutoproxyMode.Off: eb.WithDescription($"Autoproxy is currently **off** in this server. To enable it, use one of the following commands:\n{commandList}"); | ||||
|                     break; | ||||
|                 case AutoproxyMode.Front: { | ||||
|                     var lastSwitch = await _data.GetLatestSwitch(ctx.System); | ||||
|                     if (lastSwitch == null) | ||||
|                         eb.WithDescription("Autoproxy is currently set to **front mode** in this server, but you have no registered switches. Use the `pk;switch` command to log one."); | ||||
|                     else | ||||
|                     { | ||||
|                         var firstMember = await _data.GetSwitchMembers(lastSwitch).FirstOrDefaultAsync(); | ||||
|                         eb.WithDescription(firstMember == null | ||||
|                             ? "Autoproxy is currently set to **front mode** in this server, but there are currently no fronters registered." | ||||
|                             : $"Autoproxy is currently set to **front mode** in this server. The current (first) fronter is **{firstMember.Name.EscapeMarkdown()}** (`{firstMember.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 settings.AutoproxyMember != null: { | ||||
|                     var member = await _data.GetMemberById(settings.AutoproxyMember.Value); | ||||
|                     eb.WithDescription($"Autoproxy is active for member **{member.Name}** (`{member.Hid}`) in this server. To disable, type `pk;autoproxy off`."); | ||||
|                     break; | ||||
|                 } | ||||
|                 case AutoproxyMode.Latch: | ||||
|                     eb.WithDescription($"Autoproxy is currently set to **latch mode**, meaning the *last-proxied member* will be autoproxied. To disable, type `pk;autoproxy off`."); | ||||
|                     break; | ||||
|                 default: throw new ArgumentOutOfRangeException(); | ||||
|             } | ||||
|  | ||||
|             return eb.Build(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -23,6 +23,7 @@ namespace PluralKit.Bot.Commands | ||||
|         public static Command SystemFrontHistory = new Command("system fronthistory", "system [system] fronthistory", "Shows a system's front history"); | ||||
|         public static Command SystemFrontPercent = new Command("system frontpercent", "system [system] frontpercent [timespan]", "Shows a system's front breakdown"); | ||||
|         public static Command SystemPrivacy = new Command("system privacy", "system privacy <description|members|fronter|fronthistory> <public|private>", "Changes your system's privacy settings"); | ||||
|         public static Command Autoproxy = new Command("autoproxy", "autoproxy [off|front|latch|member]", "Sets your system's autoproxy mode for this server"); | ||||
|         public static Command MemberInfo = new Command("member", "member <member>", "Looks up information about a member"); | ||||
|         public static Command MemberNew = new Command("member new", "member new <name>", "Creates a new member"); | ||||
|         public static Command MemberRename = new Command("member rename", "member <member> rename <new name>", "Renames a member"); | ||||
| @@ -87,6 +88,8 @@ namespace PluralKit.Bot.Commands | ||||
|                 return HandleMemberCommand(ctx); | ||||
|             if (ctx.Match("switch", "sw")) | ||||
|                 return HandleSwitchCommand(ctx); | ||||
|             if (ctx.Match("ap", "autoproxy", "auto")) | ||||
|                 return ctx.Execute<AutoproxyCommands>(Autoproxy, m => m.Autoproxy(ctx)); | ||||
|             if (ctx.Match("link")) | ||||
|                 return ctx.Execute<LinkCommands>(Link, m => m.LinkSystem(ctx)); | ||||
|             if (ctx.Match("unlink")) | ||||
|   | ||||
| @@ -6,8 +6,10 @@ | ||||
| alter table system_guild add column autoproxy_mode int check (autoproxy_mode in (1, 2, 3, 4)) not null default 1; | ||||
|  | ||||
| -- for member mode | ||||
| alter table system_guild add column autoproxy_member nullable references members (id) on delete set null; | ||||
| alter table system_guild add column autoproxy_member int references members (id) on delete set null; | ||||
|  | ||||
| -- for latch mode | ||||
| -- not *really* nullable, null just means old (pre-schema-change) data. | ||||
| alter table messages add column guild bigint nullable default null; | ||||
| alter table messages add column guild bigint default null; | ||||
|  | ||||
| update info set schema_version = 3; | ||||
| @@ -10,7 +10,7 @@ using Serilog; | ||||
| namespace PluralKit { | ||||
|     public class SchemaService | ||||
|     { | ||||
|         private const int TargetSchemaVersion = 2; | ||||
|         private const int TargetSchemaVersion = 3; | ||||
|  | ||||
|         private DbConnectionFactory _conn; | ||||
|         private ILogger _logger; | ||||
|   | ||||
| @@ -77,9 +77,9 @@ namespace PluralKit { | ||||
|     public class SystemGuildSettings | ||||
|     { | ||||
|         public bool ProxyEnabled { get; set; } = true; | ||||
|          | ||||
|         public AutoproxyMode AutoproxyMode { get; set; } | ||||
|         public int AutoproxyMember { get; set; } | ||||
|  | ||||
|         public AutoproxyMode AutoproxyMode { get; set; } = AutoproxyMode.Off; | ||||
|         public int? AutoproxyMember { get; set; } | ||||
|     } | ||||
|  | ||||
|     public class MemberGuildSettings | ||||
| @@ -446,11 +446,13 @@ namespace PluralKit { | ||||
|         public async Task SetSystemGuildSettings(PKSystem system, ulong guild, SystemGuildSettings settings) | ||||
|         { | ||||
|             using (var conn = await _conn.Obtain()) | ||||
|                 await conn.ExecuteAsync("insert into system_guild (system, guild, proxy_enabled) values (@System, @Guild, @ProxyEnabled) on conflict (system, guild) do update set proxy_enabled = @ProxyEnabled", new | ||||
|                 await conn.ExecuteAsync("insert into system_guild (system, guild, proxy_enabled, autoproxy_mode, autoproxy_member) values (@System, @Guild, @ProxyEnabled, @AutoproxyMode, @AutoproxyMember) on conflict (system, guild) do update set proxy_enabled = @ProxyEnabled, autoproxy_mode = @AutoproxyMode, autoproxy_member = @AutoproxyMember", new | ||||
|                 { | ||||
|                     System = system.Id, | ||||
|                     Guild = guild, | ||||
|                     ProxyEnabled = settings.ProxyEnabled | ||||
|                     settings.ProxyEnabled, | ||||
|                     settings.AutoproxyMode, | ||||
|                     settings.AutoproxyMember | ||||
|                 }); | ||||
|         } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user