コード例 #1
0
        protected override object InvokeMethod(MethodInfo method, object[] args)
        {
            //TODO ignore base_ methods for now
            if (!hookDispatchFallback && !method.Name.StartsWith("base_"))
            {
                try
                {
                    object ret;
                    if (DirectCallHook(method.Name, out ret, args))
                    {
                        return(ret);
                    }
                    PrintWarning("Unable to call hook directly: " + method.Name);
                }
                catch (InvalidProgramException ex)
                {
                    Interface.Oxide.LogError("Hook dispatch failure detected, falling back to reflection based dispatch. " + ex.ToString());
                    var compilable_plugin = CSharpPluginLoader.GetCompilablePlugin(Interface.Oxide.PluginDirectory, Name);
                    if (compilable_plugin != null && compilable_plugin.CompiledAssembly != null)
                    {
                        System.IO.File.WriteAllBytes(Interface.Oxide.PluginDirectory + "\\" + Name + ".dump", compilable_plugin.CompiledAssembly.PatchedAssembly);
                        Interface.Oxide.LogWarning($"The invalid raw assembly has been dumped to Plugins/{Name}.dump");
                    }
                    hookDispatchFallback = true;
                }
            }

            return(method.Invoke(this, args));
        }
コード例 #2
0
 public override void Reload(string directory, string name)
 {
     if (!Regex.Match(directory, "\\\\include\\b", RegexOptions.IgnoreCase).Success)
     {
         CompilablePlugin compilablePlugin = CSharpPluginLoader.GetCompilablePlugin(directory, name);
         if (!compilablePlugin.IsLoading)
         {
             this.Load(compilablePlugin);
             return;
         }
         Interface.Oxide.LogDebug(string.Concat("Reload requested for plugin which is already loading: ", compilablePlugin.Name), Array.Empty <object>());
         return;
     }
     name = string.Concat("Oxide.", name);
     foreach (CompilablePlugin value in CSharpPluginLoader.plugins.Values)
     {
         if (!value.References.Contains(name))
         {
             continue;
         }
         Interface.Oxide.LogInfo(string.Concat("Reloading ", value.Name, " because it references updated include file: ", name), Array.Empty <object>());
         value.LastModifiedAt = DateTime.Now;
         this.Load(value);
     }
 }
コード例 #3
0
ファイル: CSharpPluginLoader.cs プロジェクト: romgerman/Oxide
 public CSharpPluginLoader(CSharpExtension extension)
 {
     Instance = this;
     CSharpPluginLoader.extension = extension;
     PluginCompiler.CheckCompilerBinary();
     compiler = new PluginCompiler();
 }
コード例 #4
0
 public CSharpPluginLoader(CSharpExtension extension)
 {
     Instance = this;
     CSharpPluginLoader.extension = extension;
     PluginCompiler.CheckCompilerBinary();
     compiler = new PluginCompiler();
 }
コード例 #5
0
ファイル: CSharpExtension.cs プロジェクト: RuanPitout88/Oxide
 /// <summary>
 /// Loads this extension
 /// </summary>
 public override void Load()
 {
     // Register our loader
     loader = new CSharpPluginLoader(this);
     Manager.RegisterPluginLoader(loader);
     // Register engine frame callback
     Interface.Oxide.OnFrame(OnFrame);
 }
コード例 #6
0
 /// <summary>
 /// Loads this extension
 /// </summary>
 public override void Load()
 {
     // Register our loader
     loader = new CSharpPluginLoader(this);
     Manager.RegisterPluginLoader(loader);
     // Register engine frame callback
     Interface.Oxide.OnFrame(OnFrame);
 }
コード例 #7
0
ファイル: CompilableFile.cs プロジェクト: yas-online/Oxide
 public CompilableFile(CSharpExtension extension, CSharpPluginLoader loader, string directory, string name)
 {
     Extension = extension;
     Loader = loader;
     Directory = directory;
     ScriptName = name;
     ScriptPath = Path.Combine(Directory, $"{ScriptName}.cs");
     Name = Regex.Replace(Regex.Replace(ScriptName, @"(?:^|_)([a-z])", m => m.Groups[1].Value.ToUpper()), "_", "");
     CheckLastModificationTime();
 }
