/// <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> /// Binds the specified base method to the PLUGIN table /// </summary> /// <param name="methodname"></param> /// <param name="luaname"></param> private void BindBaseMethod(string methodname, string luaname) { var method = GetType().GetMethod(methodname, BindingFlags.Static | BindingFlags.NonPublic); LuaEnvironment.RegisterFunction($"PLUGIN.{luaname}", method); }
/// <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> /// Binds the specified base method to the PLUGIN table /// </summary> /// <param name="methodname"></param> /// <param name="luaname"></param> private void BindBaseMethod(string methodname, string luaname) { MethodInfo method = GetType().GetMethod(methodname, BindingFlags.Static | BindingFlags.NonPublic); LuaEnvironment.RegisterFunction(string.Format("PLUGIN.{0}", luaname), method); }