Polish slash command embeds

This commit is contained in:
MrDevBot
2026-09-01 20:26:34 +10:00
parent aa8776bd2f
commit 2ca345d2be
+29 -17
View File
@@ -37,23 +37,27 @@ builder.Services.AddDiscordGateway(o => { o.Token = discordToken; o.Intents = Ga
.AddApplicationCommands(); .AddApplicationCommands();
var host = builder.Build(); var host = builder.Build();
InteractionMessageProperties Reply(string title, string text, int color) => new InteractionMessageProperties() InteractionMessageProperties Reply(string title, string text, int color, params (string Name, string Value)[] fields)
.AddEmbeds(new EmbedProperties().WithTitle(title).WithDescription(text).WithColor(new(color))) {
.WithFlags(MessageFlags.Ephemeral); var embed = new EmbedProperties().WithTitle(title).WithDescription(text).WithColor(new(color))
InteractionMessageProperties Denied(string text = "You are not authorised to use this command.") => Reply("Access denied", text, 0xED4245); .WithTimestamp(DateTimeOffset.UtcNow).WithFooter(new EmbedFooterProperties().WithText("Beetlejuice • Project Zomboid"));
if (fields.Length > 0) embed.AddFields(fields.Select(x => new EmbedFieldProperties().WithName(x.Name).WithValue(x.Value).WithInline()));
return new InteractionMessageProperties().AddEmbeds(embed).WithFlags(MessageFlags.Ephemeral);
}
InteractionMessageProperties Denied(string text = "You are not authorised to use this command.") => Reply("⛔ Access denied", text, 0xED4245);
bool Allowed(ApplicationCommandContext c) { lock (whitelistLock) return whitelist.Contains(c.User.Id); } bool Allowed(ApplicationCommandContext c) { lock (whitelistLock) return whitelist.Contains(c.User.Id); }
InteractionMessageProperties Whitelist(ApplicationCommandContext c, User user, bool add) InteractionMessageProperties Whitelist(ApplicationCommandContext c, User user, bool add)
{ {
if (c.User.Id != initialUser) return Denied("Only the whitelist owner can manage access."); if (c.User.Id != initialUser) return Denied("Only the whitelist owner can manage access.");
if (!add && user.Id == initialUser) return Reply("Whitelist unchanged", "The whitelist owner cannot be removed.", 0xFEE75C); if (!add && user.Id == initialUser) return Reply("⚠️ Whitelist unchanged", "The whitelist owner cannot be removed.", 0xFEE75C);
lock (whitelistLock) lock (whitelistLock)
{ {
bool changed = add ? whitelist.Add(user.Id) : whitelist.Remove(user.Id); bool changed = add ? whitelist.Add(user.Id) : whitelist.Remove(user.Id);
if (!changed) return Reply("Whitelist unchanged", add ? $"<@{user.Id}> is already whitelisted." : $"<@{user.Id}> is not whitelisted.", 0xFEE75C); if (!changed) return Reply("⚠️ Whitelist unchanged", add ? $"<@{user.Id}> is already whitelisted." : $"<@{user.Id}> is not whitelisted.", 0xFEE75C);
string temp = whitelistPath + ".tmp"; string temp = whitelistPath + ".tmp";
File.WriteAllLines(temp, whitelist.Order().Select(x => x.ToString())); File.WriteAllLines(temp, whitelist.Order().Select(x => x.ToString()));
File.Move(temp, whitelistPath, true); File.Move(temp, whitelistPath, true);
return Reply("Whitelist updated", $"{(add ? "Added" : "Removed")} <@{user.Id}>.", 0x57F287); return Reply("✅ Whitelist updated", $"{(add ? "Added" : "Removed")} <@{user.Id}>.", 0x57F287, ("Action", add ? "Added" : "Removed"));
} }
} }
async Task<string> Command(string command, bool allowDisconnect = false) async Task<string> Command(string command, bool allowDisconnect = false)
@@ -118,22 +122,24 @@ async Task Ready(string kind)
} }
async Task<InteractionMessageProperties> Manual() async Task<InteractionMessageProperties> Manual()
{ {
if (!await gate.WaitAsync(0)) return Reply("Restart busy", "A restart is already in progress.", 0xFEE75C); if (!await gate.WaitAsync(0)) return Reply("⏳ Restart in progress", "Please wait for the current restart to finish.", 0xFEE75C);
bool release = true; bool release = true;
try try
{ {
if (lastManual is { } last && DateTimeOffset.UtcNow - last < cooldown) if (lastManual is { } last && DateTimeOffset.UtcNow - last < cooldown)
return Reply("Restart cooldown", $"Try again in {Math.Ceiling((cooldown - (DateTimeOffset.UtcNow - last)).TotalSeconds)} seconds.", 0xFEE75C); return Reply("⏱️ Restart cooldown", $"Try again in {Math.Ceiling((cooldown - (DateTimeOffset.UtcNow - last)).TotalSeconds)} seconds.", 0xFEE75C);
int count = (await Players()).Count; int count = (await Players()).Count;
if (count == 0) count = (await Players()).Count; if (count == 0) count = (await Players()).Count;
if (count != 0) return Reply("Restart denied", $"{count} player{(count == 1 ? " is" : "s are")} online.", 0xED4245); if (count != 0) return Reply("🛑 Restart denied", "The server cannot restart while players are connected.", 0xED4245,
("Players online", count.ToString()));
await Quit(); await Quit();
lastManual = DateTimeOffset.UtcNow; lastManual = DateTimeOffset.UtcNow;
release = false; release = false;
_ = Task.Run(async () => { try { await Ready("Manual"); } finally { gate.Release(); } }); _ = Task.Run(async () => { try { await Ready("Manual"); } finally { gate.Release(); } });
return Reply("Restart accepted", "No players are online. The server is restarting.", 0x57F287); return Reply("🔄 Restart initiated", "No players are online. The server is restarting safely.", 0x57F287,
("Cooldown", "10 minutes"));
} }
catch (Exception e) { return Reply("Restart unavailable", e.Message, 0xED4245); } catch (Exception e) { return Reply("❌ Restart unavailable", e.Message, 0xED4245); }
finally { if (release) gate.Release(); } finally { if (release) gate.Release(); }
} }
async Task Warn(int seconds) async Task Warn(int seconds)
@@ -190,18 +196,24 @@ host.AddSlashCommandGroup("whitelist", "Manage bot access", group =>
async Task<InteractionMessageProperties> Status() async Task<InteractionMessageProperties> Status()
{ {
try { return Reply("Server online", $"{(await Players()).Count} player(s) connected.", 0x57F287); } try
catch { return Reply("Server unavailable", "Project Zomboid is offline, restarting, or unreachable.", 0xED4245); } {
int count = (await Players()).Count;
return Reply("Project Zomboid", "The server is online and responding.", 0x57F287,
("Status", "🟢 Online"), ("Players", count == 0 ? "None" : count.ToString()));
}
catch { return Reply("Project Zomboid", "The server is offline, restarting, or unreachable.", 0xED4245, ("Status", "🔴 Unavailable")); }
} }
async Task<InteractionMessageProperties> PlayerList() async Task<InteractionMessageProperties> PlayerList()
{ {
try try
{ {
var p = await Players(); var p = await Players();
return Reply("Online players", p.Count == 0 ? "No players are online." : p.Names.Length == 0 return Reply("👥 Online players", p.Count == 0 ? "The server is currently empty." : p.Names.Length == 0
? $"{p.Count} player(s) online; names unavailable." : string.Join("\n", p.Names.Select(x => $"• {x}")), 0x5865F2); ? "Player names are unavailable." : string.Join("\n", p.Names.Select(x => $"• **{x}**")), 0x5865F2,
("Count", p.Count.ToString()));
} }
catch { return Reply("Player query failed", "Unable to query the server.", 0xED4245); } catch { return Reply("❌ Player query failed", "Unable to reach the Project Zomboid server.", 0xED4245); }
} }
await host.StartAsync(); await host.StartAsync();