コード例 #8
0
 public CompilableFile(CSharpExtension extension, CSharpPluginLoader loader, string directory, string name)
 {
     Extension  = extension;
     Loader     = loader;
     Directory  = directory;
     ScriptName = name;
     ScriptPath = Path.Combine(Directory, $"{ScriptName}.cs");
     Name       = Regex.Replace(ScriptName, "_", "");
     CheckLastModificationTime();
 }
コード例 #9
0
ファイル: CompilableFile.cs プロジェクト: RuanPitout88/Oxide
 public CompilableFile(CSharpExtension extension, CSharpPluginLoader loader, string directory, string name)
 {
     Extension  = extension;
     Loader     = loader;
     Directory  = directory;
     ScriptName = name;
     Name       = Regex.Replace(Regex.Replace(ScriptName, @"(?:^|_)([a-z])", m => m.Groups[1].Value.ToUpper()), "_", "");
     ScriptPath = Path.Combine(Directory, string.Format("{0}.cs", ScriptName));
     CheckLastModificationTime();
 }
コード例 #10
0
ファイル: CompilablePlugin.cs プロジェクト: strykes/Oxide
 public CompilablePlugin(CSharpExtension extension, CSharpPluginLoader loader, string directory, string name)
 {
     Extension = extension;
     Loader = loader;
     Directory = directory;
     ScriptName = name;
     Name = Regex.Replace(Regex.Replace(ScriptName, @"(?:^|_)([a-z])", m => m.Groups[1].Value.ToUpper()), "_", "");
     ScriptPath = string.Format("{0}\\{1}.cs", Directory, ScriptName);
     CheckLastModificationTime();
 }
コード例 #11
0
 public CompilableFile(CSharpExtension extension, CSharpPluginLoader loader, string directory, string name)
 {
     this.Extension  = extension;
     this.Loader     = loader;
     this.Directory  = directory;
     this.ScriptName = name;
     this.ScriptPath = Path.Combine(this.Directory, string.Concat(this.ScriptName, ".cs"));
     this.Name       = Regex.Replace(this.ScriptName, "_", "");
     this.CheckLastModificationTime();
 }
コード例 #12
0
        protected override object InvokeMethod(HookMethod method, object[] args)
        {
            // TODO: Ignore base_ methods for now
            if (!hookDispatchFallback && !method.IsBaseHook)
            {
                if (args != null && args.Length > 0)
                {
                    ParameterInfo[] parameters = method.Parameters;
                    for (int i = 0; i < args.Length; i++)
                    {
                        object value = args[i];
                        if (value == null)
                        {
                            continue;
                        }

                        Type parameter_type = parameters[i].ParameterType;
                        if (!parameter_type.IsValueType)
                        {
                            continue;
                        }

                        Type argument_type = value.GetType();
                        if (parameter_type != typeof(object) && argument_type != parameter_type)
                        {
                            args[i] = Convert.ChangeType(value, parameter_type);
                        }
                    }
                }
                try
                {
                    if (DirectCallHook(method.Name, out object ret, args))
                    {
                        return(ret);
                    }

                    PrintWarning("Unable to call hook directly: " + method.Name);
                }
                catch (InvalidProgramException ex)
                {
                    Interface.Oxide.LogError("Hook dispatch failure detected, falling back to reflection based dispatch. " + ex);
                    CompilablePlugin compilablePlugin = CSharpPluginLoader.GetCompilablePlugin(Interface.Oxide.PluginDirectory, Name);
                    if (compilablePlugin?.CompiledAssembly != null)
                    {
                        File.WriteAllBytes(Interface.Oxide.PluginDirectory + "\\" + Name + ".dump", compilablePlugin.CompiledAssembly.PatchedAssembly);
                        Interface.Oxide.LogWarning($"The invalid raw assembly has been dumped to Plugins/{Name}.dump");
                    }
                    hookDispatchFallback = true;
                }
            }

            return(method.Method.Invoke(this, args));
        }
