Added CLI configuration
Also halt if no valid channels are connected! Changelog: added
This commit is contained in:
parent
d8c1f81023
commit
d120860322
@ -1,14 +1,46 @@
|
||||
using Newtonsoft.Json;
|
||||
using CommandLine;
|
||||
using Newtonsoft.Json;
|
||||
using System.Text;
|
||||
|
||||
namespace MinecraftDiscordBot;
|
||||
|
||||
public class BotConfiguration {
|
||||
[Verb("config", HelpText = "Manually configure the bot with CLI arguments.")]
|
||||
public class BotConfiguration : IBotConfiguration, IBotConfigurator {
|
||||
private const string DEFAULT_PREFIX = "!";
|
||||
private const int DEFAULT_PORT = 8080;
|
||||
[JsonProperty("token", Required = Required.Always)]
|
||||
public string Token { get; set; } = default!;
|
||||
[JsonProperty("port", Required = Required.Always)]
|
||||
public int Port { get; set; } = default!;
|
||||
[Option('t', "token", HelpText = "The Discord bot token", Required = true)]
|
||||
public string Token { get; init; } = default!;
|
||||
[JsonProperty("port", Required = Required.DisallowNull)]
|
||||
[Option('p', "port", Default = DEFAULT_PORT, HelpText = "The websocket server port")]
|
||||
public int Port { get; init; } = DEFAULT_PORT;
|
||||
[JsonProperty("channels", Required = Required.Always)]
|
||||
public IEnumerable<ulong> Channels { get; set; } = default!;
|
||||
[JsonProperty("prefix", Required = Required.Always)]
|
||||
public string Prefix { get; set; } = default!;
|
||||
[Option('c', "channel", HelpText = "The list of whitelisted channels", Required = true, Min = 1)]
|
||||
public IEnumerable<ulong> Channels { get; init; } = default!;
|
||||
[JsonProperty("prefix", Required = Required.DisallowNull)]
|
||||
[Option("prefix", Default = DEFAULT_PREFIX, HelpText = "The Discord bot command prefix")]
|
||||
public string Prefix { get; init; } = DEFAULT_PREFIX;
|
||||
[JsonIgnore]
|
||||
public BotConfiguration Config => this;
|
||||
}
|
||||
|
||||
public interface IBotConfigurator {
|
||||
BotConfiguration Config { get; }
|
||||
}
|
||||
|
||||
public interface IBotConfiguration {
|
||||
string Token { get; }
|
||||
int Port { get; }
|
||||
IEnumerable<ulong> Channels { get; }
|
||||
string Prefix { get; }
|
||||
}
|
||||
|
||||
[Verb("file", true, HelpText = "Load a bot configuration file.")]
|
||||
public class ConfigFile : IBotConfigurator {
|
||||
private const string DEFAULT_CONFIGPATH = "config.json";
|
||||
[Option('f', "file", Default = DEFAULT_CONFIGPATH, HelpText = "The path of the configuration file")]
|
||||
public string ConfigPath { get; set; } = DEFAULT_CONFIGPATH;
|
||||
public BotConfiguration Config
|
||||
=> JsonConvert.DeserializeObject<BotConfiguration>(File.ReadAllText(ConfigPath, Encoding.UTF8))
|
||||
?? throw new InvalidProgramException("Invalid empty config file!");
|
||||
}
|
@ -1,3 +1,4 @@
|
||||
using CommandLine;
|
||||
using Discord;
|
||||
using Discord.Commands;
|
||||
using Discord.Rest;
|
||||
@ -60,14 +61,19 @@ public class Program : IDisposable {
|
||||
|
||||
|
||||
public static Task<int> Main(string[] args)
|
||||
=> JsonConvert.DeserializeObject<BotConfiguration>(File.ReadAllText("config.json")) is BotConfiguration config
|
||||
? new Program(config).RunAsync()
|
||||
: throw new InvalidProgramException("Configuration file missing!");
|
||||
=> Parser.Default.ParseArguments<BotConfiguration, ConfigFile>(args)
|
||||
.MapResult<BotConfiguration, ConfigFile, Task<int>>(
|
||||
RunWithConfig,
|
||||
RunWithConfig,
|
||||
errs => Task.FromResult(1));
|
||||
|
||||
private static Task<int> RunWithConfig(IBotConfigurator arg) => new Program(arg.Config).RunAsync();
|
||||
|
||||
public async Task<int> RunAsync() {
|
||||
await _client.LoginAsync(TokenType.Bot, _config.Token);
|
||||
await _client.StartAsync();
|
||||
await VerifyTextChannels();
|
||||
if (!await HasValidChannels())
|
||||
return 1;
|
||||
StartWebSocketServer();
|
||||
|
||||
// Block this task until the program is closed.
|
||||
@ -75,11 +81,21 @@ public class Program : IDisposable {
|
||||
return 0;
|
||||
}
|
||||
|
||||
private async Task<bool> HasValidChannels() {
|
||||
if (await GetValidChannels(_whitelistedChannels).ToArrayAsync() is not { Length: > 0 } channels) {
|
||||
await LogError(BotSource, new InvalidOperationException("No valid textchannel was whitelisted!"));
|
||||
return false;
|
||||
}
|
||||
_channels = channels;
|
||||
return true;
|
||||
}
|
||||
|
||||
private void StartWebSocketServer() => _wssv.Start(socket => {
|
||||
socket.OnOpen = async () => await SocketOpened(socket);
|
||||
socket.OnClose = async () => await SocketClosed(socket);
|
||||
socket.OnMessage = async message => await SocketReceived(socket, message);
|
||||
});
|
||||
|
||||
private async IAsyncEnumerable<ITextChannel> GetValidChannels(IEnumerable<ulong> ids) {
|
||||
foreach (var channelId in ids) {
|
||||
var channel = await _client.GetChannelAsync(channelId);
|
||||
@ -99,8 +115,6 @@ public class Program : IDisposable {
|
||||
}
|
||||
}
|
||||
|
||||
private async Task VerifyTextChannels() => _channels = await GetValidChannels(_whitelistedChannels).ToArrayAsync();
|
||||
|
||||
private async Task SocketReceived(IWebSocketConnection socket, string message) {
|
||||
if (JsonConvert.DeserializeObject<CapabilityMessage>(message) is not CapabilityMessage capability) return;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user