Exemple #1
0
 internal void Completed(byte[] rawAssembly = null)
 {
     endedAt = Interface.Oxide.Now;
     if (plugins.Count > 0 && rawAssembly != null)
         compiledAssembly = new CompiledAssembly(name, plugins.ToArray(), rawAssembly, duration);
     Interface.Oxide.NextTick(() => callback(this));
 }
 internal void Completed(byte[] rawAssembly = null)
 {
     this.endedAt = Interface.Oxide.Now;
     if (this.plugins.Count > 0 && rawAssembly != null)
     {
         this.compiledAssembly = new CompiledAssembly(this.name, this.plugins.ToArray <CompilablePlugin>(), rawAssembly, this.duration);
     }
     Interface.Oxide.NextTick(() => this.callback(this));
 }
Exemple #3
0
 internal void Completed(byte[] rawAssembly = null)
 {
     endedAt = Interface.Oxide.Now;
     if (plugins.Count > 0 && rawAssembly != null)
     {
         compiledAssembly = new CompiledAssembly(name, plugins.ToArray(), rawAssembly, duration);
     }
     Interface.Oxide.NextTick(() => callback(this));
 }
Exemple #4
0
 internal void OnCompilationSucceeded(CompiledAssembly compiledAssembly)
 {
     if (timeoutTimer == null)
     {
         Interface.Oxide.LogWarning($"Ignored unexpected plugin compilation: {Name}");
         return;
     }
     timeoutTimer?.Destroy();
     timeoutTimer        = null;
     IsCompilationNeeded = false;
     CompilationQueuedAt = 0f;
     CompiledAssembly    = compiledAssembly;
     CompileCallback?.Invoke(true);
 }
        private void AddDependency(CompilablePlugin plugin)
        {
            if (plugin.IsLoading || this.plugins.Contains(plugin) || this.queuedPlugins.Contains(plugin))
            {
                return;
            }
            CompiledAssembly compiledAssembly = plugin.CompiledAssembly;

            if (compiledAssembly == null || compiledAssembly.IsOutdated())
            {
                this.Add(plugin);
            }
            else
            {
                this.referencedPlugins.Add(plugin.Name);
                if (!this.references.ContainsKey(compiledAssembly.Name))
                {
                    this.references[compiledAssembly.Name] = new CompilerFile(compiledAssembly.Name, compiledAssembly.RawAssembly);
                    return;
                }
            }
        }
        private void AddDependency(CompilablePlugin plugin)
        {
            if (plugin.IsLoading || plugins.Contains(plugin) || queuedPlugins.Contains(plugin))
            {
                return;
            }

            CompiledAssembly compiledDependency = plugin.CompiledAssembly;

            if (compiledDependency != null && !compiledDependency.IsOutdated())
            {
                // The dependency already has a compiled assembly which is up to date
                referencedPlugins.Add(plugin.Name);
                if (!references.ContainsKey(compiledDependency.Name))
                {
                    references[compiledDependency.Name] = new CompilerFile(compiledDependency.Name, compiledDependency.RawAssembly);
                }
            }
            else
            {
                // The dependency needs to be compiled
                Add(plugin);
            }
        }
Exemple #7
0
 internal void OnCompilationSucceeded(CompiledAssembly compiledAssembly)
 {
     if (timeoutTimer == null)
     {
         Interface.Oxide.LogWarning($"Ignored unexpected plugin compilation: {Name}");
         return;
     }
     timeoutTimer?.Destroy();
     timeoutTimer = null;
     IsCompilationNeeded = false;
     CompilationQueuedAt = 0f;
     CompiledAssembly = compiledAssembly;
     CompileCallback?.Invoke(true);
 }
