Replace guild access with owner-managed whitelist
This commit is contained in:
+1
-1
@@ -5,7 +5,7 @@ COPY src/ ./
|
||||
RUN dotnet publish -c Release -r linux-musl-x64 --self-contained true -o /out
|
||||
|
||||
FROM alpine:3.23
|
||||
RUN apk add --no-cache ca-certificates tzdata libgcc libstdc++
|
||||
RUN apk add --no-cache ca-certificates tzdata libgcc libstdc++ && mkdir /data && chown 65532:65532 /data
|
||||
COPY --from=build /out/Beetlejuice /usr/local/bin/beetlejuice
|
||||
USER 65532:65532
|
||||
ENTRYPOINT ["/usr/local/bin/beetlejuice"]
|
||||
|
||||
+27
-4
@@ -13,8 +13,12 @@ string Env(string key, string? fallback = null) => Environment.GetEnvironmentVar
|
||||
?? throw new InvalidOperationException($"Missing {key}");
|
||||
string discordToken = Env("DISCORD_TOKEN");
|
||||
if (discordToken == "REPLACE_IN_COOLIFY") { Console.WriteLine("Set DISCORD_TOKEN in Coolify, then restart Beetlejuice."); await Task.Delay(Timeout.Infinite); return; }
|
||||
ulong guildId = ulong.Parse(Env("DISCORD_GUILD_ID"));
|
||||
var roles = Env("DISCORD_ALLOWED_ROLE_IDS", "").Split(',', StringSplitOptions.RemoveEmptyEntries).Select(ulong.Parse).ToHashSet();
|
||||
const ulong initialUser = 227696176412098560;
|
||||
string whitelistPath = Env("WHITELIST_PATH", "/data/whitelist");
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(whitelistPath)!);
|
||||
var whitelist = File.Exists(whitelistPath) ? File.ReadAllLines(whitelistPath).Select(ulong.Parse).ToHashSet() : [initialUser];
|
||||
if (!File.Exists(whitelistPath)) File.WriteAllLines(whitelistPath, whitelist.Select(x => x.ToString()));
|
||||
var whitelistLock = new object();
|
||||
string rconPassword = Env("RCON_PASSWORD");
|
||||
if (rconPassword.Length != 64) throw new InvalidOperationException("RCON_PASSWORD must be 64 characters");
|
||||
var zone = TimeZoneInfo.FindSystemTimeZoneById(Env("AUTO_RESTART_TIMEZONE", "Australia/Brisbane"));
|
||||
@@ -30,8 +34,22 @@ builder.Services.AddDiscordGateway(o => { o.Token = discordToken; o.Intents = Ga
|
||||
.AddApplicationCommands();
|
||||
var host = builder.Build();
|
||||
|
||||
bool Allowed(ApplicationCommandContext c) => c.Interaction.GuildId == guildId && c.User is GuildInteractionUser u &&
|
||||
(roles.Count == 0 || u.RoleIds.Any(roles.Contains));
|
||||
bool Allowed(ApplicationCommandContext c) { lock (whitelistLock) return whitelist.Contains(c.User.Id); }
|
||||
string Whitelist(ApplicationCommandContext c, string discordId, bool add)
|
||||
{
|
||||
if (c.User.Id != initialUser) return "Not authorised.";
|
||||
if (!ulong.TryParse(discordId, out ulong id)) return "Invalid Discord ID.";
|
||||
if (!add && id == initialUser) return "The whitelist owner cannot be removed.";
|
||||
lock (whitelistLock)
|
||||
{
|
||||
bool changed = add ? whitelist.Add(id) : whitelist.Remove(id);
|
||||
if (!changed) return add ? "Already whitelisted." : "Not whitelisted.";
|
||||
string temp = whitelistPath + ".tmp";
|
||||
File.WriteAllLines(temp, whitelist.Order().Select(x => x.ToString()));
|
||||
File.Move(temp, whitelistPath, true);
|
||||
return $"{(add ? "Added" : "Removed")} <@{id}>.";
|
||||
}
|
||||
}
|
||||
async Task<string> Command(string command, bool allowDisconnect = false)
|
||||
{
|
||||
var address = (await Dns.GetHostAddressesAsync(Env("RCON_HOST", "zomboid"))).First(x => x.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork);
|
||||
@@ -129,6 +147,11 @@ host.AddSlashCommand("restart", "Restart when no players are online", (Applicati
|
||||
Allowed(c) ? Manual() : Task.FromResult("Not authorised."));
|
||||
host.AddSlashCommand("players", "List online players", async (ApplicationCommandContext c) =>
|
||||
!Allowed(c) ? "Not authorised." : await PlayerList());
|
||||
host.AddSlashCommandGroup("whitelist", "Manage bot access", group =>
|
||||
{
|
||||
group.AddSubCommand("add", "Add a Discord user", (string discordId, ApplicationCommandContext c) => Whitelist(c, discordId, true));
|
||||
group.AddSubCommand("del", "Remove a Discord user", (string discordId, ApplicationCommandContext c) => Whitelist(c, discordId, false));
|
||||
});
|
||||
|
||||
async Task<string> Status() { try { return $"Server online; {(await Players()).Count} player(s)."; } catch { return "Server unavailable."; } }
|
||||
async Task<string> PlayerList()
|
||||
|
||||
Reference in New Issue
Block a user