2018-05-06 20:09:17 +00:00
|
|
|
|
using Discord;
|
|
|
|
|
using Discord.WebSocket;
|
|
|
|
|
using System;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
|
|
|
|
namespace Kerobot
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
2018-05-11 06:13:00 +00:00
|
|
|
|
/// Program startup class.
|
2018-05-06 20:09:17 +00:00
|
|
|
|
/// </summary>
|
|
|
|
|
class Program
|
|
|
|
|
{
|
|
|
|
|
static DateTimeOffset _startTime;
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Timestamp specifying the date and time that the program began running.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public static DateTimeOffset StartTime => _startTime;
|
|
|
|
|
|
|
|
|
|
static Kerobot _main;
|
|
|
|
|
|
2018-05-11 06:13:00 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Entry point. Loads options, initializes all components, then connects to Discord.
|
|
|
|
|
/// </summary>
|
2018-05-06 20:09:17 +00:00
|
|
|
|
static async Task Main(string[] args)
|
|
|
|
|
{
|
|
|
|
|
_startTime = DateTimeOffset.UtcNow;
|
|
|
|
|
Console.WriteLine("Bot start time: " + _startTime.ToString("u"));
|
|
|
|
|
|
2018-05-11 06:13:00 +00:00
|
|
|
|
// Get instance configuration from file and parameters
|
2018-05-06 20:09:17 +00:00
|
|
|
|
var opts = Options.ParseOptions(args); // Program can exit here.
|
|
|
|
|
InstanceConfig cfg;
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
cfg = new InstanceConfig(opts);
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine(ex.Message);
|
|
|
|
|
Environment.ExitCode = 1;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2018-05-11 06:13:00 +00:00
|
|
|
|
// Quick test of database configuration
|
2018-05-06 20:09:17 +00:00
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
using (var d = new Npgsql.NpgsqlConnection(cfg.PostgresConnString))
|
|
|
|
|
{
|
|
|
|
|
await d.OpenAsync();
|
|
|
|
|
d.Close();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine("Could not establish a database connection! Check your settings and try again.");
|
|
|
|
|
Console.WriteLine($"Error: {ex.GetType().FullName}: {ex.Message}");
|
|
|
|
|
Environment.Exit(1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Configure Discord client
|
|
|
|
|
var client = new DiscordSocketClient(new DiscordSocketConfig()
|
|
|
|
|
{
|
|
|
|
|
DefaultRetryMode = RetryMode.AlwaysRetry,
|
|
|
|
|
MessageCacheSize = 0 // using our own
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Kerobot class initialization - will set up services and modules
|
|
|
|
|
_main = new Kerobot(cfg, client);
|
|
|
|
|
|
|
|
|
|
// Set up application close handler
|
|
|
|
|
Console.CancelKeyPress += Console_CancelKeyPress;
|
|
|
|
|
|
|
|
|
|
// TODO Set up unhandled exception handler
|
|
|
|
|
// send error notification to instance log channel, if possible
|
|
|
|
|
|
|
|
|
|
// And off we go.
|
|
|
|
|
await _main.DiscordClient.LoginAsync(Discord.TokenType.Bot, cfg.BotToken);
|
|
|
|
|
await _main.DiscordClient.StartAsync();
|
|
|
|
|
await Task.Delay(-1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static void Console_CancelKeyPress(object sender, ConsoleCancelEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
e.Cancel = true;
|
2018-05-11 06:13:00 +00:00
|
|
|
|
|
|
|
|
|
_main.InstanceLogAsync(true, "Kerobot", "Shutting down. Reason: Interrupt signal.");
|
|
|
|
|
|
|
|
|
|
// 5 seconds of leeway - any currently running tasks will need time to finish executing
|
|
|
|
|
var leeway = Task.Delay(5000);
|
|
|
|
|
|
|
|
|
|
// TODO periodic task service: stop processing, wait for all tasks to finish
|
|
|
|
|
// TODO notify services of shutdown
|
|
|
|
|
|
|
|
|
|
leeway.Wait();
|
|
|
|
|
|
|
|
|
|
bool success = _main.DiscordClient.StopAsync().Wait(1000);
|
|
|
|
|
if (!success) _main.InstanceLogAsync(false, "Kerobot",
|
|
|
|
|
"Failed to disconnect cleanly from Discord. Will force shut down.").Wait();
|
2018-05-06 20:09:17 +00:00
|
|
|
|
Environment.Exit(0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|