2020-12-08 11:57:17 +00:00
using Humanizer ;
2020-12-24 13:52:44 +00:00
using Myriad.Builders ;
using Myriad.Types ;
2020-12-08 11:57:17 +00:00
using NodaTime ;
2020-02-12 14:16:19 +00:00
using PluralKit.Core ;
2020-01-23 20:20:22 +00:00
2021-11-27 02:10:56 +00:00
namespace PluralKit.Bot ;
public class Autoproxy
2020-01-23 20:20:22 +00:00
{
2021-11-27 02:10:56 +00:00
public async Task SetAutoproxyMode ( Context ctx )
{
// no need to check account here, it's already done at CommandTree
ctx . CheckGuildContext ( ) ;
if ( ctx . Match ( "off" , "stop" , "cancel" , "no" , "disable" , "remove" ) )
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().AsCode()}." ) ;
}
private async Task AutoproxyOff ( Context ctx )
{
if ( ctx . MessageContext . AutoproxyMode = = AutoproxyMode . Off )
2020-01-23 20:20:22 +00:00
{
2021-11-27 02:10:56 +00:00
await ctx . Reply ( $"{Emojis.Note} Autoproxy is already off in this server." ) ;
2020-01-23 20:20:22 +00:00
}
2021-11-27 02:10:56 +00:00
else
2020-01-23 20:20:22 +00:00
{
2021-11-27 02:10:56 +00:00
await UpdateAutoproxy ( ctx , AutoproxyMode . Off , null ) ;
await ctx . Reply ( $"{Emojis.Success} Autoproxy turned off in this server." ) ;
2020-01-23 20:20:22 +00:00
}
2021-11-27 02:10:56 +00:00
}
2020-01-23 20:20:22 +00:00
2021-11-27 02:10:56 +00:00
private async Task AutoproxyLatch ( Context ctx )
{
if ( ctx . MessageContext . AutoproxyMode = = AutoproxyMode . Latch )
2020-01-23 20:20:22 +00:00
{
2021-11-27 02:10:56 +00:00
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`." ) ;
2020-01-23 20:20:22 +00:00
}
2021-11-27 02:10:56 +00:00
else
2020-01-23 20:20:22 +00:00
{
2021-11-27 02:10:56 +00:00
await UpdateAutoproxy ( ctx , AutoproxyMode . Latch , null ) ;
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." ) ;
2020-01-23 20:20:22 +00:00
}
2021-11-27 02:10:56 +00:00
}
2020-01-23 20:20:22 +00:00
2021-11-27 02:10:56 +00:00
private async Task AutoproxyFront ( Context ctx )
{
if ( ctx . MessageContext . AutoproxyMode = = AutoproxyMode . Front )
2020-01-23 20:20:22 +00:00
{
2021-11-27 02:10:56 +00:00
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`." ) ;
2020-01-23 20:20:22 +00:00
}
2021-11-27 02:10:56 +00:00
else
2020-01-23 20:20:22 +00:00
{
2021-11-27 02:10:56 +00:00
await UpdateAutoproxy ( ctx , AutoproxyMode . Front , null ) ;
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." ) ;
2020-01-23 20:20:22 +00:00
}
2021-11-27 02:10:56 +00:00
}
2020-01-23 20:20:22 +00:00
2021-11-27 02:10:56 +00:00
private async Task AutoproxyMember ( Context ctx , PKMember member )
{
ctx . CheckOwnMember ( member ) ;
2021-08-27 15:03:47 +00:00
2021-11-27 02:10:56 +00:00
await UpdateAutoproxy ( ctx , AutoproxyMode . Member , member . Id ) ;
await ctx . Reply ( $"{Emojis.Success} Autoproxy set to **{member.NameFor(ctx)}** in this server." ) ;
}
2020-01-23 20:20:22 +00:00
2021-11-27 02:10:56 +00:00
private async Task < Embed > CreateAutoproxyStatusEmbed ( Context ctx )
{
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 ( )
. Title ( $"Current autoproxy status (for {ctx.Guild.Name.EscapeMarkdown()})" ) ;
var fronters = ctx . MessageContext . LastSwitchMembers ;
var relevantMember = ctx . MessageContext . AutoproxyMode switch
{
2022-01-22 08:05:01 +00:00
AutoproxyMode . Front = > fronters . Length > 0 ? await ctx . Repository . GetMember ( fronters [ 0 ] ) : null ,
AutoproxyMode . Member = > await ctx . Repository . GetMember ( ctx . MessageContext . AutoproxyMember . Value ) ,
2021-11-27 02:10:56 +00:00
_ = > null
} ;
switch ( ctx . MessageContext . AutoproxyMode )
{
case AutoproxyMode . Off :
eb . Description ( $"Autoproxy is currently **off** in this server. To enable it, use one of the following commands:\n{commandList}" ) ;
break ;
case AutoproxyMode . Front :
{
if ( fronters . Length = = 0 )
2020-01-23 20:20:22 +00:00
{
2021-11-27 02:10:56 +00:00
eb . Description ( "Autoproxy is currently set to **front mode** in this server, but there are currently no fronters registered. Use the `pk;switch` command to log a switch." ) ;
2020-01-23 20:20:22 +00:00
}
2021-11-27 02:10:56 +00:00
else
2021-08-27 15:03:47 +00:00
{
2021-11-27 02:10:56 +00:00
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 . Description ( $"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`." ) ;
2021-08-27 15:03:47 +00:00
}
2021-11-27 02:10:56 +00:00
2020-01-23 20:20:22 +00:00
break ;
2021-11-27 02:10:56 +00:00
}
// AutoproxyMember is never null if Mode is Member, this is just to make the compiler shut up
case AutoproxyMode . Member when relevantMember ! = null :
{
eb . Description ( $"Autoproxy is active for member **{relevantMember.NameFor(ctx)}** (`{relevantMember.Hid}`) in this server. To disable, type `pk;autoproxy off`." ) ;
break ;
}
case AutoproxyMode . Latch :
eb . Description ( "Autoproxy is currently set to **latch mode**, meaning the *last-proxied member* will be autoproxied. To disable, type `pk;autoproxy off`." ) ;
break ;
2021-08-27 15:03:47 +00:00
2021-11-27 02:10:56 +00:00
default : throw new ArgumentOutOfRangeException ( ) ;
}
2020-01-23 20:20:22 +00:00
2021-11-27 02:10:56 +00:00
if ( ! ctx . MessageContext . AllowAutoproxy )
eb . Field ( new Embed . Field ( "\u200b" , $"{Emojis.Note} Autoproxy is currently **disabled** for your account (<@{ctx.Author.Id}>). To enable it, use `pk;autoproxy account enable`." ) ) ;
2020-11-20 23:34:08 +00:00
2021-11-27 02:10:56 +00:00
return eb . Build ( ) ;
}
private async Task UpdateAutoproxy ( Context ctx , AutoproxyMode autoproxyMode , MemberId ? autoproxyMember )
{
2022-01-22 08:05:01 +00:00
await ctx . Repository . GetSystemGuild ( ctx . Guild . Id , ctx . System . Id ) ;
2021-11-27 02:10:56 +00:00
var patch = new SystemGuildPatch { AutoproxyMode = autoproxyMode , AutoproxyMember = autoproxyMember } ;
2022-01-22 08:05:01 +00:00
await ctx . Repository . UpdateSystemGuild ( ctx . System . Id , ctx . Guild . Id , patch ) ;
2020-01-23 20:20:22 +00:00
}
}