separate libs, internal plugins, and shutdown improvements
This commit is contained in:
parent
b0e8a4d459
commit
b3bddfc5d1
7 changed files with 108 additions and 12 deletions
|
@ -5,8 +5,8 @@ using System.Reflection;
|
||||||
|
|
||||||
[assembly: AssemblyCompany("Piccari Creations")]
|
[assembly: AssemblyCompany("Piccari Creations")]
|
||||||
[assembly: AssemblyAlgorithmId(System.Configuration.Assemblies.AssemblyHashAlgorithm.MD5)]
|
[assembly: AssemblyAlgorithmId(System.Configuration.Assemblies.AssemblyHashAlgorithm.MD5)]
|
||||||
[assembly: AssemblyCopyright("(C) 2020 Tara Piccari")]
|
[assembly: AssemblyCopyright("(C) 2020-2024 Tara Piccari")]
|
||||||
[assembly: AssemblyFileVersion("6.0.1.0001")]
|
[assembly: AssemblyFileVersion("6.0.1.0002")]
|
||||||
[assembly: AssemblyDescription("ForgeCore Bot Server")]
|
[assembly: AssemblyDescription("ForgeCore Bot Server")]
|
||||||
|
|
||||||
namespace ForgeCore.Assemble
|
namespace ForgeCore.Assemble
|
||||||
|
@ -14,6 +14,6 @@ namespace ForgeCore.Assemble
|
||||||
public class ASMInfo
|
public class ASMInfo
|
||||||
{
|
{
|
||||||
public static string BotName = "ForgeCore";
|
public static string BotName = "ForgeCore";
|
||||||
public static string BotVer = "2.0.121724.1716";
|
public static string BotVer = "2.0.121824.1617";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
28
ForgeCore.cs
28
ForgeCore.cs
|
@ -23,8 +23,9 @@ public class ForgeCore
|
||||||
|
|
||||||
ArgumentBuilder builder = new ArgumentBuilder();
|
ArgumentBuilder builder = new ArgumentBuilder();
|
||||||
builder.withVersionArgument().withHelpArgument();
|
builder.withVersionArgument().withHelpArgument();
|
||||||
builder.withStringArgument("plugindir", "Plugins", true);
|
builder.withStringArgument("plugindir", "Plugins", false);
|
||||||
builder.withBooleanArgument("daemon", true);
|
builder.withBooleanArgument("daemon", true);
|
||||||
|
builder.withStringArgument("libdir", "Libs", false);
|
||||||
|
|
||||||
|
|
||||||
Arguments defaults = builder.Build();
|
Arguments defaults = builder.Build();
|
||||||
|
@ -41,20 +42,37 @@ public class ForgeCore
|
||||||
if (arguments.HasArg("plugindir"))
|
if (arguments.HasArg("plugindir"))
|
||||||
PluginSystem.PluginDirectory = arguments.GetArgument("plugindir").GetValue() as string;
|
PluginSystem.PluginDirectory = arguments.GetArgument("plugindir").GetValue() as string;
|
||||||
|
|
||||||
if (!Directory.Exists("Plugins"))
|
if(arguments.HasArg("libdir"))
|
||||||
Directory.CreateDirectory("Plugins");
|
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);
|
PluginSystem.InitializeSystem(PluginSystem.PluginDirectory);
|
||||||
|
|
||||||
SharedSessionData sessionData = SharedSessionData.GetInstance();
|
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
|
// Start the server tick loop
|
||||||
while (!sessionData.ShouldShutdown)
|
while (!sessionData.ShouldShutdown)
|
||||||
{
|
{
|
||||||
long tasksExecuted = 0;
|
long tasksExecuted = 0;
|
||||||
if (sessionData.TotalTasksPerTick == 0 && sessionData.TotalTicks > 0)
|
if (!sessionData.HasShutdownMethod)
|
||||||
{
|
{
|
||||||
sessionData.ShouldShutdown = true;
|
sessionData.ShouldShutdown = true;
|
||||||
Console.WriteLine("FATAL ERROR\n\nNo plugins are loaded. This server would be doing nothing in a infinite loop with no way to exit. Aborting startup procedure. \n\n\n>> Recommendation: Add one of the standard ForgeCore Plugins which include methods of executing a shutdown");
|
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)
|
foreach (var plugin in PluginSystem.Plugins)
|
||||||
|
|
|
@ -4,8 +4,8 @@ using System.Reflection;
|
||||||
[assembly:AssemblyCompany("Piccari Creations")]
|
[assembly:AssemblyCompany("Piccari Creations")]
|
||||||
[assembly:AssemblyProduct("ForgeCoreAPI")]
|
[assembly:AssemblyProduct("ForgeCoreAPI")]
|
||||||
[assembly:AssemblyCopyright("Copyright (c) 2024 Piccari Creations")]
|
[assembly:AssemblyCopyright("Copyright (c) 2024 Piccari Creations")]
|
||||||
[assembly:AssemblyVersion("2.0.0.0")]
|
[assembly:AssemblyVersion("2.0.0.1")]
|
||||||
[assembly:AssemblyFileVersion("2.0.0.0")]
|
[assembly:AssemblyFileVersion("2.0.0.1")]
|
||||||
[assembly:AssemblyDescription("API Library for ForgeCore")]
|
[assembly:AssemblyDescription("API Library for ForgeCore")]
|
||||||
|
|
||||||
|
|
||||||
|
@ -14,5 +14,7 @@ namespace ForgeCoreAPI.ASM
|
||||||
public class ASMInfo
|
public class ASMInfo
|
||||||
{
|
{
|
||||||
// Static readonly assembly attributes
|
// Static readonly assembly attributes
|
||||||
|
public static readonly string ASSEMBLY_NAME = "ForgeCoreAPI";
|
||||||
|
public static readonly string ASSEMBLY_VERSION = "2.0.121824.1618";
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -57,8 +57,10 @@ public interface IPlugin
|
||||||
public class ForgeCorePluginAttribute : Attribute
|
public class ForgeCorePluginAttribute : Attribute
|
||||||
{
|
{
|
||||||
public string pluginName;
|
public string pluginName;
|
||||||
public ForgeCorePluginAttribute(string PluginName)
|
public bool providesShutdownMethod = false;
|
||||||
|
public ForgeCorePluginAttribute(string PluginName, bool ProvidesShutdownMethod = false)
|
||||||
{
|
{
|
||||||
this.pluginName = PluginName;
|
this.pluginName = PluginName;
|
||||||
|
this.providesShutdownMethod = ProvidesShutdownMethod;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -5,4 +5,5 @@ public class PluginContainer
|
||||||
public IPlugin plugin;
|
public IPlugin plugin;
|
||||||
public bool enabled = true;
|
public bool enabled = true;
|
||||||
public string pluginName;
|
public string pluginName;
|
||||||
|
public bool providesShutdownMethod = false;
|
||||||
}
|
}
|
|
@ -9,13 +9,14 @@ public class PluginSystem
|
||||||
public static string PluginDirectory { get; set; } = "Plugins";
|
public static string PluginDirectory { get; set; } = "Plugins";
|
||||||
|
|
||||||
public static List<PluginContainer> Plugins = new List<PluginContainer>();
|
public static List<PluginContainer> Plugins = new List<PluginContainer>();
|
||||||
|
public static string LibraryDir { get; set; } = "Libs";
|
||||||
|
|
||||||
private static void PSysLog(string Message)
|
private static void PSysLog(string Message)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"[PLUGINS] {Message}");
|
Console.WriteLine($"[PLUGINS] {Message}");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void InitializeSystem(string pluginDirectory)
|
public static void InitializeSystem(string pluginDirectory, string libraryDirectory = "Libs")
|
||||||
{
|
{
|
||||||
CompoundTag pluginsData = new CompoundTag();
|
CompoundTag pluginsData = new CompoundTag();
|
||||||
if (!File.Exists("PluginStorage.dat"))
|
if (!File.Exists("PluginStorage.dat"))
|
||||||
|
@ -24,6 +25,66 @@ public class PluginSystem
|
||||||
// Leave pluginsData empty
|
// Leave pluginsData empty
|
||||||
} else pluginsData = NbtIo.Read("PluginStorage.dat");
|
} else pluginsData = NbtIo.Read("PluginStorage.dat");
|
||||||
|
|
||||||
|
// Search the primary executable for non-removable plugins
|
||||||
|
foreach (var asm in AppDomain.CurrentDomain.GetAssemblies())
|
||||||
|
{
|
||||||
|
foreach (var type in asm.GetTypes())
|
||||||
|
{
|
||||||
|
if (type.GetCustomAttribute<ForgeCorePluginAttribute>() != null)
|
||||||
|
{
|
||||||
|
ForgeCorePluginAttribute attr = type.GetCustomAttribute<ForgeCorePluginAttribute>();
|
||||||
|
PluginContainer container = new PluginContainer();
|
||||||
|
container.pluginName = attr.pluginName;
|
||||||
|
container.providesShutdownMethod = attr.providesShutdownMethod;
|
||||||
|
|
||||||
|
IPlugin plugin = Activator.CreateInstance(type) as IPlugin;
|
||||||
|
container.plugin = plugin;
|
||||||
|
plugin.Initialize();
|
||||||
|
|
||||||
|
|
||||||
|
PSysLog($"> Loading plugin: {container.pluginName}");
|
||||||
|
|
||||||
|
Tag? store = pluginsData.Get(container.pluginName);
|
||||||
|
if (store == null)
|
||||||
|
{
|
||||||
|
plugin.ResetMemory();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CompoundTag plugTag = (CompoundTag)store;
|
||||||
|
CompoundTag data = (CompoundTag)plugTag.Get("data");
|
||||||
|
|
||||||
|
bool enabled = NbtUtils.ReadBoolean(plugTag, "enabled");
|
||||||
|
container.enabled = enabled;
|
||||||
|
plugin.LoadConfig(data);
|
||||||
|
PSysLog($"> Loaded plugin: {container.pluginName}");
|
||||||
|
|
||||||
|
if (enabled)
|
||||||
|
{
|
||||||
|
plugin.Enable();
|
||||||
|
PSysLog($"> Enabled plugin: {container.pluginName}");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
plugin.Disable();
|
||||||
|
PSysLog($"> Disabled plugin: {container.pluginName}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Plugins.Add(container);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Search library folder for any libraries required to be loaded before the plugins
|
||||||
|
string[] libs = Directory.GetFiles(libraryDirectory, "*.dll");
|
||||||
|
foreach (string lib in libs)
|
||||||
|
{
|
||||||
|
Assembly.LoadFile(lib);
|
||||||
|
// We do not need to do anything else with the loaded library.
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Search the Plugins directory for DLL files
|
// Search the Plugins directory for DLL files
|
||||||
string[] files = Directory.GetFiles(pluginDirectory, "*.dll");
|
string[] files = Directory.GetFiles(pluginDirectory, "*.dll");
|
||||||
|
@ -48,6 +109,7 @@ public class PluginSystem
|
||||||
|
|
||||||
Tag? pluginStore = pluginsData.Get(attrib.pluginName);
|
Tag? pluginStore = pluginsData.Get(attrib.pluginName);
|
||||||
nPlugin.pluginName = attrib.pluginName;
|
nPlugin.pluginName = attrib.pluginName;
|
||||||
|
nPlugin.providesShutdownMethod = attrib.providesShutdownMethod;
|
||||||
|
|
||||||
PSysLog($"> Loading plugin: {nPlugin.pluginName}");
|
PSysLog($"> Loading plugin: {nPlugin.pluginName}");
|
||||||
|
|
||||||
|
@ -55,6 +117,10 @@ public class PluginSystem
|
||||||
if (pluginStore == null)
|
if (pluginStore == null)
|
||||||
{
|
{
|
||||||
plugin.ResetMemory();
|
plugin.ResetMemory();
|
||||||
|
plugin.Enable();
|
||||||
|
nPlugin.enabled = true;
|
||||||
|
PSysLog($"> Loaded plugin: {nPlugin.pluginName}");
|
||||||
|
PSysLog($"> No existing settings found for plugin: {nPlugin.pluginName}");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -82,5 +148,11 @@ public class PluginSystem
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if any plugin provides a shutdown method
|
||||||
|
foreach (var plugin in Plugins)
|
||||||
|
{
|
||||||
|
if (plugin.providesShutdownMethod) SharedSessionData.GetInstance().HasShutdownMethod = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -18,4 +18,5 @@ public class SharedSessionData
|
||||||
public long TotalTicks { get; set; } = 0;
|
public long TotalTicks { get; set; } = 0;
|
||||||
public long TasksLastTick { get; set; } = 0;
|
public long TasksLastTick { get; set; } = 0;
|
||||||
public long TotalTasksPerTick { get; set; } = 0;
|
public long TotalTasksPerTick { get; set; } = 0;
|
||||||
|
public bool HasShutdownMethod { get; set; } = false;
|
||||||
}
|
}
|
Loading…
Add table
Add a link
Reference in a new issue