diff --git a/Minecraft.Server.FourKit/FourKitHost.cs b/Minecraft.Server.FourKit/FourKitHost.cs index 51f1b128..15f49637 100644 --- a/Minecraft.Server.FourKit/FourKitHost.cs +++ b/Minecraft.Server.FourKit/FourKitHost.cs @@ -25,9 +25,15 @@ public static partial class FourKitHost // host exe's directory instead so end users see a top-level plugins/. string hostExePath = Environment.ProcessPath ?? AppContext.BaseDirectory; string serverRoot = Path.GetDirectoryName(hostExePath) ?? AppContext.BaseDirectory; + + // Redirect AppContext.BaseDirectory to the server root so that + // plugins using AppContext.BaseDirectory get the exe directory + // instead of the runtime/ subfolder. + AppContext.SetData("APP_CONTEXT_BASE_DIRECTORY", serverRoot + Path.DirectorySeparatorChar); + string pluginsDir = Path.Combine(serverRoot, "plugins"); s_loader = new PluginLoader(); - s_loader.LoadPlugins(pluginsDir); + s_loader.LoadPlugins(pluginsDir, serverRoot); s_loader.EnableAll(); ServerLog.Info("fourkit", "Plugin system ready."); diff --git a/Minecraft.Server.FourKit/Plugin/ServerPlugin.cs b/Minecraft.Server.FourKit/Plugin/ServerPlugin.cs index a4fd94f2..c3358039 100644 --- a/Minecraft.Server.FourKit/Plugin/ServerPlugin.cs +++ b/Minecraft.Server.FourKit/Plugin/ServerPlugin.cs @@ -28,6 +28,22 @@ public abstract class ServerPlugin /// public virtual string author { get; } = "Unknown"; + /// + /// The server's root directory (where the server executable lives). + /// Use this instead of AppContext.BaseDirectory which points + /// to the .NET runtime subfolder. Set automatically before + /// is called. + /// + public string serverDirectory { get; internal set; } = string.Empty; + + /// + /// A per-plugin data directory (plugins/<PluginName>/). + /// Created automatically if it does not exist. Use this for config + /// files, logs, databases, or any plugin-specific storage. + /// Set automatically before is called. + /// + public string dataDirectory { get; internal set; } = string.Empty; + /// /// Called when this plugin is enabled /// diff --git a/Minecraft.Server.FourKit/PluginLoader.cs b/Minecraft.Server.FourKit/PluginLoader.cs index baecfcd0..9dd89af9 100644 --- a/Minecraft.Server.FourKit/PluginLoader.cs +++ b/Minecraft.Server.FourKit/PluginLoader.cs @@ -10,11 +10,16 @@ internal sealed class PluginLoader BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly; private readonly List _plugins = new(); + private string _serverRoot = string.Empty; + private string _pluginsDirectory = string.Empty; public IReadOnlyList Plugins => _plugins.AsReadOnly(); - public void LoadPlugins(string pluginsDirectory) + public void LoadPlugins(string pluginsDirectory, string serverRoot) { + _serverRoot = serverRoot; + _pluginsDirectory = pluginsDirectory; + if (!Directory.Exists(pluginsDirectory)) { ServerLog.Info("fourkit", $"Creating plugins directory: {pluginsDirectory}"); @@ -136,8 +141,15 @@ internal sealed class PluginLoader { try { - InvokePluginMethod(plugin, "onEnable", "OnEnable"); string pName = GetPluginString(plugin, "name", "getName", "GetName", plugin.GetType().Name); + + plugin.serverDirectory = _serverRoot; + string dataDir = Path.Combine(_pluginsDirectory, pName); + if (!Directory.Exists(dataDir)) + Directory.CreateDirectory(dataDir); + plugin.dataDirectory = dataDir; + + InvokePluginMethod(plugin, "onEnable", "OnEnable"); ServerLog.Info("fourkit", $"Enabled: {pName}"); FourKit.FireEvent(new PluginEnableEvent(plugin));