2020-02-01 12:03:02 +00:00
using System.Linq ;
using System.Threading.Tasks ;
2020-08-04 22:43:17 +00:00
using System.Collections.Generic ;
2020-02-01 12:03:02 +00:00
using PluralKit.Core ;
2020-02-12 14:16:19 +00:00
namespace PluralKit.Bot
2020-02-01 12:03:02 +00:00
{
public class Member
{
2020-08-29 11:46:27 +00:00
private readonly IDatabase _db ;
private readonly ModelRepository _repo ;
private readonly EmbedService _embeds ;
2020-02-01 13:40:57 +00:00
2020-08-29 11:46:27 +00:00
public Member ( EmbedService embeds , IDatabase db , ModelRepository repo )
2020-02-01 12:03:02 +00:00
{
_embeds = embeds ;
2020-06-13 17:42:04 +00:00
_db = db ;
2020-08-29 11:46:27 +00:00
_repo = repo ;
2020-02-01 12:03:02 +00:00
}
public async Task NewMember ( Context ctx ) {
if ( ctx . System = = null ) throw Errors . NoSystemError ;
var memberName = ctx . RemainderOrNull ( ) ? ? throw new PKSyntaxError ( "You must pass a member name." ) ;
// Hard name length cap
if ( memberName . Length > Limits . MaxMemberNameLength ) throw Errors . MemberNameTooLongError ( memberName . Length ) ;
// Warn if there's already a member by this name
2020-08-29 11:46:27 +00:00
var existingMember = await _db . Execute ( c = > _repo . GetMemberByName ( c , ctx . System . Id , memberName ) ) ;
2020-02-01 12:03:02 +00:00
if ( existingMember ! = null ) {
2020-07-21 00:10:26 +00:00
var msg = $"{Emojis.Warn} You already have a member in your system with the name \" { existingMember . NameFor ( ctx ) } \ " (with ID `{existingMember.Hid}`). Do you want to create another member with the same name?" ;
2020-02-01 12:03:02 +00:00
if ( ! await ctx . PromptYesNo ( msg ) ) throw new PKError ( "Member creation cancelled." ) ;
}
2020-06-29 12:54:11 +00:00
await using var conn = await _db . Obtain ( ) ;
2020-02-01 12:03:02 +00:00
// Enforce per-system member limit
2020-08-29 11:46:27 +00:00
var memberCount = await _repo . GetSystemMemberCount ( conn , ctx . System . Id ) ;
2020-10-09 10:18:29 +00:00
var memberLimit = ctx . System . MemberLimitOverride ? ? Limits . MaxMemberCount ;
if ( memberCount > = memberLimit )
throw Errors . MemberLimitReachedError ( memberLimit ) ;
2020-02-01 12:03:02 +00:00
// Create the member
2020-08-29 11:46:27 +00:00
var member = await _repo . CreateMember ( conn , ctx . System . Id , memberName ) ;
2020-02-01 12:03:02 +00:00
memberCount + + ;
// Send confirmation and space hint
2020-06-20 15:36:03 +00:00
await ctx . Reply ( $"{Emojis.Success} Member \" { memberName } \ " (`{member.Hid}`) registered! Check out the getting started page for how to get a member up and running: https://pluralkit.me/start#members" ) ;
2020-02-01 12:03:02 +00:00
if ( memberName . Contains ( " " ) )
await ctx . Reply ( $"{Emojis.Note} Note that this member's name contains spaces. You will need to surround it with \" double quotes \ " when using commands referring to it, or just use the member's 5-character ID (which is `{member.Hid}`)." ) ;
2020-10-09 14:23:31 +00:00
if ( memberCount > = memberLimit )
await ctx . Reply ( $"{Emojis.Warn} You have reached the per-system member limit ({memberLimit}). You will be unable to create additional members until existing members are deleted." ) ;
else if ( memberCount > = Limits . MaxMembersWarnThreshold ( memberLimit ) )
await ctx . Reply ( $"{Emojis.Warn} You are approaching the per-system member limit ({memberCount} / {memberLimit} members). Please review your member list for unused or duplicate members." ) ;
2020-02-01 12:03:02 +00:00
}
public async Task MemberRandom ( Context ctx )
{
ctx . CheckSystem ( ) ;
var randGen = new global :: System . Random ( ) ;
//Maybe move this somewhere else in the file structure since it doesn't need to get created at every command
// TODO: don't buffer these, find something else to do ig
2020-08-29 11:46:27 +00:00
var members = await _db . Execute ( c = >
{
if ( ctx . MatchFlag ( "all" , "a" ) )
return _repo . GetSystemMembers ( c , ctx . System . Id ) ;
return _repo . GetSystemMembers ( c , ctx . System . Id )
. Where ( m = > m . MemberVisibility = = PrivacyLevel . Public ) ;
} ) . ToListAsync ( ) ;
2020-08-04 22:43:17 +00:00
2020-02-01 12:03:02 +00:00
if ( members = = null | | ! members . Any ( ) )
throw Errors . NoMembersError ;
var randInt = randGen . Next ( members . Count ) ;
await ctx . Reply ( embed : await _embeds . CreateMemberEmbed ( ctx . System , members [ randInt ] , ctx . Guild , ctx . LookupContextFor ( ctx . System ) ) ) ;
}
public async Task ViewMember ( Context ctx , PKMember target )
{
2020-08-29 11:46:27 +00:00
var system = await _db . Execute ( c = > _repo . GetSystem ( c , target . System ) ) ;
2020-02-01 12:03:02 +00:00
await ctx . Reply ( embed : await _embeds . CreateMemberEmbed ( system , target , ctx . Guild , ctx . LookupContextFor ( system ) ) ) ;
}
}
}