コード例 #13
0
        public override Plugin Load(string directory, string name)
        {
            CompilablePlugin compilablePlugin = CSharpPluginLoader.GetCompilablePlugin(directory, name);

            if (!compilablePlugin.IsLoading)
            {
                this.Load(compilablePlugin);
                return(null);
            }
            Interface.Oxide.LogDebug(string.Concat("Load requested for plugin which is already loading: ", compilablePlugin.Name), Array.Empty <object>());
            return(null);
        }
コード例 #14
0
        /// <summary>
        /// Loads this extension
        /// </summary>
        public override void Load()
        {
            // Register our loader
            loader = new CSharpPluginLoader(this);
            Manager.RegisterPluginLoader(loader);

            // Register engine frame callback
            Interface.Oxide.OnFrame(OnFrame);

            Cleanup.Add(Path.Combine(Interface.Oxide.RootDirectory, "mono-2.0.dll"));
            Cleanup.Add(Path.Combine(Interface.Oxide.RootDirectory, "msvcr120.dll"));
        }
コード例 #15
0
ファイル: CSharpExtension.cs プロジェクト: AEtherSurfer/Oxide
        /// <summary>
        /// Loads this extension
        /// </summary>
        public override void Load()
        {
            // Register our loader
            loader = new CSharpPluginLoader(this);
            Manager.RegisterPluginLoader(loader);

            // Register engine frame callback
            Interface.Oxide.OnFrame(OnFrame);

            Cleanup.Add(Path.Combine(Interface.Oxide.RootDirectory, "mono-2.0.dll"));
            Cleanup.Add(Path.Combine(Interface.Oxide.RootDirectory, "msvcr120.dll"));
        }
コード例 #16
0
        /// <summary>
        /// Loads this extension
        /// </summary>
        public override void Load()
        {
            // Register our loader
            loader = new CSharpPluginLoader(this);
            Manager.RegisterPluginLoader(loader);

            // Register engine frame callback
            Interface.Oxide.OnFrame(OnFrame);

            // Cleanup old files and/or file locations
            Cleanup.Add(Path.Combine(Interface.Oxide.RootDirectory, Environment.OSVersion.Platform == PlatformID.Unix ? "CSharpCompiler.exe" : "CSharpCompiler.x86"));
            Cleanup.Add(Path.Combine(Interface.Oxide.RootDirectory, "CSharpCompiler"));
        }
コード例 #17
0
        /// <summary>
        /// Loads this extension
        /// </summary>
        public override void Load()
        {
            // Register our loader
            loader = new CSharpPluginLoader(this);
            Manager.RegisterPluginLoader(loader);

            // Register engine frame callback
            Interface.Oxide.OnFrame(OnFrame);

            if (File.Exists(Path.Combine(Interface.Oxide.ExtensionDirectory, "oxide.disable-sandbox")))
            {
                Interface.Oxide.LogWarning($"{Path.Combine(Interface.Oxide.ExtensionDirectory, "oxide.disable-sandbox")} found, disabling security sandbox. Potentially dangerous APIs and methods are now allowed inside plugins.");
                CSharpExtension.SandboxEnabled = false;
            }
        }
コード例 #18
0
 private void PluginLoadingCompleted(CompilablePlugin plugin)
 {
     base.LoadingPlugins.Remove(plugin.Name);
     plugin.IsLoading = false;
     string[] array = base.LoadingPlugins.ToArray();
     for (int i = 0; i < (int)array.Length; i++)
     {
         string           str = array[i];
         CompilablePlugin compilablePlugin = CSharpPluginLoader.GetCompilablePlugin(plugin.Directory, str);
         if (compilablePlugin.IsLoading && compilablePlugin.Requires.Contains(plugin.Name))
         {
             this.Load(compilablePlugin);
         }
     }
 }
