Use structured localized Discord embeds
This commit is contained in:
+25
-16
@@ -1,4 +1,5 @@
|
|||||||
using System.Buffers.Binary;
|
using System.Buffers.Binary;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
@@ -37,11 +38,14 @@ 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, params (string Name, string Value)[] fields)
|
string Time(DateTimeOffset value) => $"<t:{value.ToUnixTimeSeconds()}:F>\n<t:{value.ToUnixTimeSeconds()}:R>";
|
||||||
|
InteractionMessageProperties Reply(string title, string text, int color, params (string Name, string Value, bool Inline)[] fields)
|
||||||
{
|
{
|
||||||
var embed = new EmbedProperties().WithTitle(title).WithDescription(text).WithColor(new(color))
|
var embed = new EmbedProperties().WithTitle(title).WithColor(new(color))
|
||||||
.WithTimestamp(DateTimeOffset.UtcNow).WithFooter(new EmbedFooterProperties().WithText("Beetlejuice • Project Zomboid"));
|
.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()));
|
if (text.Length > 0) embed.WithDescription(text);
|
||||||
|
if (fields.Length > 0) embed.AddFields(fields.Select(x =>
|
||||||
|
new EmbedFieldProperties().WithName(x.Name).WithValue(x.Value).WithInline(x.Inline)));
|
||||||
return new InteractionMessageProperties().AddEmbeds(embed).WithFlags(MessageFlags.Ephemeral);
|
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);
|
InteractionMessageProperties Denied(string text = "You are not authorised to use this command.") => Reply("⛔ Access denied", text, 0xED4245);
|
||||||
@@ -57,7 +61,8 @@ InteractionMessageProperties Whitelist(ApplicationCommandContext c, User user, b
|
|||||||
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, ("Action", add ? "Added" : "Removed"));
|
return Reply("Whitelist updated", "Access control was updated successfully.", 0x57F287,
|
||||||
|
("User", $"<@{user.Id}>\n`{user.Id}`", true), ("Action", add ? "`ADDED`" : "`REMOVED`", true));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
async Task<string> Command(string command, bool allowDisconnect = false)
|
async Task<string> Command(string command, bool allowDisconnect = false)
|
||||||
@@ -130,14 +135,14 @@ async Task<InteractionMessageProperties> Manual()
|
|||||||
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", "The server cannot restart while players are connected.", 0xED4245,
|
if (count != 0) return Reply("Restart denied", "The server cannot restart while players are connected.", 0xED4245,
|
||||||
("Players online", count.ToString()));
|
("Players Online", $"`{count}`", true));
|
||||||
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 initiated", "No players are online. The server is restarting safely.", 0x57F287,
|
return Reply("Restart initiated", "The server is restarting safely.", 0x57F287,
|
||||||
("Cooldown", "10 minutes"));
|
("Requested", Time(DateTimeOffset.UtcNow), false), ("Cooldown Ends", Time(DateTimeOffset.UtcNow + cooldown), false));
|
||||||
}
|
}
|
||||||
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(); }
|
||||||
@@ -198,20 +203,24 @@ async Task<InteractionMessageProperties> Status()
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
int count = (await Players()).Count;
|
long started = Stopwatch.GetTimestamp();
|
||||||
return Reply("Project Zomboid", "The server is online and responding.", 0x57F287,
|
await Command("list");
|
||||||
("Status", "🟢 Online"), ("Players", count == 0 ? "None" : count.ToString()));
|
long latency = (long)Stopwatch.GetElapsedTime(started).TotalMilliseconds;
|
||||||
|
return Reply("Online", "", 0x57F287,
|
||||||
|
("Response Time", $"`{latency} ms`", true), ("Next Restart", Time(Next()), false));
|
||||||
}
|
}
|
||||||
catch { return Reply("Project Zomboid", "The server is offline, restarting, or unreachable.", 0xED4245, ("Status", "🔴 Unavailable")); }
|
catch { return Reply("Unavailable", "The server is offline, restarting, or unreachable.", 0xED4245); }
|
||||||
}
|
}
|
||||||
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 ? "The server is currently empty." : p.Names.Length == 0
|
if (p.Count == 0) return Reply("Online players", "", 0x5865F2, ("Connected", "`0`", true));
|
||||||
? "Player names are unavailable." : string.Join("\n", p.Names.Select(x => $"• **{x}**")), 0x5865F2,
|
string names = p.Names.Length == 0 ? "Names unavailable." :
|
||||||
("Count", p.Count.ToString()));
|
string.Join("\n", p.Names.Take(25).Select((name, index) => $"`{index + 1:00}` **{name}**"));
|
||||||
|
return Reply("Online players", "", 0x5865F2,
|
||||||
|
("Connected", $"`{p.Count}`", true), ("Players", names, false));
|
||||||
}
|
}
|
||||||
catch { return Reply("❌ Player query failed", "Unable to reach the Project Zomboid server.", 0xED4245); }
|
catch { return Reply("❌ Player query failed", "Unable to reach the Project Zomboid server.", 0xED4245); }
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user