Exemple #8
0
        public void LoadPlugin(Action<CSharpPlugin> callback = null)
        {
            if (CompiledAssembly == null)
            {
                Interface.Oxide.LogError("Load called before a compiled assembly exists: " + Name);
                RemoteLogger.Error("Load called before a compiled assembly exists: " + Name);
                IsReloading = false;
                return;
            }

            loadCallback = callback;

            CompiledAssembly.LoadAssembly(loaded =>
            {
                IsReloading = false;
                if (!loaded)
                {
                    if (callback != null) callback(null);
                    return;
                }

                if (CompilerErrors != null)
                {
                    InitFailed("Unable to load " + ScriptName + ". " + CompilerErrors);
                    return;
                }

                var type = CompiledAssembly.LoadedAssembly.GetType("Oxide.Plugins." + Name);
                if (type == null)
                {
                    InitFailed("Unable to find main plugin class: " + Name);
                    return;
                }

                CSharpPlugin plugin = null;
                try
                {
                    plugin = Activator.CreateInstance(type) as CSharpPlugin;
                }
                catch (MissingMethodException)
                {
                    InitFailed("Main plugin class should not have a constructor defined: " + Name);
                    return;
                }
                catch (TargetInvocationException invocation_exception)
                {
                    var ex = invocation_exception.InnerException;
                    InitFailed("Unable to load " + ScriptName + ". " + ex.ToString());
                    return;
                }
                catch (Exception ex)
                {
                    InitFailed("Unable to load " + ScriptName + ". " + ex.ToString());
                    return;
                }

                if (plugin == null)
                {
                    RemoteLogger.Error("Plugin assembly failed to load: " + ScriptName);
                    InitFailed("Plugin assembly failed to load: " + ScriptName);
                    return;
                }

                plugin.SetPluginInfo(ScriptName, ScriptPath);
                plugin.Watcher = Extension.Watcher;

                if (!Interface.Oxide.PluginLoaded(plugin))
                {
                    InitFailed();
                    return;
                }

                if (!CompiledAssembly.IsBatch) LastGoodAssembly = CompiledAssembly;
                if (callback != null) callback(plugin);
            });
        }
Exemple #9
0
 private void OnPluginFailed()
 {
     if (LastGoodAssembly == null)
     {
         Interface.Oxide.LogInfo("No previous version to rollback plugin: {0}", ScriptName);
         return;
     }
     Interface.Oxide.LogInfo("Rolling back plugin to last good version: {0}", ScriptName);
     CompiledAssembly = LastGoodAssembly;
     CompilerErrors = null;
     LoadPlugin();
 }
Exemple #10
0
 public void OnCompilationSucceeded(CompiledAssembly compiled_assembly)
 {
     compilationQueuedAt = 0f;
     CompiledAssembly = compiled_assembly;
     compileCallback(true);
 }
Exemple #11
0
 private void CompileAssembly(CompilablePlugin[] plugs)
 {
     foreach (var pl in plugs) pl.OnCompilationStarted(compiler);
     var plugins = new List<CompilablePlugin>(plugs);
     compiler.Compile(plugins, (assembly_name, raw_assembly, duration) =>
     {
         if (plugins.Count > 1 && raw_assembly == null)
         {
             var plugin_names = plugins.Select(pl => pl.Name);
             var standalone_plugins = plugins.Where(pl => !pl.Requires.Any(r => plugin_names.Contains(r))).ToArray();
             foreach (var plugin in standalone_plugins) plugins.Remove(plugin);
             foreach (var plugin in plugins)
             {
                 plugin.OnCompilationFailed();
                 PluginErrors[plugin.Name] = "Batch containing dependencies failed to compile";
             }
             if (standalone_plugins.Length < 1)
             {
                 Interface.Oxide.LogError($"A batch of {plugins.Count} plugins failed to compile");
                 return;
             }
             Interface.Oxide.LogError($"A batch of {plugins.Count} plugins failed to compile, attempting to compile separately");
             foreach (var plugin in standalone_plugins) CompileAssembly(new[] { plugin });
             return;
         }
         if (raw_assembly == null)
         {
             var plugin = plugins[0];
             plugin.OnCompilationFailed();
             PluginErrors[plugin.Name] = "Failed to compile: " + plugin.CompilerErrors;
             Interface.Oxide.LogError("{0} plugin failed to compile!", plugin.ScriptName);
             Interface.Oxide.LogError(plugin.CompilerErrors);
             RemoteLogger.Warning($"{plugin.ScriptName} plugin failed to compile!\n{plugin.CompilerErrors}");
         }
         else
         {
             var compiled_plugins = plugins.Where(pl => pl.CompilerErrors == null).ToList();
             var compiled_names = compiled_plugins.Select(pl => pl.Name).ToArray();
             CompiledAssembly compiled_assembly = null;
             if (compiled_plugins.Count > 0)
             {
                 var verb = compiled_plugins.Count > 1 ? "were" : "was";
                 Interface.Oxide.LogInfo($"{compiled_names.ToSentence()} {verb} compiled successfully in {Math.Round(duration * 1000f)}ms");
                 compiled_assembly = new CompiledAssembly(assembly_name, compiled_plugins.ToArray(), raw_assembly);
             }
             foreach (var plugin in plugins)
             {
                 if (plugin.CompilerErrors == null)
                 {
                     plugin.OnCompilationSucceeded(compiled_assembly);
                 }
                 else
                 {
                     plugin.OnCompilationFailed();
                     PluginErrors[plugin.Name] = "Failed to compile: " + plugin.CompilerErrors;
                     Interface.Oxide.LogError($"Error while compiling {plugin.CompilerErrors}");
                 }
             }
         }
     });
 }