コード例 #19
0
        public override IEnumerable <string> ScanDirectory(string directory)
        {
            CSharpPluginLoader cSharpPluginLoader = null;

            if (PluginCompiler.BinaryPath != null)
            {
                foreach (string str in cSharpPluginLoader.< > n__0(directory))
                {
                    yield return(str);
                }
            }
            else
            {
            }
        }
コード例 #20
0
 internal override void OnCompilationStarted()
 {
     base.OnCompilationStarted();
     foreach (Plugin plugin in Interface.Oxide.RootPluginManager.GetPlugins())
     {
         if (!(plugin is CSharpPlugin))
         {
             continue;
         }
         CompilablePlugin compilablePlugin = CSharpPluginLoader.GetCompilablePlugin(this.Directory, plugin.Name);
         if (!compilablePlugin.Requires.Contains(this.Name))
         {
             continue;
         }
         compilablePlugin.CompiledAssembly = null;
         this.Loader.Load(compilablePlugin);
     }
 }
コード例 #21
0
 internal void Add(CompilablePlugin plugin)
 {
     if (!queuedPlugins.Add(plugin))
     {
         return;
     }
     plugin.Loader.PluginLoadingStarted(plugin);
     plugin.CompilerErrors = null;
     plugin.OnCompilationStarted();
     foreach (var pl in Interface.Oxide.RootPluginManager.GetPlugins().Where(pl => pl is CSharpPlugin))
     {
         var loadedPlugin = CSharpPluginLoader.GetCompilablePlugin(plugin.Directory, pl.Name);
         if (!loadedPlugin.Requires.Contains(plugin.Name))
         {
             continue;
         }
         AddDependency(loadedPlugin);
     }
 }
コード例 #22
0
ファイル: CompilablePlugin.cs プロジェクト: ppker/Oxide
        internal override void OnCompilationStarted()
        {
            base.OnCompilationStarted();

            // Enqueue compilation of any plugins which depend on this plugin
            foreach (var plugin in Interface.Oxide.RootPluginManager.GetPlugins())
            {
                if (!(plugin is CSharpPlugin))
                {
                    continue;
                }
                var compilablePlugin = CSharpPluginLoader.GetCompilablePlugin(Directory, plugin.Name);
                if (!compilablePlugin.Requires.Contains(Name))
                {
                    continue;
                }
                compilablePlugin.CompiledAssembly = null;
                Loader.Load(compilablePlugin);
            }
        }
コード例 #23
0
 internal void Add(CompilablePlugin plugin)
 {
     if (!this.queuedPlugins.Add(plugin))
     {
         return;
     }
     plugin.Loader.PluginLoadingStarted(plugin);
     plugin.CompilerErrors = null;
     plugin.OnCompilationStarted();
     foreach (Plugin plugin1 in
              from pl in Interface.Oxide.RootPluginManager.GetPlugins()
              where pl is CSharpPlugin
              select pl)
     {
         CompilablePlugin compilablePlugin = CSharpPluginLoader.GetCompilablePlugin(plugin.Directory, plugin1.Name);
         if (!compilablePlugin.Requires.Contains(plugin.Name))
         {
             continue;
         }
         this.AddDependency(compilablePlugin);
     }
 }
コード例 #24
0
ファイル: CompilablePlugin.cs プロジェクト: ppker/Oxide
 public CompilablePlugin(CSharpExtension extension, CSharpPluginLoader loader, string directory, string name) : base(extension, loader, directory, name)
 {
 }
コード例 #25
0
 public override void Load()
 {
     this.loader = new CSharpPluginLoader(this);
     base.Manager.RegisterPluginLoader(this.loader);
     Interface.Oxide.OnFrame(new Action <float>(this.OnFrame));
 }
