Add a simple discord bot to manage the server

This commit is contained in:
Sanae 2022-06-12 18:48:24 -06:00
parent 774ef20bb4
commit 561d633e40
6 changed files with 122 additions and 27 deletions

View File

@ -13,6 +13,12 @@ public static class CommandHandler {
Handlers[name] = handler;
}
public static void RegisterCommandAliases(Handler handler, params string[] names) {
foreach (string name in names) {
Handlers.Add(name, handler);
}
}
public static Response GetResult(string input) {
try {
string[] args = input.Split(' ');

83
Server/DiscordBot.cs Normal file
View File

@ -0,0 +1,83 @@
using DSharpPlus;
using DSharpPlus.Entities;
using Microsoft.Extensions.Logging;
using Shared;
namespace Server;
public class DiscordBot {
private DiscordClient? DiscordClient;
private string? Token;
private Settings.DiscordTable Config => Settings.Instance.Discord;
private string Prefix => Config.Prefix;
private readonly Logger Logger = new Logger("Discord");
private DiscordChannel? LogChannel;
public DiscordBot() {
Token = Config.Token;
Logger.AddLogHandler(Log);
if (Config.Token == null) return;
Settings.LoadHandler += SettingsLoadHandler;
}
private async void SettingsLoadHandler() {
try {
if (DiscordClient == null || Token != Config.Token)
Run();
if (Config.LogChannel != null)
LogChannel = await (DiscordClient?.GetChannelAsync(ulong.Parse(Config.LogChannel)) ??
throw new NullReferenceException("Discord client not setup yet!"));
} catch (Exception e) {
Logger.Error($"Failed to get log channel \"{Config.LogChannel}\"");
Logger.Error(e);
}
}
private async void Log(string source, string level, string text, ConsoleColor _) {
try {
if (DiscordClient != null && LogChannel != null) {
await DiscordClient.SendMessageAsync(LogChannel,
$"Console log:```{Logger.PrefixNewLines(text, $"{level} [{source}]")}```");
}
} catch (Exception e) {
await Console.Error.WriteLineAsync("Exception in discord logger");
await Console.Error.WriteLineAsync(e.ToString());
}
}
public async void Run() {
Token = Config.Token;
DiscordClient?.Dispose();
if (Config.Token == null) {
DiscordClient = null;
return;
}
try {
DiscordClient = new DiscordClient(new DiscordConfiguration {
Token = Config.Token,
MinimumLogLevel = LogLevel.None
});
await DiscordClient.ConnectAsync(new DiscordActivity("Hide and Seek", ActivityType.Competing));
SettingsLoadHandler();
string mentionPrefix = $"{DiscordClient.CurrentUser.Mention} ";
DiscordClient.MessageCreated += async (_, args) => {
DiscordMessage msg = args.Message;
Console.WriteLine(
$"{msg.Content} {DiscordClient.CurrentUser.Mention} {msg.Content.StartsWith(mentionPrefix)}");
if (msg.Content.StartsWith(Prefix)) {
await msg.Channel.TriggerTypingAsync();
await msg.RespondAsync(string.Join('\n',
CommandHandler.GetResult(msg.Content[Prefix.Length..]).ReturnStrings));
} else if (msg.Content.StartsWith(mentionPrefix)) {
await msg.Channel.TriggerTypingAsync();
await msg.RespondAsync(string.Join('\n',
CommandHandler.GetResult(msg.Content[mentionPrefix.Length..]).ReturnStrings));
}
};
} catch (Exception e) {
Logger.Error("Exception occurred in discord runner!");
Logger.Error(e);
}
}
}

View File

@ -12,6 +12,8 @@ HashSet<int> shineBag = new HashSet<int>();
CancellationTokenSource cts = new CancellationTokenSource();
Task listenTask = server.Listen(cts.Token);
Logger consoleLogger = new Logger("Console");
DiscordBot bot = new DiscordBot();
bot.Run();
server.ClientJoined += (c, _) => {
c.Metadata["shineSync"] = new ConcurrentBag<int>();
@ -453,15 +455,10 @@ Console.CancelKeyPress += (_, e) => {
cts.Cancel();
};
CommandHandler.RegisterCommand("exit", _ => {
CommandHandler.RegisterCommandAliases(_ => {
cts.Cancel();
return "Shutting down clients";
});
CommandHandler.RegisterCommand("quit", _ => {
cts.Cancel();
return "Shutting down clients";
});
return "Shutting down";
}, "exit", "quit", "q");
Task.Run(() => {
consoleLogger.Info("Run help command for valid commands.");

View File

@ -12,6 +12,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="DSharpPlus" Version="4.3.0-nightly-01142" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
</ItemGroup>

View File

@ -9,6 +9,7 @@ namespace Server;
public class Settings {
public static Settings Instance = new Settings();
private static readonly Logger Logger = new Logger("Settings");
public static Action? LoadHandler;
static Settings() {
LoadSettings();
@ -24,9 +25,9 @@ public class Settings {
catch (Exception e) {
Logger.Warn($"Failed to load settings.json: {e}");
}
} else {
SaveSettings();
}
SaveSettings();
LoadHandler?.Invoke();
}
public static void SaveSettings() {
@ -43,6 +44,7 @@ public class Settings {
public FlipTable Flip { get; set; } = new FlipTable();
public ScenarioTable Scenario { get; set; } = new ScenarioTable();
public BannedPlayers BanList { get; set; } = new BannedPlayers();
public DiscordTable Discord { get; set; } = new DiscordTable();
public class ServerTable {
public string Address { get; set; } = IPAddress.Any.ToString();
@ -70,4 +72,10 @@ public class Settings {
public List<Guid> Players { get; set; } = new List<Guid>();
public FlipOptions Pov { get; set; } = FlipOptions.Both;
}
public class DiscordTable {
public string? Token { get; set; }
public string Prefix { get; set; } = "$";
public string? LogChannel { get; set; }
}
}

View File

@ -9,27 +9,15 @@ public class Logger {
public string Name { get; set; }
public void Info(string text) {
Console.ResetColor();
Console.Write(PrefixNewLines(text, $"Info [{Name}]"));
}
public void Info(string text) => Handler?.Invoke(Name, "Info", text, ConsoleColor.White);
public void Warn(string text) {
Console.ForegroundColor = ConsoleColor.Yellow;
Console.Write(PrefixNewLines(text, $"Warn [{Name}]"));
}
public void Warn(string text) => Handler?.Invoke(Name, "Warn", text, ConsoleColor.Yellow);
public void Error(string text) {
Console.ForegroundColor = ConsoleColor.Red;
Console.Write(PrefixNewLines(text, $"Error [{Name}]"));
}
public void Error(string text) => Handler?.Invoke(Name, "Error", text, ConsoleColor.Red);
public void Error(Exception error) {
Console.ForegroundColor = ConsoleColor.Red;
Console.Write(PrefixNewLines(error.ToString(), $"Error [{Name}]"));
}
public void Error(Exception error) => Error(error.ToString());
private string PrefixNewLines(string text, string prefix) {
public static string PrefixNewLines(string text, string prefix) {
StringBuilder builder = new StringBuilder();
foreach (string str in text.Split('\n'))
builder
@ -38,4 +26,16 @@ public class Logger {
.AppendLine(str);
return builder.ToString();
}
public delegate void LogHandler(string source, string level, string text, ConsoleColor color);
private static LogHandler? Handler;
public static void AddLogHandler(LogHandler handler) => Handler += handler;
static Logger() {
AddLogHandler((source, level, text, color) => {
Console.ForegroundColor = color;
Console.Write(PrefixNewLines(text, $"{level} [{source}]"));
});
}
}