feat: add basic premium scaffolding

This commit is contained in:
alyssa 2025-12-21 01:19:02 -05:00 committed by asleepyskye
parent f22ba3f0ea
commit 0a474c43eb
8 changed files with 70 additions and 2 deletions

View file

@ -36,6 +36,10 @@ public class BotConfig
public bool IsBetaBot { get; set; } = false!;
public string BetaBotAPIUrl { get; set; }
public String? PremiumSubscriberEmoji { get; set; }
public String? PremiumLifetimeEmoji { get; set; }
public String? PremiumDashboardUrl { get; set; }
public record ClusterSettings
{
// this is zero-indexed

View file

@ -92,6 +92,7 @@ public partial class CommandTree
if (ctx.Match("sus")) return ctx.Execute<Fun>(null, m => m.Sus(ctx));
if (ctx.Match("error")) return ctx.Execute<Fun>(null, m => m.Error(ctx));
if (ctx.Match("stats", "status")) return ctx.Execute<Misc>(null, m => m.Stats(ctx));
if (ctx.Match("premium")) return ctx.Execute<Misc>(null, m => m.Premium(ctx));
if (ctx.Match("permcheck"))
return ctx.Execute<Checks>(PermCheck, m => m.PermCheckGuild(ctx));
if (ctx.Match("proxycheck"))

View file

@ -28,6 +28,8 @@ public class Context
private Command? _currentCommand;
private BotConfig _botConfig;
public Context(ILifetimeScope provider, int shardId, Guild? guild, Channel channel, MessageCreateEvent message,
int commandParseOffset, PKSystem senderSystem, SystemConfig config,
GuildConfig? guildConfig, string[] prefixes)
@ -46,6 +48,7 @@ public class Context
_metrics = provider.Resolve<IMetrics>();
_provider = provider;
_commandMessageService = provider.Resolve<CommandMessageService>();
_botConfig = provider.Resolve<BotConfig>();
CommandPrefix = message.Content?.Substring(0, commandParseOffset);
DefaultPrefix = prefixes[0];
Parameters = new Parameters(message.Content?.Substring(commandParseOffset));
@ -74,6 +77,23 @@ public class Context
public readonly SystemConfig Config;
public DateTimeZone Zone => Config?.Zone ?? DateTimeZone.Utc;
public bool Premium
{
get
{
if (Config?.PremiumLifetime ?? false) return true;
// generate _this_ current instant _before_ the check, otherwise it will always be true...
var premiumUntil = Config?.PremiumUntil ?? SystemClock.Instance.GetCurrentInstant();
return SystemClock.Instance.GetCurrentInstant() < premiumUntil;
}
}
public string PremiumEmoji => (Config?.PremiumLifetime ?? false)
? ($"<:lifetime_premium:{_botConfig.PremiumLifetimeEmoji}>" ?? "\u2729")
: Premium
? ($"<:premium_subscriber:{_botConfig.PremiumSubscriberEmoji}>" ?? "\u2729")
: "";
public readonly string CommandPrefix;
public readonly string DefaultPrefix;
public readonly Parameters Parameters;

View file

@ -31,6 +31,32 @@ public class Misc
_shards = shards;
}
public async Task Premium(Context ctx)
{
ctx.CheckSystem();
String message;
if (ctx.Config?.PremiumLifetime ?? false)
{
message = $"Your system has lifetime PluralKit Premium. {ctx.PremiumEmoji} Thanks for the support!";
}
else if (ctx.Premium)
{
message = $"Your system has PluralKit Premium active until <t:{ctx.Config.PremiumUntil?.ToUnixTimeSeconds()}>. {ctx.PremiumEmoji} Thanks for the support!";
}
else
{
message = "PluralKit Premium is not currently active for your system.";
if (ctx.Config?.PremiumUntil != null)
{
message += $" The subscription expired at <t:{ctx.Config.PremiumUntil?.ToUnixTimeSeconds()}> (<t:{ctx.Config.PremiumUntil?.ToUnixTimeSeconds()}:R>)";
}
}
await ctx.Reply(message + $"\n\nManage your subscription at <{_botConfig.PremiumDashboardUrl}>");
}
public async Task Invite(Context ctx)
{
var permissions =

View file

@ -21,14 +21,16 @@ public class EmbedService
private readonly IDatabase _db;
private readonly ModelRepository _repo;
private readonly DiscordApiClient _rest;
private readonly BotConfig _config;
private readonly CoreConfig _coreConfig;
public EmbedService(IDatabase db, ModelRepository repo, IDiscordCache cache, DiscordApiClient rest, CoreConfig coreConfig)
public EmbedService(IDatabase db, ModelRepository repo, IDiscordCache cache, DiscordApiClient rest, BotConfig config, CoreConfig coreConfig)
{
_db = db;
_repo = repo;
_cache = cache;
_rest = rest;
_config = config;
_coreConfig = coreConfig;
}
@ -192,7 +194,7 @@ public class EmbedService
new MessageComponent()
{
Type = ComponentType.Text,
Content = $"-# System ID: `{system.DisplayHid(cctx.Config)}`\n-# Created: {system.Created.FormatZoned(cctx.Zone)}",
Content = $"-# System ID: `{system.DisplayHid(cctx.Config)}`{cctx.PremiumEmoji}\n-# Created: {system.Created.FormatZoned(cctx.Zone)}",
},
],
Accessory = new MessageComponent()