コード例 #26
0
ファイル: Compilation.cs プロジェクト: diametric/Oxide.CSharp
        private void PreparseScript(CompilablePlugin plugin)
        {
            plugin.References.Clear();
            plugin.IncludePaths.Clear();
            plugin.Requires.Clear();

            bool parsingNamespace = false;

            for (int i = 0; i < plugin.ScriptLines.Length; i++)
            {
                string line = plugin.ScriptLines[i].Trim();
                if (line.Length < 1)
                {
                    continue;
                }

                Match match;
                if (parsingNamespace)
                {
                    // Skip blank lines and opening brace at the top of the namespace block
                    match = Regex.Match(line, @"^\s*\{?\s*$", RegexOptions.IgnoreCase);
                    if (match.Success)
                    {
                        continue;
                    }

                    // Skip class custom attributes
                    match = Regex.Match(line, @"^\s*\[", RegexOptions.IgnoreCase);
                    if (match.Success)
                    {
                        continue;
                    }

                    // Detect main plugin class name
                    match = Regex.Match(line, @"^\s*(?:public|private|protected|internal)?\s*class\s+(\S+)\s+\:\s+\S+Plugin\s*$", RegexOptions.IgnoreCase);
                    if (!match.Success)
                    {
                        break;
                    }

                    string className = match.Groups[1].Value;
                    if (className != plugin.Name)
                    {
                        Interface.Oxide.LogError($"Plugin filename {plugin.ScriptName}.cs must match the main class {className} (should be {className}.cs)");
                        plugin.CompilerErrors = $"Plugin filename {plugin.ScriptName}.cs must match the main class {className} (should be {className}.cs)";
                        RemovePlugin(plugin);
                    }

                    break;
                }

                // Include explicit plugin dependencies defined by magic comments in script
                match = Regex.Match(line, @"^//\s*Requires:\s*(\S+?)(\.cs)?\s*$", RegexOptions.IgnoreCase);
                if (match.Success)
                {
                    string dependencyName = match.Groups[1].Value;
                    plugin.Requires.Add(dependencyName);
                    if (!File.Exists(Path.Combine(plugin.Directory, dependencyName + ".cs")))
                    {
                        Interface.Oxide.LogError($"{plugin.Name} plugin requires missing dependency: {dependencyName}");
                        plugin.CompilerErrors = $"Missing dependency: {dependencyName}";
                        RemovePlugin(plugin);
                        return;
                    }

                    //Interface.Oxide.LogDebug(plugin.Name + " plugin requires dependency: " + dependency_name);
                    CompilablePlugin dependencyPlugin = CSharpPluginLoader.GetCompilablePlugin(plugin.Directory, dependencyName);
                    AddDependency(dependencyPlugin);
                    continue;
                }

                // Include explicit references defined by magic comments in script
                match = Regex.Match(line, @"^//\s*Reference:\s*(\S+)\s*$", RegexOptions.IgnoreCase);
                if (match.Success)
                {
                    string result = match.Groups[1].Value;
                    if (!result.StartsWith("Oxide.") && !result.Contains("Harmony") && !result.Contains("Newtonsoft.Json") &&
                        !result.Contains("protobuf-net") && !result.StartsWith("Rust."))
                    {
                        AddReference(plugin, result);
                        Interface.Oxide.LogInfo("Added '// Reference: {0}' in plugin '{1}'", result, plugin.Name);
                    }
                    else
                    {
                        Interface.Oxide.LogWarning("Ignored unnecessary '// Reference: {0}' in plugin '{1}'", result, plugin.Name);
                    }

                    continue;
                }

                // Include implicit references detected from using statements in script
                match = Regex.Match(line, @"^\s*using\s+(Oxide\.(?:Core|Ext|Game)\.(?:[^\.]+))[^;]*;.*$", RegexOptions.IgnoreCase);
                if (match.Success)
                {
                    string result    = match.Groups[1].Value;
                    string newResult = Regex.Replace(result, @"Oxide\.[\w]+\.([\w]+)", "Oxide.$1");
                    if (!string.IsNullOrEmpty(newResult) && File.Exists(Path.Combine(Interface.Oxide.ExtensionDirectory, newResult + ".dll")))
                    {
                        AddReference(plugin, newResult);
                    }
                    else
                    {
                        AddReference(plugin, result);
                    }

                    continue;
                }

                // Start parsing the Oxide.Plugins namespace contents
                match = Regex.Match(line, @"^\s*namespace Oxide\.Plugins\s*(\{\s*)?$", RegexOptions.IgnoreCase);
                if (match.Success)
                {
                    parsingNamespace = true;
                }
            }
        }
