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;
|
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)]
|
[JsonProperty("token", Required = Required.Always)]
|
||||||
public string Token { get; set; } = default!;
|
[Option('t', "token", HelpText = "The Discord bot token", Required = true)]
|
||||||
[JsonProperty("port", Required = Required.Always)]
|
public string Token { get; init; } = default!;
|
||||||
public int Port { get; set; } = 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)]
|
[JsonProperty("channels", Required = Required.Always)]
|
||||||
public IEnumerable<ulong> Channels { get; set; } = default!;
|
[Option('c', "channel", HelpText = "The list of whitelisted channels", Required = true, Min = 1)]
|
||||||
[JsonProperty("prefix", Required = Required.Always)]
|
public IEnumerable<ulong> Channels { get; init; } = default!;
|
||||||
public string Prefix { get; set; } = 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;
|
||||||
using Discord.Commands;
|
using Discord.Commands;
|
||||||
using Discord.Rest;
|
using Discord.Rest;
|
||||||
@ -60,14 +61,19 @@ public class Program : IDisposable {
|
|||||||
|
|
||||||
|
|
||||||
public static Task<int> Main(string[] args)
|
public static Task<int> Main(string[] args)
|
||||||
=> JsonConvert.DeserializeObject<BotConfiguration>(File.ReadAllText("config.json")) is BotConfiguration config
|
=> Parser.Default.ParseArguments<BotConfiguration, ConfigFile>(args)
|
||||||
? new Program(config).RunAsync()
|
.MapResult<BotConfiguration, ConfigFile, Task<int>>(
|
||||||
: throw new InvalidProgramException("Configuration file missing!");
|
RunWithConfig,
|
||||||
|
RunWithConfig,
|
||||||
|
errs => Task.FromResult(1));
|
||||||
|
|
||||||
|
private static Task<int> RunWithConfig(IBotConfigurator arg) => new Program(arg.Config).RunAsync();
|
||||||
|
|
||||||
public async Task<int> RunAsync() {
|
public async Task<int> RunAsync() {
|
||||||
await _client.LoginAsync(TokenType.Bot, _config.Token);
|
await _client.LoginAsync(TokenType.Bot, _config.Token);
|
||||||
await _client.StartAsync();
|
await _client.StartAsync();
|
||||||
await VerifyTextChannels();
|
if (!await HasValidChannels())
|
||||||
|
return 1;
|
||||||
StartWebSocketServer();
|
StartWebSocketServer();
|
||||||
|
|
||||||
// Block this task until the program is closed.
|
// Block this task until the program is closed.
|
||||||
@ -75,11 +81,21 @@ public class Program : IDisposable {
|
|||||||
return 0;
|
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 => {
|
private void StartWebSocketServer() => _wssv.Start(socket => {
|
||||||
socket.OnOpen = async () => await SocketOpened(socket);
|
socket.OnOpen = async () => await SocketOpened(socket);
|
||||||
socket.OnClose = async () => await SocketClosed(socket);
|
socket.OnClose = async () => await SocketClosed(socket);
|
||||||
socket.OnMessage = async message => await SocketReceived(socket, message);
|
socket.OnMessage = async message => await SocketReceived(socket, message);
|
||||||
});
|
});
|
||||||
|
|
||||||
private async IAsyncEnumerable<ITextChannel> GetValidChannels(IEnumerable<ulong> ids) {
|
private async IAsyncEnumerable<ITextChannel> GetValidChannels(IEnumerable<ulong> ids) {
|
||||||
foreach (var channelId in ids) {
|
foreach (var channelId in ids) {
|
||||||
var channel = await _client.GetChannelAsync(channelId);
|
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) {
|
private async Task SocketReceived(IWebSocketConnection socket, string message) {
|
||||||
if (JsonConvert.DeserializeObject<CapabilityMessage>(message) is not CapabilityMessage capability) return;
|
if (JsonConvert.DeserializeObject<CapabilityMessage>(message) is not CapabilityMessage capability) return;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user