Get basic ForgeCore server implemented

This commit is contained in:
zontreck 2024-12-17 17:20:46 -07:00
parent 65f5cb722b
commit 0c694c3e78
9 changed files with 168 additions and 11 deletions

1
.gitignore vendored
View file

@ -352,3 +352,4 @@ MigrationBackup/
.idea
.vscode
run

View file

@ -6,7 +6,7 @@ using System.Reflection;
[assembly: AssemblyCompany("Piccari Creations")]
[assembly: AssemblyAlgorithmId(System.Configuration.Assemblies.AssemblyHashAlgorithm.MD5)]
[assembly: AssemblyCopyright("(C) 2020 Tara Piccari")]
[assembly: AssemblyFileVersion("5.0.7.9200")]
[assembly: AssemblyFileVersion("6.0.1.0001")]
[assembly: AssemblyDescription("ForgeCore Bot Server")]
namespace ForgeCore.Assemble
@ -14,6 +14,6 @@ namespace ForgeCore.Assemble
public class ASMInfo
{
public static string BotName = "ForgeCore";
public static string BotVer = "2.0.121524.1636";
public static string BotVer = "2.0.121724.1716";
}
}

View file

@ -1,15 +1,19 @@
using System;
using System.IO;
using System.Linq;
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)
{
PluginSystem.InitializeSystem();
Arguments arguments = ArgumentParser.Parse(args);
if (arguments.HasArg("help") || arguments.Count == 0)
@ -18,12 +22,77 @@ public class ForgeCore
ArgumentBuilder builder = new ArgumentBuilder();
builder.withVersionArgument().withHelpArgument();
builder.withStringArgument("plugindir", "Plugins", true);
builder.withBooleanArgument("daemon", true);
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 (!Directory.Exists("Plugins"))
Directory.CreateDirectory("Plugins");
PluginSystem.InitializeSystem(PluginSystem.PluginDirectory);
SharedSessionData sessionData = SharedSessionData.GetInstance();
// Start the server tick loop
while (!sessionData.ShouldShutdown)
{
long tasksExecuted = 0;
if (sessionData.TotalTasksPerTick == 0 && sessionData.TotalTicks > 0)
{
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");
}
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;
}
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...");
return 0;
}
}

View file

@ -28,6 +28,11 @@ public interface IPlugin
/// </summary>
void tick();
/// <summary>
/// Called when the server is starting the shutdown process. This operation cannot be aborted, all plugin tasks should be immediately stopped. SaveConfig will follow this instruction.
/// </summary>
void TearDown();
/// <summary>
/// Provides the plugin with a copy of its saved configuration data
/// </summary>

View file

@ -0,0 +1,8 @@
namespace ForgeCoreAPI;
public class PluginContainer
{
public IPlugin plugin;
public bool enabled = true;
public string pluginName;
}

View file

@ -6,13 +6,22 @@ namespace ForgeCoreAPI;
public class PluginSystem
{
public static List<IPlugin> Plugins = new List<IPlugin>();
public static string PluginDirectory { get; set; } = "Plugins";
public static void InitializeSystem()
public static List<PluginContainer> Plugins = new List<PluginContainer>();
public static void InitializeSystem(string pluginDirectory)
{
CompoundTag pluginsData = NbtIo.Read("PluginStorage.dat");
CompoundTag pluginsData = new CompoundTag();
if (!File.Exists("PluginStorage.dat"))
{
// We have no existing saved config for plugins, or this is the first run
// Leave pluginsData empty
} else pluginsData = NbtIo.Read("PluginStorage.dat");
// Search the Plugins directory for DLL files
string[] files = Directory.GetFiles("Plugins", "*.dll");
string[] files = Directory.GetFiles(pluginDirectory, "*.dll");
// Begin loading assemblies
foreach (var file in files)
@ -24,12 +33,17 @@ public class PluginSystem
{
if (types.GetCustomAttribute<ForgeCorePluginAttribute>() != null)
{
PluginContainer nPlugin = new PluginContainer();
IPlugin plugin = Activator.CreateInstance(types) as IPlugin;
plugin.Initialize();
nPlugin.plugin = plugin;
ForgeCorePluginAttribute attrib = types.GetCustomAttribute<ForgeCorePluginAttribute>();
Tag? pluginStore = pluginsData.Get(attrib.pluginName);
nPlugin.pluginName = attrib.pluginName;
if (pluginStore == null)
{
plugin.ResetMemory();
@ -40,11 +54,19 @@ public class PluginSystem
CompoundTag dataTag = tag["data"] as CompoundTag;
plugin.LoadConfig(dataTag);
if(tag.Get("enabled").AsByte() == 1) plugin.Enable();
else plugin.Disable();
if (NbtUtils.ReadBoolean(tag, "enabled"))
{
nPlugin.enabled = true;
plugin.Enable();
}
else
{
plugin.Disable();
nPlugin.enabled = false;
}
}
Plugins.Add(plugin);
Plugins.Add(nPlugin);
}
}
}

View file

@ -0,0 +1,21 @@
namespace ForgeCoreAPI;
public class SharedSessionData
{
private static readonly object _lock = new object();
private static SharedSessionData? _instance;
public static SharedSessionData GetInstance()
{
lock (_lock)
{
if(_instance == null) _instance = new SharedSessionData();
return _instance;
}
}
public bool ShouldShutdown { get; set; } = false;
public long TotalTicks { get; set; } = 0;
public long TasksLastTick { get; set; } = 0;
public long TotalTasksPerTick { get; set; } = 0;
}

18
localtest Executable file
View file

@ -0,0 +1,18 @@
#!/bin/bash
rm -rf run || true
mkdir run
rm -rf bin
dotnet restore
dotnet publish ForgeCore.csproj --nologo -c Release --self-contained true /p:PublishSingleFile=true
cp bin/Release/net8.0/linux-x64/publish/ForgeCore run/
cd run
chmod +x ForgeCore
./ForgeCore --version
./ForgeCore --help
./ForgeCore --daemon

13
test Executable file
View file

@ -0,0 +1,13 @@
#!/bin/bash
rm -rf run || true
mkdir run
cd run
wget https://ci.zontreck.com/job/Projects/job/CSharp/job/ForgeCore/job/master/lastSuccessfulBuild/artifact/bin/Release/net8.0/linux-x64/publish/ForgeCore
chmod +x ForgeCore
./ForgeCore --version
./ForgeCore --help
./ForgeCore