mirror of
https://github.com/PluralKit/PluralKit.git
synced 2026-02-04 04:56:49 +00:00
feat: add premium management admin commands
This commit is contained in:
parent
bd5b5c03fe
commit
a6941cea08
3 changed files with 93 additions and 0 deletions
|
|
@ -182,6 +182,8 @@ public partial class CommandTree
|
||||||
await ctx.Execute<Admin>(Admin, a => a.SystemRecover(ctx));
|
await ctx.Execute<Admin>(Admin, a => a.SystemRecover(ctx));
|
||||||
else if (ctx.Match("sd", "systemdelete"))
|
else if (ctx.Match("sd", "systemdelete"))
|
||||||
await ctx.Execute<Admin>(Admin, a => a.SystemDelete(ctx));
|
await ctx.Execute<Admin>(Admin, a => a.SystemDelete(ctx));
|
||||||
|
else if (ctx.Match("pe", "premiumexpiry", "premium"))
|
||||||
|
await ctx.Execute<Admin>(Admin, a => a.PremiumExpiry(ctx));
|
||||||
else if (ctx.Match("sendmsg", "sendmessage"))
|
else if (ctx.Match("sendmsg", "sendmessage"))
|
||||||
await ctx.Execute<Admin>(Admin, a => a.SendAdminMessage(ctx));
|
await ctx.Execute<Admin>(Admin, a => a.SendAdminMessage(ctx));
|
||||||
else if (ctx.Match("al", "abuselog"))
|
else if (ctx.Match("al", "abuselog"))
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,8 @@ using System.Text.RegularExpressions;
|
||||||
|
|
||||||
using Humanizer;
|
using Humanizer;
|
||||||
using Dapper;
|
using Dapper;
|
||||||
|
using NodaTime;
|
||||||
|
using NodaTime.Text;
|
||||||
using SqlKata;
|
using SqlKata;
|
||||||
|
|
||||||
using Myriad.Builders;
|
using Myriad.Builders;
|
||||||
|
|
@ -79,6 +81,16 @@ public class Admin
|
||||||
var groupCount = await ctx.Repository.GetSystemGroupCount(system.Id);
|
var groupCount = await ctx.Repository.GetSystemGroupCount(system.Id);
|
||||||
eb.Field(new Embed.Field("Group limit", $"{groupLimit} {UntilLimit(groupCount, groupLimit)}", true));
|
eb.Field(new Embed.Field("Group limit", $"{groupLimit} {UntilLimit(groupCount, groupLimit)}", true));
|
||||||
|
|
||||||
|
var premiumEntitlement = "none";
|
||||||
|
if (config.PremiumLifetime)
|
||||||
|
premiumEntitlement = $"<:lifetime_premium:{_botConfig.PremiumLifetimeEmoji}> **lifetime**";
|
||||||
|
else if (config.PremiumUntil != null)
|
||||||
|
if (SystemClock.Instance.GetCurrentInstant() < config.PremiumUntil!)
|
||||||
|
premiumEntitlement = $"<:premium_subscriber:{_botConfig.PremiumSubscriberEmoji}> <t:{config.PremiumUntil?.ToUnixTimeSeconds()}> <t:{config.PremiumUntil?.ToUnixTimeSeconds()}:R>";
|
||||||
|
else
|
||||||
|
premiumEntitlement = $"Expired! <t:{config.PremiumUntil?.ToUnixTimeSeconds()}> <t:{config.PremiumUntil?.ToUnixTimeSeconds()}:R>";
|
||||||
|
eb.Field(new Embed.Field("Premium entitlement", premiumEntitlement, false));
|
||||||
|
|
||||||
return eb.Build();
|
return eb.Build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -396,6 +408,75 @@ public class Admin
|
||||||
await ctx.Reply($"{Emojis.Success} System deletion succesful.");
|
await ctx.Reply($"{Emojis.Success} System deletion succesful.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task PremiumExpiry(Context ctx)
|
||||||
|
{
|
||||||
|
ctx.AssertBotAdmin();
|
||||||
|
|
||||||
|
var target = await ctx.MatchSystem();
|
||||||
|
if (target == null)
|
||||||
|
throw new PKError("Unknown system.");
|
||||||
|
|
||||||
|
await ctx.Reply(null, await CreateEmbed(ctx, target));
|
||||||
|
if (!ctx.HasNext())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (ctx.Match("lifetime", "staff"))
|
||||||
|
{
|
||||||
|
if (!await ctx.PromptYesNo($"Grant system `{target.Hid}` lifetime premium?", "Grant"))
|
||||||
|
throw new PKError("Premium entitlement change cancelled.");
|
||||||
|
|
||||||
|
await ctx.Repository.UpdateSystemConfig(target.Id, new SystemConfigPatch
|
||||||
|
{
|
||||||
|
PremiumLifetime = true,
|
||||||
|
PremiumUntil = null,
|
||||||
|
});
|
||||||
|
await ctx.Reply($"{Emojis.Success} Premium entitlement changed.");
|
||||||
|
}
|
||||||
|
else if (ctx.Match("none", "clear"))
|
||||||
|
{
|
||||||
|
if (!await ctx.PromptYesNo($"Clear premium entitlements for system `{target.Hid}`?", "Clear"))
|
||||||
|
throw new PKError("Premium entitlement change cancelled.");
|
||||||
|
|
||||||
|
await ctx.Repository.UpdateSystemConfig(target.Id, new SystemConfigPatch
|
||||||
|
{
|
||||||
|
PremiumLifetime = false,
|
||||||
|
PremiumUntil = null,
|
||||||
|
});
|
||||||
|
await ctx.Reply($"{Emojis.Success} Premium entitlement changed.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var timeToMove = ctx.RemainderOrNull() ??
|
||||||
|
throw new PKSyntaxError("Must pass a date/time to set premium expiry to.");
|
||||||
|
|
||||||
|
Instant? time = null;
|
||||||
|
|
||||||
|
// DateUtils.ParseDateTime expects periods to be in the past, so we have to do
|
||||||
|
// this explicitly here...
|
||||||
|
var duration = DateUtils.ParsePeriod(timeToMove);
|
||||||
|
if (duration != null)
|
||||||
|
{
|
||||||
|
time = SystemClock.Instance.GetCurrentInstant() + duration;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var result = DateUtils.ParseDateTime(timeToMove, false);
|
||||||
|
if (result == null) throw Errors.InvalidDateTime(timeToMove);
|
||||||
|
time = result.Value.ToInstant();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!await ctx.PromptYesNo($"Change premium expiry for system `{target.Hid}` to <t:{time?.ToUnixTimeSeconds()}>?", "Change"))
|
||||||
|
throw new PKError("Premium entitlement change cancelled.");
|
||||||
|
|
||||||
|
await ctx.Repository.UpdateSystemConfig(target.Id, new SystemConfigPatch
|
||||||
|
{
|
||||||
|
PremiumLifetime = false,
|
||||||
|
PremiumUntil = time,
|
||||||
|
});
|
||||||
|
await ctx.Reply($"{Emojis.Success} Premium entitlement changed.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public async Task AbuseLogCreate(Context ctx)
|
public async Task AbuseLogCreate(Context ctx)
|
||||||
{
|
{
|
||||||
var denyBotUsage = ctx.MatchFlag("deny", "deny-bot-usage");
|
var denyBotUsage = ctx.MatchFlag("deny", "deny-bot-usage");
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,8 @@ public class SystemConfigPatch: PatchObject
|
||||||
public Partial<string?> NameFormat { get; set; }
|
public Partial<string?> NameFormat { get; set; }
|
||||||
public Partial<SystemConfig.HidPadFormat> HidListPadding { get; set; }
|
public Partial<SystemConfig.HidPadFormat> HidListPadding { get; set; }
|
||||||
public Partial<SystemConfig.ProxySwitchAction> ProxySwitch { get; set; }
|
public Partial<SystemConfig.ProxySwitchAction> ProxySwitch { get; set; }
|
||||||
|
public Partial<bool> PremiumLifetime { get; set; }
|
||||||
|
public Partial<Instant?> PremiumUntil { get; set; }
|
||||||
|
|
||||||
public override Query Apply(Query q) => q.ApplyPatch(wrapper => wrapper
|
public override Query Apply(Query q) => q.ApplyPatch(wrapper => wrapper
|
||||||
.With("ui_tz", UiTz)
|
.With("ui_tz", UiTz)
|
||||||
|
|
@ -45,6 +47,8 @@ public class SystemConfigPatch: PatchObject
|
||||||
.With("card_show_color_hex", CardShowColorHex)
|
.With("card_show_color_hex", CardShowColorHex)
|
||||||
.With("proxy_switch", ProxySwitch)
|
.With("proxy_switch", ProxySwitch)
|
||||||
.With("name_format", NameFormat)
|
.With("name_format", NameFormat)
|
||||||
|
.With("premium_lifetime", PremiumLifetime)
|
||||||
|
.With("premium_until", PremiumUntil)
|
||||||
);
|
);
|
||||||
|
|
||||||
public new void AssertIsValid()
|
public new void AssertIsValid()
|
||||||
|
|
@ -118,6 +122,12 @@ public class SystemConfigPatch: PatchObject
|
||||||
if (NameFormat.IsPresent)
|
if (NameFormat.IsPresent)
|
||||||
o.Add("name_format", NameFormat.Value);
|
o.Add("name_format", NameFormat.Value);
|
||||||
|
|
||||||
|
if (PremiumLifetime.IsPresent)
|
||||||
|
o.Add("premium_lifetime", PremiumLifetime.Value);
|
||||||
|
|
||||||
|
if (PremiumUntil.IsPresent)
|
||||||
|
o.Add("premium_until", PremiumUntil.Value?.FormatExport());
|
||||||
|
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue