예제 #1
0
 /// <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);
     }
 }
예제 #2
0
        /// <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);
        }
예제 #3
0
        /// <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);
        }
예제 #4
0
        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;
            }
        }
예제 #5
0
        /// <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);
            }
        }
예제 #6
0
        /// <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");
        }
예제 #7
0
        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;
            }
        }
예제 #8
0
        /// <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);
        }
예제 #9
0
        /// <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;
        }
예제 #10
0
        /// <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;
        }