コード例 #27
0
ファイル: CompilablePlugin.cs プロジェクト: yas-online/Oxide
 public CompilablePlugin(CSharpExtension extension, CSharpPluginLoader loader, string directory, string name) : base(extension, loader, directory, name)
 {
 }
コード例 #28
0
        private void PreparseScript(CompilablePlugin plugin)
        {
            plugin.References.Clear();
            plugin.IncludePaths.Clear();
            plugin.Requires.Clear();
            if (plugin.ScriptLines.Any <string>((string line) => {
                if (line.Contains("uMod"))
                {
                    return(true);
                }
                return(line.Contains("Universal"));
            }))
            {
                plugin.ScriptLines = (
                    from s in plugin.ScriptLines
                    select s.Replace("uMod", "Oxide.Core").Replace("using Oxide.Core;", "using Oxide.Core; using Oxide.Core.Plugins;").Replace("namespace Oxide.Core.Plugins", "namespace Oxide.Plugins").Replace("Libraries.Universal", "Libraries.Covalence").Replace("UniversalPlugin", "CovalencePlugin").Replace("Oxide.Core.Version", "OxideMod.Version")).ToArray <string>();
            }
            bool flag = false;

            for (int i = 0; i < (int)plugin.ScriptLines.Length; i++)
            {
                string str = plugin.ScriptLines[i].Trim();
                if (str.Length >= 1)
                {
                    if (!flag)
                    {
                        Match match = Regex.Match(str, "^//\\s*Requires:\\s*(\\S+?)(\\.cs)?\\s*$", RegexOptions.IgnoreCase);
                        if (!match.Success)
                        {
                            match = Regex.Match(str, "^//\\s*Reference:\\s*(\\S+)\\s*$", RegexOptions.IgnoreCase);
                            if (!match.Success)
                            {
                                match = Regex.Match(str, "^\\s*using\\s+(Oxide\\.(?:Core|Ext|Game)\\.(?:[^\\.]+))[^;]*;.*$", RegexOptions.IgnoreCase);
                                if (!match.Success)
                                {
                                    match = Regex.Match(str, "^\\s*namespace Oxide\\.Plugins\\s*(\\{\\s*)?$", RegexOptions.IgnoreCase);
                                    if (match.Success)
                                    {
                                        flag = true;
                                    }
                                }
                                else
                                {
                                    string value = match.Groups[1].Value;
                                    string str1  = Regex.Replace(value, "Oxide\\.[\\w]+\\.([\\w]+)", "Oxide.$1");
                                    if (string.IsNullOrEmpty(str1) || !File.Exists(Path.Combine(Interface.get_Oxide().get_ExtensionDirectory(), string.Concat(str1, ".dll"))))
                                    {
                                        this.AddReference(plugin, value);
                                    }
                                    else
                                    {
                                        this.AddReference(plugin, str1);
                                    }
                                }
                            }
                            else
                            {
                                string value1 = match.Groups[1].Value;
                                if (value1.StartsWith("Oxide.") || value1.StartsWith("Newtonsoft.Json") || value1.StartsWith("protobuf-net") || value1.StartsWith("Rust."))
                                {
                                    Interface.get_Oxide().LogWarning("Ignored unnecessary '// Reference: {0}' in plugin '{1}'", new object[] { value1, plugin.Name });
                                }
                                else
                                {
                                    this.AddReference(plugin, value1);
                                    Interface.get_Oxide().LogInfo("Added '// Reference: {0}' in plugin '{1}'", new object[] { value1, plugin.Name });
                                }
                            }
                        }
                        else
                        {
                            string value2 = match.Groups[1].Value;
                            plugin.Requires.Add(value2);
                            if (!File.Exists(Path.Combine(plugin.Directory, string.Concat(value2, ".cs"))))
                            {
                                Interface.get_Oxide().LogError(string.Concat(plugin.Name, " plugin requires missing dependency: ", value2), Array.Empty <object>());
                                plugin.CompilerErrors = string.Concat("Missing dependency: ", value2);
                                this.RemovePlugin(plugin);
                                return;
                            }
                            this.AddDependency(CSharpPluginLoader.GetCompilablePlugin(plugin.Directory, value2));
                        }
                    }
                    else
                    {
                        Match match1 = Regex.Match(str, "^\\s*\\{?\\s*$", RegexOptions.IgnoreCase);
                        if (!match1.Success)
                        {
                            match1 = Regex.Match(str, "^\\s*\\[", RegexOptions.IgnoreCase);
                            if (!match1.Success)
                            {
                                match1 = Regex.Match(str, "^\\s*(?:public|private|protected|internal)?\\s*class\\s+(\\S+)\\s+\\:\\s+\\S+Plugin\\s*$", RegexOptions.IgnoreCase);
                                if (!match1.Success)
                                {
                                    break;
                                }
                                string str2 = match1.Groups[1].Value;
                                if (str2 == plugin.Name)
                                {
                                    break;
                                }
                                Interface.get_Oxide().LogError(string.Concat(new string[] { "Plugin filename ", plugin.ScriptName, ".cs must match the main class ", str2, " (should be ", str2, ".cs)" }), Array.Empty <object>());
                                plugin.CompilerErrors = string.Concat(new string[] { "Plugin filename ", plugin.ScriptName, ".cs must match the main class ", str2, " (should be ", str2, ".cs)" });
                                this.RemovePlugin(plugin);
                                return;
                            }
                        }
                    }
                }
            }
        }
