using System.Text; using AIStudio.Settings; using Lua; namespace AIStudio.Tools.PluginSystem; /// /// Loads Lua modules from a plugin directory. /// /// /// Any plugin can load Lua modules from its own directory. This class is used to load these modules. /// Loading other modules outside the plugin directory is not allowed. /// /// The directory where the plugin is located. public sealed class PluginLoader(string pluginDirectory) : ILuaModuleLoader { private static readonly string PLUGIN_BASE_PATH = Path.Join(SettingsManager.DataDirectory, "plugins"); #region Implementation of ILuaModuleLoader /// public bool Exists(string moduleName) { // Ensure that the user doesn't try to escape the plugin directory: if (moduleName.Contains("..") || pluginDirectory.Contains("..")) return false; // Ensure that the plugin directory is nested in the plugin base path: if (!pluginDirectory.StartsWith(PLUGIN_BASE_PATH, StringComparison.OrdinalIgnoreCase)) return false; var path = Path.Join(pluginDirectory, $"{moduleName}.lua"); return File.Exists(path); } /// public async ValueTask LoadAsync(string moduleName, CancellationToken cancellationToken = default) { var path = Path.Join(pluginDirectory, $"{moduleName}.lua"); var code = await File.ReadAllTextAsync(path, Encoding.UTF8, cancellationToken); return new(moduleName, code); } #endregion }