Add a few utility admin commands

Signed-off-by: Ske <voltasalt@gmail.com>
This commit is contained in:
Ske
2021-06-08 19:37:44 +02:00
parent af5de7c892
commit 8740230c3d
9 changed files with 177 additions and 12 deletions

View File

@@ -0,0 +1,128 @@
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using PluralKit.Bot.Interactive;
using PluralKit.Core;
namespace PluralKit.Bot
{
public class Admin
{
private readonly BotConfig _botConfig;
private readonly IDatabase _db;
private readonly ModelRepository _repo;
public Admin(BotConfig botConfig, IDatabase db, ModelRepository repo)
{
_botConfig = botConfig;
_db = db;
_repo = repo;
}
public async Task UpdateSystemId(Context ctx)
{
AssertBotAdmin(ctx);
var target = await ctx.MatchSystem();
if (target == null)
throw new PKError("Unknown system.");
var newHid = ctx.PopArgument();
if (!Regex.IsMatch(newHid, "^[a-z]{5}$"))
throw new PKError($"Invalid new system ID `{newHid}`.");
var existingSystem = await _db.Execute(c => _repo.GetSystemByHid(c, newHid));
if (existingSystem != null)
throw new PKError($"Another system already exists with ID `{newHid}`.");
var prompt = new YesNoPrompt(ctx)
{
Message = $"Change system ID of `{target.Hid}` to `{newHid}`?",
AcceptLabel = "Change"
};
await prompt.Run();
await _db.Execute(c => _repo.UpdateSystem(c, target.Id, new SystemPatch {Hid = newHid}));
await ctx.Reply($"{Emojis.Success} System ID updated (`{target.Hid}` -> `{newHid}`).");
}
public async Task UpdateMemberId(Context ctx)
{
AssertBotAdmin(ctx);
var target = await ctx.MatchMember();
if (target == null)
throw new PKError("Unknown member.");
var newHid = ctx.PopArgument();
if (!Regex.IsMatch(newHid, "^[a-z]{5}$"))
throw new PKError($"Invalid new member ID `{newHid}`.");
var existingMember = await _db.Execute(c => _repo.GetMemberByHid(c, newHid));
if (existingMember != null)
throw new PKError($"Another member already exists with ID `{newHid}`.");
var prompt = new YesNoPrompt(ctx)
{
Message = $"Change member ID of **{target.NameFor(LookupContext.ByNonOwner)}** (`{target.Hid}`) to `{newHid}`?",
AcceptLabel = "Change"
};
await prompt.Run();
if (prompt.Result != true)
throw new PKError("ID change cancelled.");
await _db.Execute(c => _repo.UpdateMember(c, target.Id, new MemberPatch {Hid = newHid}));
await ctx.Reply($"{Emojis.Success} Member ID updated (`{target.Hid}` -> `{newHid}`).");
}
public async Task SystemMemberLimit(Context ctx)
{
AssertBotAdmin(ctx);
var target = await ctx.MatchSystem();
if (target == null)
throw new PKError("Unknown system.");
var currentLimit = target.MemberLimitOverride ?? Limits.MaxMemberCount;
if (!ctx.HasNext())
{
await ctx.Reply($"Current member limit is **{currentLimit}** members.");
return;
}
var newLimitStr = ctx.PopArgument();
if (!int.TryParse(newLimitStr, out var newLimit))
throw new PKError($"Couldn't parse `{newLimitStr}` as number.");
var prompt = new YesNoPrompt(ctx)
{
Message = $"Update member limit from **{currentLimit}** to **{newLimit}**?",
AcceptLabel = "Update"
};
await prompt.Run();
if (prompt.Result != true)
throw new PKError("Member limit change cancelled.");
await using var conn = await _db.Obtain();
await _repo.UpdateSystem(conn, target.Id, new SystemPatch
{
MemberLimitOverride = newLimit
});
await ctx.Reply($"{Emojis.Success} Member limit updated.");
}
private void AssertBotAdmin(Context ctx)
{
if (!IsBotAdmin(ctx))
throw new PKError("This command is only usable by bot admins.");
}
private bool IsBotAdmin(Context ctx)
{
return _botConfig.AdminRole != null && ctx.Member.Roles.Contains(_botConfig.AdminRole.Value);
}
}
}

View File

@@ -90,6 +90,7 @@ namespace PluralKit.Bot
public static Command BlacklistRemove = new Command("blacklist remove", "blacklist remove all|<channel> [channel 2] [channel 3...]", "Removes certain channels from the proxy blacklist");
public static Command Invite = new Command("invite", "invite", "Gets a link to invite PluralKit to other servers");
public static Command PermCheck = new Command("permcheck", "permcheck <guild>", "Checks whether a server's permission setup is correct");
public static Command Admin = new Command("admin", "admin", "Super secret admin commands (sshhhh)");
public static Command[] SystemCommands = {
SystemInfo, SystemNew, SystemRename, SystemTag, SystemDesc, SystemAvatar, SystemColor, SystemDelete, SystemTimezone,
@@ -197,6 +198,8 @@ namespace PluralKit.Bot
if (ctx.Match("stats")) return ctx.Execute<Misc>(null, m => m.Stats(ctx));
if (ctx.Match("permcheck"))
return ctx.Execute<Misc>(PermCheck, m => m.PermCheckGuild(ctx));
if (ctx.Match("admin"))
return HandleAdminCommand(ctx);
if (ctx.Match("random", "r"))
if (ctx.Match("group", "g") || ctx.MatchFlag("group", "g"))
return ctx.Execute<Random>(GroupRandom, r => r.Group(ctx));
@@ -208,6 +211,18 @@ namespace PluralKit.Bot
$"{Emojis.Error} Unknown command {ctx.PeekArgument().AsCode()}. For a list of possible commands, see <https://pluralkit.me/commands>.");
}
private async Task HandleAdminCommand(Context ctx)
{
if (ctx.Match("usid", "updatesystemid"))
await ctx.Execute<Admin>(Admin, a => a.UpdateSystemId(ctx));
else if (ctx.Match("umid", "updatememberid"))
await ctx.Execute<Admin>(Admin, a => a.UpdateMemberId(ctx));
else if (ctx.Match("uml", "updatememberlimit"))
await ctx.Execute<Admin>(Admin, a => a.SystemMemberLimit(ctx));
else
await ctx.Reply($"{Emojis.Error} Unknown command.");
}
private async Task HandleSystemCommand(Context ctx)
{
// If we have no parameters, default to self-target