コード例 #29
0
        private void PreparseScript(CompilablePlugin plugin)
        {
            plugin.References.Clear();
            plugin.IncludePaths.Clear();
            plugin.Requires.Clear();

            var parsingNamespace = false;

            for (var i = 0; i < plugin.ScriptLines.Length; i++)
            {
                var line = plugin.ScriptLines[i].Trim();
                if (line.Length < 1)
                {
                    continue;
                }

                Match match;
                if (parsingNamespace)
                {
                    // Skip blank lines and opening brace at the top of the namespace block
                    match = Regex.Match(line, @"^\s*\{?\s*$", RegexOptions.IgnoreCase);
                    if (match.Success)
                    {
                        continue;
                    }

                    // Skip class custom attributes
                    match = Regex.Match(line, @"^\s*\[", RegexOptions.IgnoreCase);
                    if (match.Success)
                    {
                        continue;
                    }

                    // Detect main plugin class name
                    match = Regex.Match(line, @"^\s*(?:public|private|protected|internal)?\s*class\s+(\S+)\s+\:\s+\S+Plugin\s*$", RegexOptions.IgnoreCase);
                    if (!match.Success)
                    {
                        break;
                    }

                    var className = match.Groups[1].Value;
                    if (className != plugin.Name)
                    {
                        Interface.Oxide.LogError($"Plugin filename is incorrect: {plugin.ScriptName}.cs (should be {className}.cs)");
                        plugin.CompilerErrors = $"Filename is incorrect: {plugin.ScriptName}.cs (should be {className}.cs)";
                        RemovePlugin(plugin);
                    }

                    break;
                }

                // Include explicit plugin dependencies defined by magic comments in script
                match = Regex.Match(line, @"^//\s*Requires:\s*(\S+?)(\.cs)?\s*$", RegexOptions.IgnoreCase);
                if (match.Success)
                {
                    var dependencyName = match.Groups[1].Value;
                    plugin.Requires.Add(dependencyName);
                    if (!File.Exists(Path.Combine(plugin.Directory, dependencyName + ".cs")))
                    {
                        Interface.Oxide.LogError($"{plugin.Name} plugin requires missing dependency: {dependencyName}");
                        plugin.CompilerErrors = $"Missing dependency: {dependencyName}";
                        RemovePlugin(plugin);
                        return;
                    }
                    //Interface.Oxide.LogDebug(plugin.Name + " plugin requires dependency: " + dependency_name);
                    var dependencyPlugin = CSharpPluginLoader.GetCompilablePlugin(plugin.Directory, dependencyName);
                    AddDependency(dependencyPlugin);
                    continue;
                }

                // Include explicit references defined by magic comments in script
                match = Regex.Match(line, @"^//\s*Reference:\s*(\S+)\s*$", RegexOptions.IgnoreCase);
                if (match.Success)
                {
                    var result = match.Groups[1].Value;
                    if (!newGameExtensionNamespace || !result.StartsWith(gameExtensionNamespace.Replace(".Game.", ".Ext.")))
                    {
                        AddReference(plugin, match.Groups[1].Value);
                    }
                    else
                    {
                        Interface.Oxide.LogWarning("Ignored obsolete game extension reference '{0}' in plugin '{1}'", result, plugin.Name);
                    }
                    continue;
                }

                // Include implicit references detected from using statements in script
                match = Regex.Match(line, @"^\s*using\s+(Oxide\.(?:Ext|Game)\.(?:[^\.]+))[^;]*;\s*$", RegexOptions.IgnoreCase);
                if (match.Success)
                {
                    AddReference(plugin, match.Groups[1].Value);
                    continue;
                }

                // Start parsing the Oxide.Plugins namespace contents
                match = Regex.Match(line, @"^\s*namespace Oxide\.Plugins\s*(\{\s*)?$", RegexOptions.IgnoreCase);
                if (match.Success)
                {
                    parsingNamespace = true;
                }
            }
        }
