mirror of
https://github.com/PluralKit/PluralKit.git
synced 2026-02-04 04:56:49 +00:00
feat: add basic premium scaffolding
This commit is contained in:
parent
05801f6ab9
commit
832f07675f
8 changed files with 70 additions and 2 deletions
|
|
@ -36,6 +36,10 @@ public class BotConfig
|
||||||
public bool IsBetaBot { get; set; } = false!;
|
public bool IsBetaBot { get; set; } = false!;
|
||||||
public string BetaBotAPIUrl { get; set; }
|
public string BetaBotAPIUrl { get; set; }
|
||||||
|
|
||||||
|
public String? PremiumSubscriberEmoji { get; set; }
|
||||||
|
public String? PremiumLifetimeEmoji { get; set; }
|
||||||
|
public String? PremiumDashboardUrl { get; set; }
|
||||||
|
|
||||||
public record ClusterSettings
|
public record ClusterSettings
|
||||||
{
|
{
|
||||||
// this is zero-indexed
|
// this is zero-indexed
|
||||||
|
|
|
||||||
|
|
@ -92,6 +92,7 @@ public partial class CommandTree
|
||||||
if (ctx.Match("sus")) return ctx.Execute<Fun>(null, m => m.Sus(ctx));
|
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("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("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"))
|
if (ctx.Match("permcheck"))
|
||||||
return ctx.Execute<Checks>(PermCheck, m => m.PermCheckGuild(ctx));
|
return ctx.Execute<Checks>(PermCheck, m => m.PermCheckGuild(ctx));
|
||||||
if (ctx.Match("proxycheck"))
|
if (ctx.Match("proxycheck"))
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,8 @@ public class Context
|
||||||
|
|
||||||
private Command? _currentCommand;
|
private Command? _currentCommand;
|
||||||
|
|
||||||
|
private BotConfig _botConfig;
|
||||||
|
|
||||||
public Context(ILifetimeScope provider, int shardId, Guild? guild, Channel channel, MessageCreateEvent message,
|
public Context(ILifetimeScope provider, int shardId, Guild? guild, Channel channel, MessageCreateEvent message,
|
||||||
int commandParseOffset, PKSystem senderSystem, SystemConfig config,
|
int commandParseOffset, PKSystem senderSystem, SystemConfig config,
|
||||||
GuildConfig? guildConfig, string[] prefixes)
|
GuildConfig? guildConfig, string[] prefixes)
|
||||||
|
|
@ -46,6 +48,7 @@ public class Context
|
||||||
_metrics = provider.Resolve<IMetrics>();
|
_metrics = provider.Resolve<IMetrics>();
|
||||||
_provider = provider;
|
_provider = provider;
|
||||||
_commandMessageService = provider.Resolve<CommandMessageService>();
|
_commandMessageService = provider.Resolve<CommandMessageService>();
|
||||||
|
_botConfig = provider.Resolve<BotConfig>();
|
||||||
CommandPrefix = message.Content?.Substring(0, commandParseOffset);
|
CommandPrefix = message.Content?.Substring(0, commandParseOffset);
|
||||||
DefaultPrefix = prefixes[0];
|
DefaultPrefix = prefixes[0];
|
||||||
Parameters = new Parameters(message.Content?.Substring(commandParseOffset));
|
Parameters = new Parameters(message.Content?.Substring(commandParseOffset));
|
||||||
|
|
@ -74,6 +77,23 @@ public class Context
|
||||||
public readonly SystemConfig Config;
|
public readonly SystemConfig Config;
|
||||||
public DateTimeZone Zone => Config?.Zone ?? DateTimeZone.Utc;
|
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 CommandPrefix;
|
||||||
public readonly string DefaultPrefix;
|
public readonly string DefaultPrefix;
|
||||||
public readonly Parameters Parameters;
|
public readonly Parameters Parameters;
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,32 @@ public class Misc
|
||||||
_shards = shards;
|
_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)
|
public async Task Invite(Context ctx)
|
||||||
{
|
{
|
||||||
var permissions =
|
var permissions =
|
||||||
|
|
|
||||||
|
|
@ -21,14 +21,16 @@ public class EmbedService
|
||||||
private readonly IDatabase _db;
|
private readonly IDatabase _db;
|
||||||
private readonly ModelRepository _repo;
|
private readonly ModelRepository _repo;
|
||||||
private readonly DiscordApiClient _rest;
|
private readonly DiscordApiClient _rest;
|
||||||
|
private readonly BotConfig _config;
|
||||||
private readonly CoreConfig _coreConfig;
|
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;
|
_db = db;
|
||||||
_repo = repo;
|
_repo = repo;
|
||||||
_cache = cache;
|
_cache = cache;
|
||||||
_rest = rest;
|
_rest = rest;
|
||||||
|
_config = config;
|
||||||
_coreConfig = coreConfig;
|
_coreConfig = coreConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -192,7 +194,7 @@ public class EmbedService
|
||||||
new MessageComponent()
|
new MessageComponent()
|
||||||
{
|
{
|
||||||
Type = ComponentType.Text,
|
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()
|
Accessory = new MessageComponent()
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,9 @@ public class SystemConfig
|
||||||
public ProxySwitchAction ProxySwitch { get; }
|
public ProxySwitchAction ProxySwitch { get; }
|
||||||
public string NameFormat { get; }
|
public string NameFormat { get; }
|
||||||
|
|
||||||
|
public bool PremiumLifetime { get; }
|
||||||
|
public Instant? PremiumUntil { get; }
|
||||||
|
|
||||||
public enum HidPadFormat
|
public enum HidPadFormat
|
||||||
{
|
{
|
||||||
None = 0,
|
None = 0,
|
||||||
|
|
|
||||||
7
crates/migrate/data/migrations/54.sql
Normal file
7
crates/migrate/data/migrations/54.sql
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
-- database version 54
|
||||||
|
-- initial support for premium
|
||||||
|
|
||||||
|
alter table system_config add column premium_until timestamp;
|
||||||
|
alter table system_config add column premium_lifetime bool default false;
|
||||||
|
|
||||||
|
update info set schema_version = 54;
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
use chrono::NaiveDateTime;
|
||||||
use pk_macros::pk_model;
|
use pk_macros::pk_model;
|
||||||
|
|
||||||
use sqlx::{postgres::PgTypeInfo, Database, Decode, Postgres, Type};
|
use sqlx::{postgres::PgTypeInfo, Database, Decode, Postgres, Type};
|
||||||
|
|
@ -87,4 +88,8 @@ struct SystemConfig {
|
||||||
name_format: Option<String>,
|
name_format: Option<String>,
|
||||||
#[json = "description_templates"]
|
#[json = "description_templates"]
|
||||||
description_templates: Vec<String>,
|
description_templates: Vec<String>,
|
||||||
|
#[json = "premium_until"]
|
||||||
|
premium_until: Option<NaiveDateTime>,
|
||||||
|
#[json = "premium_lifetime"]
|
||||||
|
premium_lifetime: bool
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue