using System.Runtime.InteropServices; using IPinfo; namespace EmperorPalpatine; using Tomlet; class Program { public static IConfig Config { get; private set; } public static Database Database { get; private set; } public static IPinfoClient IPinfo { get; private set; } public static Filter[] Filters { get; private set; } public static VM[] VMs { get; private set; } public static DiscordBot Discord { get; private set; } private static CancellationTokenSource cts = new(); private static HTTPServer HTTP; static async Task Main(string[] args) { Utilities.Log(LogLevel.INFO, "Emperor Palpatine v4 is starting up..."); // Load configuration string configraw; try { configraw = File.ReadAllText("config.toml"); } catch (Exception ex) { Utilities.Log(LogLevel.FATAL, $"Failed to read config.toml: {ex.Message}"); Environment.Exit(1); return; } try { Config = TomletMain.To(configraw); } catch (Exception ex) { Utilities.Log(LogLevel.FATAL, $"Failed to parse config.toml: {ex.Message}"); Environment.Exit(1); return; } // Register kill signal handlers Console.CancelKeyPress += (_, _) => Exit(); PosixSignalRegistration.Create(PosixSignal.SIGTERM, _ => Exit()); // Initialize IPinfo IPinfo = new IPinfoClient.Builder().AccessToken(Config.IPInfoToken).Build(); // Initialize filters Filters = (Config.Filters?.Length > 0) ? Config.Filters.Select(f => new Filter(f)).ToArray() : []; // Initialize the database Database = new Database(Config.Database); await Database.InitAsync(); Utilities.Log(LogLevel.INFO, "Connected to MySQL Database."); // Initialize the Discord bot Discord = new DiscordBot(Config.Discord.Token, Config.Discord.ReportChannel); await Discord.Connect(); // Connect to VMs VMs = Config.VMs.Select(vm => new VM(Config.Username, vm, Database)).ToArray(); foreach (var vm in VMs) { vm.MessageIncident += (_, i) => Discord.FlagChatMessageAsync(i); vm.UsernameIncident += (_, i) => Discord.FlagUsernameAsync(i); await vm.OpenAsync(); } // Start the HTTP server HTTP = new HTTPServer(); HTTP.Run(); } public static void Exit() { Task.WaitAll(VMs.Select(vm => vm.CloseAsync()).ToArray()); cts.Cancel(); } }