コード例 #30
0
        protected override object InvokeMethod(HookMethod method, object[] args)
        {
            object obj;
            object obj1;
            bool   compiledAssembly;

            if (!this.hookDispatchFallback && !method.IsBaseHook)
            {
                if (args != null && args.Length != 0)
                {
                    ParameterInfo[] parameters = method.Parameters;
                    for (int i = 0; i < (int)args.Length; i++)
                    {
                        object obj2 = args[i];
                        if (obj2 != null)
                        {
                            Type parameterType = parameters[i].ParameterType;
                            if (parameterType.IsValueType)
                            {
                                Type type = obj2.GetType();
                                if (parameterType != typeof(object) && type != parameterType)
                                {
                                    args[i] = Convert.ChangeType(obj2, parameterType);
                                }
                            }
                        }
                    }
                }
                try
                {
                    if (!this.DirectCallHook(method.Name, out obj, args))
                    {
                        this.PrintWarning(string.Concat("Unable to call hook directly: ", method.Name), Array.Empty <object>());
                        return(method.Method.Invoke(this, args));
                    }
                    else
                    {
                        obj1 = obj;
                    }
                }
                catch (InvalidProgramException invalidProgramException1)
                {
                    InvalidProgramException invalidProgramException = invalidProgramException1;
                    Interface.Oxide.LogError(string.Concat("Hook dispatch failure detected, falling back to reflection based dispatch. ", invalidProgramException), Array.Empty <object>());
                    CompilablePlugin compilablePlugin = CSharpPluginLoader.GetCompilablePlugin(Interface.Oxide.PluginDirectory, base.Name);
                    if (compilablePlugin != null)
                    {
                        compiledAssembly = compilablePlugin.CompiledAssembly;
                    }
                    else
                    {
                        compiledAssembly = false;
                    }
                    if (compiledAssembly)
                    {
                        File.WriteAllBytes(string.Concat(Interface.Oxide.PluginDirectory, "\\", base.Name, ".dump"), compilablePlugin.CompiledAssembly.PatchedAssembly);
                        Interface.Oxide.LogWarning(string.Concat("The invalid raw assembly has been dumped to Plugins/", base.Name, ".dump"), Array.Empty <object>());
                    }
                    this.hookDispatchFallback = true;
                    return(method.Method.Invoke(this, args));
                }
                return(obj1);
            }
            return(method.Method.Invoke(this, args));
        }