Exemple #12
0
        internal void LoadPlugin(Action <CSharpPlugin> callback = null)
        {
            if (CompiledAssembly == null)
            {
                Interface.Oxide.LogError("Load called before a compiled assembly exists: {0}", Name);
                //RemoteLogger.Error($"Load called before a compiled assembly exists: {Name}");
                return;
            }

            LoadCallback = callback;

            CompiledAssembly.LoadAssembly(loaded =>
            {
                if (!loaded)
                {
                    callback?.Invoke(null);
                    return;
                }

                if (CompilerErrors != null)
                {
                    InitFailed($"Unable to load {ScriptName}. {CompilerErrors}");
                    return;
                }

                var type = CompiledAssembly.LoadedAssembly.GetType($"Oxide.Plugins.{Name}");
                if (type == null)
                {
                    InitFailed($"Unable to find main plugin class: {Name}");
                    return;
                }

                CSharpPlugin plugin;
                try
                {
                    plugin = Activator.CreateInstance(type) as CSharpPlugin;
                }
                catch (MissingMethodException)
                {
                    InitFailed($"Main plugin class should not have a constructor defined: {Name}");
                    return;
                }
                catch (TargetInvocationException invocationException)
                {
                    var ex = invocationException.InnerException;
                    InitFailed($"Unable to load {ScriptName}. {ex.ToString()}");
                    return;
                }
                catch (Exception ex)
                {
                    InitFailed($"Unable to load {ScriptName}. {ex.ToString()}");
                    return;
                }

                if (plugin == null)
                {
                    //RemoteLogger.Error($"Plugin assembly failed to load: {ScriptName}");
                    InitFailed($"Plugin assembly failed to load: {ScriptName}");
                    return;
                }

                if (!plugin.SetPluginInfo(ScriptName, ScriptPath))
                {
                    InitFailed();
                    return;
                }

                plugin.Watcher = Extension.Watcher;
                plugin.Loader  = Loader;

                if (!Interface.Oxide.PluginLoaded(plugin))
                {
                    InitFailed();
                    return;
                }

                if (!CompiledAssembly.IsBatch)
                {
                    LastGoodAssembly = CompiledAssembly;
                }
                callback?.Invoke(plugin);
            });
        }
Exemple #13
0
        internal void LoadPlugin(Action<CSharpPlugin> callback = null)
        {
            if (CompiledAssembly == null)
            {
                Interface.Oxide.LogError("Load called before a compiled assembly exists: {0}", Name);
                RemoteLogger.Error($"Load called before a compiled assembly exists: {Name}");
                return;
            }

            LoadCallback = callback;

            CompiledAssembly.LoadAssembly(loaded =>
            {
                if (!loaded)
                {
                    callback?.Invoke(null);
                    return;
                }

                if (CompilerErrors != null)
                {
                    InitFailed($"Unable to load {ScriptName}. {CompilerErrors}");
                    return;
                }

                var type = CompiledAssembly.LoadedAssembly.GetType($"Oxide.Plugins.{Name}");
                if (type == null)
                {
                    InitFailed($"Unable to find main plugin class: {Name}");
                    return;
                }

                CSharpPlugin plugin;
                try
                {
                    plugin = Activator.CreateInstance(type) as CSharpPlugin;
                }
                catch (MissingMethodException)
                {
                    InitFailed($"Main plugin class should not have a constructor defined: {Name}");
                    return;
                }
                catch (TargetInvocationException invocationException)
                {
                    var ex = invocationException.InnerException;
                    InitFailed($"Unable to load {ScriptName}. {ex.ToString()}");
                    return;
                }
                catch (Exception ex)
                {
                    InitFailed($"Unable to load {ScriptName}. {ex.ToString()}");
                    return;
                }

                if (plugin == null)
                {
                    RemoteLogger.Error($"Plugin assembly failed to load: {ScriptName}");
                    InitFailed($"Plugin assembly failed to load: {ScriptName}");
                    return;
                }

                plugin.SetPluginInfo(ScriptName, ScriptPath);
                plugin.Watcher = Extension.Watcher;
                plugin.Loader = Loader;

                if (!Interface.Oxide.PluginLoaded(plugin))
                {
                    InitFailed();
                    return;
                }

                if (!CompiledAssembly.IsBatch) LastGoodAssembly = CompiledAssembly;
                callback?.Invoke(plugin);
            });
        }
Exemple #14
0
 internal void OnCompilationSucceeded(CompiledAssembly compiled_assembly)
 {
     IsCompilationNeeded = false;
     compilationQueuedAt = 0f;
     CompiledAssembly = compiled_assembly;
     compileCallback?.Invoke(true);
 }
        private void PatchAssembly(Action <byte[]> callback)
        {
            Action action1 = null;

            if (this.isPatching)
            {
                Interface.Oxide.LogWarning("Already patching plugin assembly: {0} (ignoring)", new object[] { this.PluginNames.ToSentence <string>() });
                return;
            }
            float now = Interface.Oxide.Now;

            this.isPatching = true;
            ThreadPool.QueueUserWorkItem((object _) => {
                AssemblyDefinition assemblyDefinition;
                try
                {
                    using (MemoryStream memoryStream = new MemoryStream(this.RawAssembly))
                    {
                        assemblyDefinition = AssemblyDefinition.ReadAssembly(memoryStream);
                    }
                    ConstructorInfo constructor      = typeof(UnauthorizedAccessException).GetConstructor(new Type[] { typeof(string) });
                    MethodReference methodReference1 = assemblyDefinition.MainModule.Import(constructor);
                    Action <TypeDefinition> methods  = null;
                    methods = (TypeDefinition type) => {
                        string fullName;
                        string str;
                        foreach (MethodDefinition method in type.Methods)
                        {
                            bool flag = false;
                            if (method.Body != null)
                            {
                                bool flag1 = false;
                                foreach (VariableDefinition variable in method.Body.Variables)
                                {
                                    if (!CompiledAssembly.IsNamespaceBlacklisted(variable.VariableType.FullName))
                                    {
                                        continue;
                                    }
                                    Mono.Cecil.Cil.MethodBody methodBody = new Mono.Cecil.Cil.MethodBody(method);
                                    methodBody.Instructions.Add(Instruction.Create(OpCodes.Ldstr, string.Concat("System access is restricted, you are not allowed to use ", variable.VariableType.FullName)));
                                    methodBody.Instructions.Add(Instruction.Create(OpCodes.Newobj, methodReference1));
                                    methodBody.Instructions.Add(Instruction.Create(OpCodes.Throw));
                                    method.Body = methodBody;
                                    flag1       = true;
                                    break;
                                }
                                if (flag1)
                                {
                                    continue;
                                }
                                Collection <Instruction> instructions = method.Body.Instructions;
                                ILProcessor lProcessor  = method.Body.GetILProcessor();
                                Instruction instruction = instructions.First <Instruction>();
                                for (int i = 0; i < instructions.Count && !flag; i++)
                                {
                                    Instruction item = instructions[i];
                                    if (item.OpCode == OpCodes.Ldtoken)
                                    {
                                        IMetadataTokenProvider operand = item.Operand as IMetadataTokenProvider;
                                        str         = (operand != null ? operand.ToString() : null);
                                        string str1 = str;
                                        if (CompiledAssembly.IsNamespaceBlacklisted(str1))
                                        {
                                            lProcessor.InsertBefore(instruction, Instruction.Create(OpCodes.Ldstr, string.Concat("System access is restricted, you are not allowed to use ", str1)));
                                            lProcessor.InsertBefore(instruction, Instruction.Create(OpCodes.Newobj, methodReference1));
                                            lProcessor.InsertBefore(instruction, Instruction.Create(OpCodes.Throw));
                                            flag = true;
                                        }
                                    }
                                    else if (item.OpCode == OpCodes.Call || item.OpCode == OpCodes.Calli || item.OpCode == OpCodes.Callvirt || item.OpCode == OpCodes.Ldftn)
                                    {
                                        MethodReference methodReference = item.Operand as MethodReference;
                                        string str2 = (methodReference != null ? methodReference.DeclaringType.FullName : null);
                                        if (str2 == "System.Type" && methodReference.Name == "GetType" || CompiledAssembly.IsNamespaceBlacklisted(str2))
                                        {
                                            lProcessor.InsertBefore(instruction, Instruction.Create(OpCodes.Ldstr, string.Concat("System access is restricted, you are not allowed to use ", str2)));
                                            lProcessor.InsertBefore(instruction, Instruction.Create(OpCodes.Newobj, methodReference1));
                                            lProcessor.InsertBefore(instruction, Instruction.Create(OpCodes.Throw));
                                            flag = true;
                                        }
                                    }
                                    else if (item.OpCode == OpCodes.Ldfld)
                                    {
                                        FieldReference fieldReference = item.Operand as FieldReference;
                                        fullName    = (fieldReference != null ? fieldReference.FieldType.FullName : null);
                                        string str3 = fullName;
                                        if (CompiledAssembly.IsNamespaceBlacklisted(str3))
                                        {
                                            lProcessor.InsertBefore(instruction, Instruction.Create(OpCodes.Ldstr, string.Concat("System access is restricted, you are not allowed to use ", str3)));
                                            lProcessor.InsertBefore(instruction, Instruction.Create(OpCodes.Newobj, methodReference1));
                                            lProcessor.InsertBefore(instruction, Instruction.Create(OpCodes.Throw));
                                            flag = true;
                                        }
                                    }
                                }
                            }
                            else if (method.HasPInvokeInfo)
                            {
                                MethodDefinition attributes           = method;
                                attributes.Attributes                 = attributes.Attributes & (Mono.Cecil.MethodAttributes.MemberAccessMask | Mono.Cecil.MethodAttributes.Private | Mono.Cecil.MethodAttributes.FamANDAssem | Mono.Cecil.MethodAttributes.Assembly | Mono.Cecil.MethodAttributes.Family | Mono.Cecil.MethodAttributes.FamORAssem | Mono.Cecil.MethodAttributes.Public | Mono.Cecil.MethodAttributes.Static | Mono.Cecil.MethodAttributes.Final | Mono.Cecil.MethodAttributes.Virtual | Mono.Cecil.MethodAttributes.HideBySig | Mono.Cecil.MethodAttributes.VtableLayoutMask | Mono.Cecil.MethodAttributes.NewSlot | Mono.Cecil.MethodAttributes.CheckAccessOnOverride | Mono.Cecil.MethodAttributes.Abstract | Mono.Cecil.MethodAttributes.SpecialName | Mono.Cecil.MethodAttributes.UnmanagedExport | Mono.Cecil.MethodAttributes.RTSpecialName | Mono.Cecil.MethodAttributes.HasSecurity | Mono.Cecil.MethodAttributes.RequireSecObject);
                                Mono.Cecil.Cil.MethodBody methodBody1 = new Mono.Cecil.Cil.MethodBody(method);
                                methodBody1.Instructions.Add(Instruction.Create(OpCodes.Ldstr, "PInvoke access is restricted, you are not allowed to use PInvoke"));
                                methodBody1.Instructions.Add(Instruction.Create(OpCodes.Newobj, methodReference1));
                                methodBody1.Instructions.Add(Instruction.Create(OpCodes.Throw));
                                method.Body = methodBody1;
                            }
                            if (!flag)
                            {
                                continue;
                            }
                            Mono.Cecil.Cil.MethodBody body = method.Body;
                            if (body != null)
                            {
                                body.OptimizeMacros();
                            }
                            else
                            {
                            }
                        }
                        foreach (TypeDefinition nestedType in type.NestedTypes)
                        {
                            methods(nestedType);
                        }
                    };
                    foreach (TypeDefinition typeDefinition in assemblyDefinition.MainModule.Types)
                    {
                        methods(typeDefinition);
                        if (this.IsCompilerGenerated(typeDefinition))
                        {
                            continue;
                        }
                        if (typeDefinition.Namespace != "Oxide.Plugins")
                        {
                            if (!(typeDefinition.FullName != "<Module>") || this.PluginNames.Any <string>((string plugin) => typeDefinition.FullName.StartsWith(string.Concat("Oxide.Plugins.", plugin))))
                            {
                                continue;
                            }
                            Interface.Oxide.LogWarning(((int)this.PluginNames.Length == 1 ? string.Concat(this.PluginNames[0], " has polluted the global namespace by defining ", typeDefinition.FullName) : string.Concat("A plugin has polluted the global namespace by defining ", typeDefinition.FullName)), Array.Empty <object>());
                        }
                        else if (!this.PluginNames.Contains <string>(typeDefinition.Name))
                        {
                            Interface.Oxide.LogWarning(((int)this.PluginNames.Length == 1 ? string.Concat(this.PluginNames[0], " has polluted the global namespace by defining ", typeDefinition.Name) : string.Concat("A plugin has polluted the global namespace by defining ", typeDefinition.Name)), Array.Empty <object>());
                        }
                        else
                        {
                            Collection <MethodDefinition> methodDefinitions = typeDefinition.Methods;
                            Func <MethodDefinition, bool> u003cu003e9_204   = CompiledAssembly.< > c.< > 9__20_4;
                            if (u003cu003e9_204 == null)
                            {
                                u003cu003e9_204 = (MethodDefinition m) => {
                                    if (m.IsStatic || !m.IsConstructor || m.HasParameters)
                                    {
                                        return(false);
                                    }
                                    return(!m.IsPublic);
                                };
                                CompiledAssembly.< > c.< > 9__20_4 = u003cu003e9_204;
                            }
                            if (methodDefinitions.FirstOrDefault <MethodDefinition>(u003cu003e9_204) == null)
                            {
                                DirectCallMethod directCallMethod = new DirectCallMethod(assemblyDefinition.MainModule, typeDefinition);
                            }
                            else
                            {
                                CompilablePlugin compilablePlugin = this.CompilablePlugins.SingleOrDefault <CompilablePlugin>((CompilablePlugin p) => p.Name == typeDefinition.Name);
                                if (compilablePlugin == null)
                                {
                                    continue;
                                }
                                compilablePlugin.CompilerErrors = "Primary constructor in main class must be public";
                            }
                        }
                    }
                    foreach (TypeDefinition typeDefinition1 in assemblyDefinition.MainModule.Types)
                    {
                        if (typeDefinition1.Namespace != "Oxide.Plugins" || !this.PluginNames.Contains <string>(typeDefinition1.Name))
                        {
                            continue;
                        }
                        Collection <MethodDefinition> methods1        = typeDefinition1.Methods;
                        Func <MethodDefinition, bool> u003cu003e9_206 = CompiledAssembly.< > c.< > 9__20_6;
                        if (u003cu003e9_206 == null)
                        {
                            u003cu003e9_206 = (MethodDefinition m) => {
                                if (m.IsStatic || m.HasGenericParameters || m.ReturnType.IsGenericParameter || m.IsSetter)
                                {
                                    return(false);
                                }
                                return(!m.IsGetter);
                            };
                            CompiledAssembly.< > c.< > 9__20_6 = u003cu003e9_206;
                        }
                        foreach (MethodDefinition methodDefinition in methods1.Where <MethodDefinition>(u003cu003e9_206))
                        {
                            foreach (ParameterDefinition parameter in methodDefinition.Parameters)
                            {
                                foreach (CustomAttribute customAttribute in parameter.CustomAttributes)
                                {
                                }
                            }
                        }
                    }
                    using (MemoryStream memoryStream1 = new MemoryStream())
                    {
                        assemblyDefinition.Write(memoryStream1);
                        this.PatchedAssembly = memoryStream1.ToArray();
                    }
                    OxideMod oxide       = Interface.Oxide;
                    Action u003cu003e9_2 = action1;
                    if (u003cu003e9_2 == null)
                    {
                        Action u003cu003e4_this = () => {
                            this.isPatching = false;
                            callback(this.PatchedAssembly);
                        };
                        Action action = u003cu003e4_this;
                        action1       = u003cu003e4_this;
                        u003cu003e9_2 = action;
                    }
                    oxide.NextTick(u003cu003e9_2);
                }
                catch (Exception exception1)
                {
                    Exception exception = exception1;
                    Interface.Oxide.NextTick(() => {
                        this.isPatching = false;
                        Interface.Oxide.LogException(string.Concat("Exception while patching: ", this.PluginNames.ToSentence <string>()), exception);
                        callback(null);
                    });
                }
            });
        }