82dfe43d5a
This does a *lot* of things. Essentially, it replaces the existing individual proxy- and autoproxy caches on the bot end with a global cache (in Core) that handles all the caching at once, and automatically invalidates the cache once something changes in the datastore. This allows us to do proxying and autoproxying with *zero database queries* (best-case).
74 lines
3.8 KiB
C#
74 lines
3.8 KiB
C#
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
|
|
using PluralKit.Bot.CommandSystem;
|
|
using PluralKit.Core;
|
|
|
|
namespace PluralKit.Bot.Commands
|
|
{
|
|
public class Member
|
|
{
|
|
private IDataStore _data;
|
|
private EmbedService _embeds;
|
|
|
|
public Member(IDataStore data, EmbedService embeds)
|
|
{
|
|
_data = data;
|
|
_embeds = embeds;
|
|
}
|
|
|
|
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
|
|
var existingMember = await _data.GetMemberByName(ctx.System, memberName);
|
|
if (existingMember != null) {
|
|
var msg = await ctx.Reply($"{Emojis.Warn} You already have a member in your system with the name \"{existingMember.Name.SanitizeMentions()}\" (with ID `{existingMember.Hid}`). Do you want to create another member with the same name?");
|
|
if (!await ctx.PromptYesNo(msg)) throw new PKError("Member creation cancelled.");
|
|
}
|
|
|
|
// Enforce per-system member limit
|
|
var memberCount = await _data.GetSystemMemberCount(ctx.System, true);
|
|
if (memberCount >= Limits.MaxMemberCount)
|
|
throw Errors.MemberLimitReachedError;
|
|
|
|
// Create the member
|
|
var member = await _data.CreateMember(ctx.System, memberName);
|
|
memberCount++;
|
|
|
|
// Send confirmation and space hint
|
|
await ctx.Reply($"{Emojis.Success} Member \"{memberName.SanitizeMentions()}\" (`{member.Hid}`) registered! See the user guide for commands for editing this member: https://pluralkit.me/guide#member-management");
|
|
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}`).");
|
|
if (memberCount >= Limits.MaxMemberCount)
|
|
await ctx.Reply($"{Emojis.Warn} You have reached the per-system member limit ({Limits.MaxMemberCount}). You will be unable to create additional members until existing members are deleted.");
|
|
else if (memberCount >= Limits.MaxMembersWarnThreshold)
|
|
await ctx.Reply($"{Emojis.Warn} You are approaching the per-system member limit ({memberCount} / {Limits.MaxMemberCount} members). Please review your member list for unused or duplicate members.");
|
|
}
|
|
|
|
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
|
|
var members = await _data.GetSystemMembers(ctx.System).Where(m => m.MemberPrivacy == PrivacyLevel.Public).ToListAsync();
|
|
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)
|
|
{
|
|
var system = await _data.GetSystemById(target.System);
|
|
await ctx.Reply(embed: await _embeds.CreateMemberEmbed(system, target, ctx.Guild, ctx.LookupContextFor(system)));
|
|
}
|
|
}
|
|
} |