using System; using System.IO; using System.Linq; using System.Threading; using ForgeCore.Assemble; using ForgeCoreAPI; using LibAC.Arguments; using LibAC.NBT; using LibAC.NBT.API; namespace ForgeCore; public class ForgeCore { public static int Main(string[] args) { Arguments arguments = ArgumentParser.Parse(args); if (arguments.HasArg("help") || arguments.Count == 0) { // Print the help message for the default CLI Args ArgumentBuilder builder = new ArgumentBuilder(); builder.withVersionArgument().withHelpArgument(); builder.withStringArgument("plugindir", "Plugins", false); builder.withBooleanArgument("daemon", true); builder.withStringArgument("libdir", "Libs", false); Arguments defaults = builder.Build(); Console.WriteLine(ArgumentHelpers.GenerateHelpMessage(defaults.GetAllArguments().ToList(), "ForgeCore")); return 0; } if (arguments.HasArg("version")) { Console.WriteLine($"ForgeCore Version {ASMInfo.BotVer}"); return 0; } if (arguments.HasArg("plugindir")) PluginSystem.PluginDirectory = arguments.GetArgument("plugindir").GetValue() as string; if(arguments.HasArg("libdir")) PluginSystem.LibraryDir = arguments.GetArgument("libdir").GetValue() as string; if (!Directory.Exists(PluginSystem.PluginDirectory)) Directory.CreateDirectory(PluginSystem.PluginDirectory); if(!Directory.Exists(PluginSystem.LibraryDir)) Directory.CreateDirectory(PluginSystem.LibraryDir); PluginSystem.InitializeSystem(PluginSystem.PluginDirectory); SharedSessionData sessionData = SharedSessionData.GetInstance(); // Subscribe to the interrupt event Console.CancelKeyPress += delegate { Console.WriteLine("CTRL+C Detected. Processing shutdown request..."); SharedSessionData.GetInstance().ShouldShutdown = true; }; // Start the server tick loop while (!sessionData.ShouldShutdown) { long tasksExecuted = 0; if (!sessionData.HasShutdownMethod) { sessionData.ShouldShutdown = true; Console.WriteLine("/!\\ FATAL ERROR /!\\\n\nNo plugin has a method for shutting down. This server would be unable to cleanly shut down. Consider adding a plugin with a shutdown method of any kind\n\nCTRL+C is not advised, as server settings may not get saved with an interrupt"); } foreach (var plugin in PluginSystem.Plugins) { if (plugin.enabled) { plugin.plugin.tick(); tasksExecuted++; } } sessionData.TasksLastTick = tasksExecuted; sessionData.TotalTicks++; if(sessionData.TotalTasksPerTick == 0) sessionData.TotalTasksPerTick = tasksExecuted; Thread.Sleep(TimeSpan.FromSeconds(5)); } Console.WriteLine("Preparing to shut down... Please wait..."); Console.WriteLine("Gathering plugin settings..."); CompoundTag saveData = new CompoundTag(); foreach (var pluginContainer in PluginSystem.Plugins) { pluginContainer.plugin.TearDown(); CompoundTag entry = new CompoundTag(); NbtUtils.WriteBoolean(entry, "enabled", pluginContainer.enabled); entry.Add("data", pluginContainer.plugin.SaveConfig()); saveData.Add(pluginContainer.pluginName, entry); } Console.WriteLine("Saving plugin data..."); NbtIo.Write("PluginStorage.dat", saveData); Console.WriteLine("> Plugin Storage saved."); Console.WriteLine("> Exiting server..."); Thread.Sleep(TimeSpan.FromSeconds(5)); return 0; } }