/// <summary> /// Gets the namespace table for the specified namespace /// </summary> /// <param name="nspace"></param> /// <returns></returns> private LuaTable GetNamespaceTable(string nspace) { if (string.IsNullOrEmpty(nspace)) { return(GetNamespaceTable("global")); } else { var nspacesplit = nspace.Split('.'); var curtable = LuaEnvironment["_G"] as LuaTable; if (curtable == null) { Interface.Oxide.LogError("_G is null!"); return(null); } for (var i = 0; i < nspacesplit.Length; i++) { var prevtable = curtable; curtable = curtable?[nspacesplit[i]] as LuaTable; if (curtable != null) { continue; } LuaEnvironment.NewTable("tmp"); curtable = LuaEnvironment["tmp"] as LuaTable; LuaEnvironment["tmp"] = null; if (prevtable != null) { prevtable[nspacesplit[i]] = curtable; } } return(curtable); } }
/// <summary> /// Creates an overload selector with the specified set of methods /// </summary> /// <param name="methods"></param> /// <returns></returns> private LuaTable CreateOverloadSelector(MethodBase[] methods) { LuaEnvironment.NewTable("overloadselector"); var tbl = LuaEnvironment["overloadselector"] as LuaTable; LuaEnvironment["overloadselector"] = null; tbl["methodarray"] = methods; setmetatable.Call(tbl, overloadselectormeta); return(tbl); }
/// <summary> /// Populates the config with default settings /// </summary> protected override void LoadDefaultConfig() { LuaEnvironment.NewTable("tmp"); var tmp = LuaEnvironment["tmp"] as LuaTable; Table["Config"] = tmp; LuaEnvironment["tmp"] = null; CallHook("LoadDefaultConfig", null); Utility.SetConfigFromTable(Config, tmp); }
public LuaScript(LuaEnvironment env, string path, object gameObject) { _Env = env; var envTable = env.NewTable(path, gameObject); _Table = envTable; envTable.Get("Print", out _Start); if (_Start == null) { _Start = _Empty; } }
/// <summary> /// Loads a library into the specified path /// </summary> /// <param name="library"></param> /// <param name="path"></param> public void LoadLibrary(Library library, string path) { //Interface.Oxide.RootLogger.Write(LogType.Debug, "Loading library '{0}' into Lua... (path is '{1}')", library.GetType().Name, path); // Create the library table if it doesn't exist var libraryTable = LuaEnvironment[path] as LuaTable; if (libraryTable == null) { LuaEnvironment.NewTable(path); libraryTable = LuaEnvironment[path] as LuaTable; //Interface.Oxide.RootLogger.Write(LogType.Debug, "Library table not found, creating one... {0}", libraryTable); } else { //Interface.Oxide.RootLogger.Write(LogType.Debug, "Library table found, using it... {0}", libraryTable); } // Bind all methods foreach (var name in library.GetFunctionNames()) { var method = library.GetFunction(name); LuaEnvironment.RegisterFunction($"{path}.{name}", library, method); } // Only bind properties if it's not global if (path != "_G") { // Create properties table LuaEnvironment.NewTable("tmp"); var propertiesTable = LuaEnvironment["tmp"] as LuaTable; //Interface.Oxide.RootLogger.Write(LogType.Debug, "Made properties table {0}", propertiesTable); libraryTable["_properties"] = propertiesTable; libraryTable["_object"] = library; // NOTE: Is this a security risk? LuaEnvironment["tmp"] = null; // Bind all properties foreach (var name in library.GetPropertyNames()) { var property = library.GetProperty(name); propertiesTable[name] = property; } // Bind the metatable //Interface.Oxide.RootLogger.Write(LogType.Debug, "setmetatable {0}", libraryMetaTable); (LuaEnvironment["setmetatable"] as LuaFunction).Call(libraryTable, libraryMetaTable); } }
/// <summary> /// Called when all other extensions have been loaded /// </summary> public override void OnModLoad() { foreach (var extension in Manager.GetAllExtensions()) { if (!extension.IsGameExtension) { continue; } WhitelistAssemblies = extension.WhitelistAssemblies; WhitelistNamespaces = extension.WhitelistNamespaces; break; } // Bind Lua specific libraries LoadLibrary(new LuaGlobal(Manager.Logger), "_G"); LuaEnvironment.NewTable("datafile"); LoadLibrary(new LuaDatafile(LuaEnvironment), "datafile"); if (LuaEnvironment["util"] == null) { LuaEnvironment.NewTable("util"); } LoadLibrary(new LuaUtil(LuaEnvironment), "util"); // Bind any libraries to Lua foreach (var name in Manager.GetLibraries()) { var path = name.ToLowerInvariant(); var lib = Manager.GetLibrary(name); if (lib.IsGlobal) { path = "_G"; } else if (LuaEnvironment[path] == null) { LuaEnvironment.NewTable(path); } LoadLibrary(lib, path); } // Bind attributes to Lua LoadPluginFunctionAttribute("Command"); }
private void HandleCommandCallback(LuaFunction func, IPlayer caller, string cmd, string[] args) { LuaEnvironment.NewTable("tmp"); var argsTable = LuaEnvironment["tmp"] as LuaTable; LuaEnvironment["tmp"] = null; for (var i = 0; i < args.Length; i++) { argsTable[i + 1] = args[i]; } try { func.Call(Table, caller, cmd, argsTable); } catch (Exception) { // TODO: Error handling and stuff throw; } }
/// <summary> /// Creates a table that encapsulates the specified type /// </summary> /// <param name="type"></param> /// <returns></returns> private LuaTable CreateTypeTable(Type type) { // Make the table LuaEnvironment.NewTable("tmp"); var tmp = LuaEnvironment["tmp"] as LuaTable; // Set the type field tmp["_type"] = type; // Is it generic? if (type.IsGenericType) { // Setup metamethod setmetatable.Call(tmp, generictypetablemeta); } // Is it an enum? else if (type.IsEnum) { // Set all enum fields var fields = type.GetFields().Where(x => x.IsLiteral); foreach (var value in fields) { tmp[value.Name] = value.GetValue(null); } } else { // Bind all public static methods var methods = type.GetMethods(BindingFlags.Static | BindingFlags.Public); var processed = new HashSet <string>(); foreach (var method in methods) { if (!processed.Contains(method.Name)) { // We need to check if this method is overloaded var overloads = methods.Where(m => m.Name == method.Name).ToArray(); if (overloads.Length == 1) { // It's not, simply bind it LuaEnvironment.RegisterFunction($"tmp.{method.Name}", method); } else { // It is, "overloads" holds all our method overloads tmp[method.Name] = CreateOverloadSelector(overloads); } // Processed processed.Add(method.Name); } } // Make the public static field table LuaEnvironment.NewTable("sftbl"); var sftbl = LuaEnvironment["sftbl"] as LuaTable; LuaEnvironment["sftbl"] = null; tmp["_sftbl"] = sftbl; var fields = type.GetFields(BindingFlags.Static | BindingFlags.Public); foreach (var field in fields) { sftbl[field.Name] = field; } // Bind all nested types foreach (var nested in type.GetNestedTypes()) { tmp[nested.Name] = CreateTypeTable(nested); } // Setup metamethod setmetatable.Call(tmp, typetablemeta); } // Return it LuaEnvironment["tmp"] = null; return(tmp); }
/// <summary> /// Loads this plugin /// </summary> public override void Load() { // Load the plugin into a table var source = File.ReadAllText(Filename); if (Regex.IsMatch(source, @"PLUGIN\.Version\s*=\s*[\'|""]", RegexOptions.IgnoreCase)) { throw new Exception("Plugin version is a string, Oxide 1.18 plugins are not compatible with Oxide 2"); } var pluginfunc = LuaEnvironment.LoadString(source, Path.GetFileName(Filename)); if (pluginfunc == null) { throw new Exception("LoadString returned null for some reason"); } LuaEnvironment.NewTable("PLUGIN"); Table = (LuaTable)LuaEnvironment["PLUGIN"]; ((LuaFunction)LuaEnvironment["setmetatable"]).Call(Table, luaExt.PluginMetatable); Table["Name"] = Name; pluginfunc.Call(); // Read plugin attributes if (!(Table["Title"] is string)) { throw new Exception("Plugin is missing title"); } if (!(Table["Author"] is string)) { throw new Exception("Plugin is missing author"); } if (!(Table["Version"] is VersionNumber)) { throw new Exception("Plugin is missing version"); } Title = (string)Table["Title"]; Author = (string)Table["Author"]; Version = (VersionNumber)Table["Version"]; if (Table["Description"] is string) { Description = (string)Table["Description"]; } if (Table["ResourceId"] is double) { ResourceId = (int)(double)Table["ResourceId"]; } if (Table["HasConfig"] is bool) { HasConfig = (bool)Table["HasConfig"]; } // Set attributes Table["Object"] = this; Table["Plugin"] = this; // Get all functions and hook them functions = new Dictionary <string, LuaFunction>(); foreach (var keyobj in Table.Keys) { var key = keyobj as string; if (key == null) { continue; } var value = Table[key]; var func = value as LuaFunction; if (func != null) { functions.Add(key, func); } } if (!HasConfig) { HasConfig = functions.ContainsKey("LoadDefaultConfig"); } // Bind any base methods (we do it here because we don't want them to be hooked) BindBaseMethods(); // Deal with any attributes var attribs = Table["_attribArr"] as LuaTable; if (attribs != null) { var i = 0; while (attribs[++i] != null) { var attrib = attribs[i] as LuaTable; var attribName = attrib["_attribName"] as string; var attribFunc = attrib["_func"] as LuaFunction; if (attribFunc != null && !string.IsNullOrEmpty(attribName)) { HandleAttribute(attribName, attribFunc, attrib); } } } // Clean up LuaEnvironment["PLUGIN"] = null; }
/// <summary> /// Loads this plugin /// </summary> public void Load() { // Load the plugin into a table string source = File.ReadAllText(Filename); LuaFunction pluginfunc = LuaEnvironment.LoadString(source, Path.GetFileName(Filename)); if (pluginfunc == null) { throw new Exception("LoadString returned null for some reason"); } LuaEnvironment.NewTable("PLUGIN"); Table = LuaEnvironment["PLUGIN"] as LuaTable; Name = Path.GetFileNameWithoutExtension(Filename); Table["Name"] = Name; pluginfunc.Call(); // Read plugin attributes if (Table["Title"] == null || !(Table["Title"] is string)) { throw new Exception("Plugin is missing title"); } if (Table["Author"] == null || !(Table["Author"] is string)) { throw new Exception("Plugin is missing author"); } if (Table["Version"] == null || !(Table["Version"] is VersionNumber)) { throw new Exception("Plugin is missing version"); } Title = (string)Table["Title"]; Author = (string)Table["Author"]; Version = (VersionNumber)Table["Version"]; if (Table["ResourceId"] is int) { ResourceId = (int)Table["ResourceId"]; } if (Table["HasConfig"] is bool) { HasConfig = (bool)Table["HasConfig"]; } // Set attributes Table["Object"] = this; Table["Plugin"] = this; // Get all functions and hook them functions = new Dictionary <string, LuaFunction>(); foreach (var keyobj in Table.Keys) { string key = keyobj as string; if (key != null) { object value = Table[key]; LuaFunction func = value as LuaFunction; if (func != null) { functions.Add(key, func); } } } // Bind any base methods (we do it here because we don't want them to be hooked) BindBaseMethods(); // Clean up LuaEnvironment["PLUGIN"] = null; }