mirror of
https://github.com/PluralKit/PluralKit.git
synced 2026-02-06 13:57:54 +00:00
feat: premium ID changes
Some checks failed
Build and push Docker image / .net docker build (push) Has been cancelled
.net checks / run .net tests (push) Has been cancelled
.net checks / dotnet-format (push) Has been cancelled
Build and push Rust service Docker images / rust docker build (push) Has been cancelled
rust checks / cargo fmt (push) Has been cancelled
Some checks failed
Build and push Docker image / .net docker build (push) Has been cancelled
.net checks / run .net tests (push) Has been cancelled
.net checks / dotnet-format (push) Has been cancelled
Build and push Rust service Docker images / rust docker build (push) Has been cancelled
rust checks / cargo fmt (push) Has been cancelled
This commit is contained in:
parent
41f8beb2aa
commit
24b6b0d455
16 changed files with 306 additions and 3 deletions
|
|
@ -416,12 +416,15 @@ public class Admin
|
|||
if (target == null)
|
||||
throw new PKError("Unknown system.");
|
||||
|
||||
await ctx.Reply(null, await CreateEmbed(ctx, target));
|
||||
if (!ctx.HasNext())
|
||||
{
|
||||
await ctx.Reply(null, await CreateEmbed(ctx, target));
|
||||
return;
|
||||
}
|
||||
|
||||
if (ctx.Match("lifetime", "staff"))
|
||||
{
|
||||
await ctx.Reply(null, await CreateEmbed(ctx, target));
|
||||
if (!await ctx.PromptYesNo($"Grant system `{target.Hid}` lifetime premium?", "Grant"))
|
||||
throw new PKError("Premium entitlement change cancelled.");
|
||||
|
||||
|
|
@ -434,6 +437,7 @@ public class Admin
|
|||
}
|
||||
else if (ctx.Match("none", "clear"))
|
||||
{
|
||||
await ctx.Reply(null, await CreateEmbed(ctx, target));
|
||||
if (!await ctx.PromptYesNo($"Clear premium entitlements for system `{target.Hid}`?", "Clear"))
|
||||
throw new PKError("Premium entitlement change cancelled.");
|
||||
|
||||
|
|
@ -465,6 +469,7 @@ public class Admin
|
|||
time = result.Value.ToInstant();
|
||||
}
|
||||
|
||||
await ctx.Reply(null, await CreateEmbed(ctx, target));
|
||||
if (!await ctx.PromptYesNo($"Change premium expiry for system `{target.Hid}` to <t:{time?.ToUnixTimeSeconds()}>?", "Change"))
|
||||
throw new PKError("Premium entitlement change cancelled.");
|
||||
|
||||
|
|
@ -477,6 +482,37 @@ public class Admin
|
|||
}
|
||||
}
|
||||
|
||||
public async Task PremiumIdChangeAllowance(Context ctx)
|
||||
{
|
||||
ctx.AssertBotAdmin();
|
||||
|
||||
var target = await ctx.MatchSystem();
|
||||
if (target == null)
|
||||
throw new PKError("Unknown system.");
|
||||
|
||||
if (!ctx.HasNext())
|
||||
{
|
||||
await ctx.Reply(null, await CreateEmbed(ctx, target));
|
||||
return;
|
||||
}
|
||||
|
||||
var config = await ctx.Repository.GetSystemConfig(target.Id);
|
||||
var newAllowanceStr = ctx.PopArgument().ToLower().Replace(",", null).Replace("k", "000");
|
||||
if (!int.TryParse(newAllowanceStr, out var newAllowance))
|
||||
throw new PKError($"Couldn't parse `{newAllowanceStr}` as number.");
|
||||
|
||||
await ctx.Reply(null, await CreateEmbed(ctx, target));
|
||||
if (!await ctx.PromptYesNo($"Update premium ID change allowance from **{config.PremiumIdChangesRemaining}** to **{newAllowance}**?", "Update"))
|
||||
throw new PKError("ID change allowance cancelled.");
|
||||
|
||||
await ctx.Repository.UpdateSystemConfig(target.Id, new SystemConfigPatch
|
||||
{
|
||||
PremiumIdChangesRemaining = newAllowance,
|
||||
});
|
||||
|
||||
await ctx.Reply($"{Emojis.Success} Premium entitlement changed.");
|
||||
}
|
||||
|
||||
public async Task AbuseLogCreate(Context ctx)
|
||||
{
|
||||
var denyBotUsage = ctx.MatchFlag("deny", "deny-bot-usage");
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@ using System.Text.RegularExpressions;
|
|||
using Myriad.Builders;
|
||||
using Myriad.Types;
|
||||
|
||||
using NodaTime;
|
||||
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
using PluralKit.Core;
|
||||
|
|
@ -99,6 +101,38 @@ public class Groups
|
|||
await ctx.Reply(replyStr, eb.Build());
|
||||
}
|
||||
|
||||
public async Task ChangeId(Context ctx, PKGroup target)
|
||||
{
|
||||
ctx.CheckSystem().CheckOwnGroup(target);
|
||||
if (!ctx.Premium)
|
||||
throw Errors.PremiumExclusiveCommand();
|
||||
|
||||
var input = ctx.PopArgument();
|
||||
if (!input.TryParseHid(out var newHid))
|
||||
throw new PKError($"Invalid new member ID `{input}`.");
|
||||
|
||||
var existingGroup = await ctx.Repository.GetGroupByHid(newHid);
|
||||
if (existingGroup != null)
|
||||
throw new PKError($"Another group already exists with ID `{newHid.DisplayHid(ctx.Config)}`.");
|
||||
|
||||
if (ctx.Config.PremiumIdChangesRemaining < 1)
|
||||
throw new PKError("You do not have enough available ID changes to do this.");
|
||||
if ((await ctx.Repository.GetHidChangelogCountForDate(ctx.System.Id, SystemClock.Instance.GetCurrentInstant().InUtc().Date)) >= Limits.PremiumDailyHidChanges)
|
||||
throw new PKError($"You have already changed {Limits.PremiumDailyHidChanges} IDs today. Please try again tomorrow.");
|
||||
|
||||
if (!await ctx.PromptYesNo($"Change ID for group **{target.NameFor(ctx)}** (`{target.DisplayHid(ctx.Config)}`) to `{newHid.DisplayHid(ctx.Config)}`?", "Change"))
|
||||
throw new PKError("ID change cancelled.");
|
||||
|
||||
if (!await ctx.Repository.TryUpdateSystemConfigForIdChange(ctx.System.Id))
|
||||
throw new PKError("You do not have enough available ID changes to do this.");
|
||||
|
||||
await ctx.Repository.CreateHidChangelog(ctx.System.Id, ctx.Message.Author.Id, "group", target.Hid, newHid);
|
||||
await ctx.Repository.UpdateGroup(target.Id, new GroupPatch { Hid = newHid });
|
||||
|
||||
var newConfig = await ctx.Repository.GetSystemConfig(ctx.System.Id);
|
||||
await ctx.Reply($"{Emojis.Success} Group ID changed to `{newHid.DisplayHid(ctx.Config)}`. You have **{newConfig.PremiumIdChangesRemaining}** ID changes remaining.");
|
||||
}
|
||||
|
||||
public async Task RenameGroup(Context ctx, PKGroup target)
|
||||
{
|
||||
ctx.CheckOwnGroup(target);
|
||||
|
|
|
|||
|
|
@ -21,6 +21,38 @@ public class MemberEdit
|
|||
_avatarHosting = avatarHosting;
|
||||
}
|
||||
|
||||
public async Task ChangeId(Context ctx, PKMember target)
|
||||
{
|
||||
ctx.CheckSystem().CheckOwnMember(target);
|
||||
if (!ctx.Premium)
|
||||
throw Errors.PremiumExclusiveCommand();
|
||||
|
||||
var input = ctx.PopArgument();
|
||||
if (!input.TryParseHid(out var newHid))
|
||||
throw new PKError($"Invalid new member ID `{input}`.");
|
||||
|
||||
var existingMember = await ctx.Repository.GetMemberByHid(newHid);
|
||||
if (existingMember != null)
|
||||
throw new PKError($"Another member already exists with ID `{newHid.DisplayHid(ctx.Config)}`.");
|
||||
|
||||
if (ctx.Config.PremiumIdChangesRemaining < 1)
|
||||
throw new PKError("You do not have enough available ID changes to do this.");
|
||||
if ((await ctx.Repository.GetHidChangelogCountForDate(ctx.System.Id, SystemClock.Instance.GetCurrentInstant().InUtc().Date)) >= Limits.PremiumDailyHidChanges)
|
||||
throw new PKError($"You have already changed {Limits.PremiumDailyHidChanges} IDs today. Please try again tomorrow.");
|
||||
|
||||
if (!await ctx.PromptYesNo($"Change ID for member **{target.NameFor(ctx)}** (`{target.DisplayHid(ctx.Config)}`) to `{newHid.DisplayHid(ctx.Config)}`?", "Change"))
|
||||
throw new PKError("ID change cancelled.");
|
||||
|
||||
if (!await ctx.Repository.TryUpdateSystemConfigForIdChange(ctx.System.Id))
|
||||
throw new PKError("You do not have enough available ID changes to do this.");
|
||||
|
||||
await ctx.Repository.CreateHidChangelog(ctx.System.Id, ctx.Message.Author.Id, "member", target.Hid, newHid);
|
||||
await ctx.Repository.UpdateMember(target.Id, new MemberPatch { Hid = newHid });
|
||||
|
||||
var newConfig = await ctx.Repository.GetSystemConfig(ctx.System.Id);
|
||||
await ctx.Reply($"{Emojis.Success} Member ID changed to `{newHid.DisplayHid(ctx.Config)}`. You have **{newConfig.PremiumIdChangesRemaining}** ID changes remaining.");
|
||||
}
|
||||
|
||||
public async Task Name(Context ctx, PKMember target)
|
||||
{
|
||||
var format = ctx.MatchFormat();
|
||||
|
|
|
|||
|
|
@ -54,7 +54,57 @@ public class Misc
|
|||
}
|
||||
}
|
||||
|
||||
await ctx.Reply(message + $"\n\nManage your subscription at <{_botConfig.PremiumDashboardUrl}>");
|
||||
List<MessageComponent> components = [
|
||||
new MessageComponent()
|
||||
{
|
||||
Type = ComponentType.Text,
|
||||
Content = message,
|
||||
},
|
||||
];
|
||||
|
||||
if (ctx.Premium)
|
||||
{
|
||||
var hidChangesLeftToday = Limits.PremiumDailyHidChanges - await ctx.Repository.GetHidChangelogCountForDate(ctx.System.Id, SystemClock.Instance.GetCurrentInstant().InUtc().Date);
|
||||
var limitMessage = $"You have **{ctx.Config.PremiumIdChangesRemaining}** ID changes available, of which you can use **{hidChangesLeftToday}** today.";
|
||||
|
||||
components.Add(new()
|
||||
{
|
||||
Type = ComponentType.Separator,
|
||||
});
|
||||
components.Add(new()
|
||||
{
|
||||
Type = ComponentType.Text,
|
||||
Content = limitMessage,
|
||||
});
|
||||
}
|
||||
|
||||
await ctx.Reply(components: [
|
||||
new()
|
||||
{
|
||||
Type = ComponentType.Container,
|
||||
Components = [
|
||||
new()
|
||||
{
|
||||
Type = ComponentType.Text,
|
||||
Content = $"## {(_botConfig.PremiumSubscriberEmoji != null ? $"<:premium_subscriber:{_botConfig.PremiumSubscriberEmoji}>" : "\u2729")} PluralKit Premium",
|
||||
},
|
||||
..components,
|
||||
],
|
||||
},
|
||||
new()
|
||||
{
|
||||
Type = ComponentType.ActionRow,
|
||||
Components = [
|
||||
new()
|
||||
{
|
||||
Type = ComponentType.Button,
|
||||
Style = ButtonStyle.Link,
|
||||
Label = "Manage your subscription",
|
||||
Url = _botConfig.PremiumDashboardUrl,
|
||||
},
|
||||
],
|
||||
},
|
||||
]);
|
||||
}
|
||||
|
||||
public async Task Invite(Context ctx)
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@ using Myriad.Types;
|
|||
|
||||
using Newtonsoft.Json;
|
||||
|
||||
using NodaTime;
|
||||
|
||||
using PluralKit.Core;
|
||||
using SqlKata.Compilers;
|
||||
|
||||
|
|
@ -20,13 +22,47 @@ public class SystemEdit
|
|||
private readonly DataFileService _dataFiles;
|
||||
private readonly PrivateChannelService _dmCache;
|
||||
private readonly AvatarHostingService _avatarHosting;
|
||||
private readonly BotConfig _botConfig;
|
||||
|
||||
public SystemEdit(DataFileService dataFiles, HttpClient client, PrivateChannelService dmCache, AvatarHostingService avatarHosting)
|
||||
public SystemEdit(DataFileService dataFiles, HttpClient client, PrivateChannelService dmCache, AvatarHostingService avatarHosting, BotConfig botConfig)
|
||||
{
|
||||
_dataFiles = dataFiles;
|
||||
_client = client;
|
||||
_dmCache = dmCache;
|
||||
_avatarHosting = avatarHosting;
|
||||
_botConfig = botConfig;
|
||||
}
|
||||
|
||||
public async Task ChangeId(Context ctx, PKSystem target)
|
||||
{
|
||||
ctx.CheckSystem().CheckOwnSystem(target);
|
||||
if (!ctx.Premium)
|
||||
throw Errors.PremiumExclusiveCommand();
|
||||
|
||||
var input = ctx.PopArgument();
|
||||
if (!input.TryParseHid(out var newHid))
|
||||
throw new PKError($"Invalid new system ID `{input}`.");
|
||||
|
||||
var existingSystem = await ctx.Repository.GetSystemByHid(newHid);
|
||||
if (existingSystem != null)
|
||||
throw new PKError($"Another system already exists with ID `{newHid.DisplayHid(ctx.Config)}`.");
|
||||
|
||||
if (ctx.Config.PremiumIdChangesRemaining < 1)
|
||||
throw new PKError("You do not have enough available ID changes to do this.");
|
||||
if ((await ctx.Repository.GetHidChangelogCountForDate(target.Id, SystemClock.Instance.GetCurrentInstant().InUtc().Date)) >= Limits.PremiumDailyHidChanges)
|
||||
throw new PKError($"You have already changed {Limits.PremiumDailyHidChanges} IDs today. Please try again tomorrow.");
|
||||
|
||||
if (!await ctx.PromptYesNo($"Change your system ID to `{newHid.DisplayHid(ctx.Config)}`?", "Change"))
|
||||
throw new PKError("ID change cancelled.");
|
||||
|
||||
if (!await ctx.Repository.TryUpdateSystemConfigForIdChange(target.Id))
|
||||
throw new PKError("You do not have enough available ID changes to do this.");
|
||||
|
||||
await ctx.Repository.CreateHidChangelog(target.Id, ctx.Message.Author.Id, "system", target.Hid, newHid);
|
||||
await ctx.Repository.UpdateSystem(target.Id, new SystemPatch { Hid = newHid });
|
||||
|
||||
var newConfig = await ctx.Repository.GetSystemConfig(target.Id);
|
||||
await ctx.Reply($"{Emojis.Success} System ID changed to `{newHid.DisplayHid(ctx.Config)}`. You have **{newConfig.PremiumIdChangesRemaining}** ID changes remaining.");
|
||||
}
|
||||
|
||||
public async Task Name(Context ctx, PKSystem target)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue