Exemple #1
0
        private static void Unload(string path)
        {
            instance.Print("Unloading scripts in \"" + path + "\"...");

            AppDomain            oldAppDomain = null;
            List <IServerScript> oldscripts   = new List <IServerScript>();

            if (_scripts.ContainsKey(path))
            {
                oldscripts = _scripts[path];

                _scripts.Remove(path);

                oldAppDomain = SeparateAppDomain.Extract(path);
            }

            instance.Print(oldscripts.Count + " script(s) unloaded from \"" + path + "\".");
            instance.Print("");

            ScriptTimer[] timers;
            lock (ScriptTimers) timers = ScriptTimers.ToArray();

            foreach (IServerScript iscript in oldscripts)
            {
                foreach (ScriptTimer st in timers.Where(st => st.caller == iscript))
                {
                    st.Dispose();
                }

                lock (scripteventhandlers)
                {
                    if (scripteventhandlers.ContainsKey(iscript))
                    {
                        foreach (string eventname in scripteventhandlers[iscript].Keys)
                        {
                            try
                            {
                                instance.RemoveAllEventHandlers((ServerScript)iscript, eventname);

                                ((ServerScript)iscript).RemoveAllEventHandlers(eventname);
                            }
                            catch (Exception e)
                            {
                                instance.Print(PrintType.Error, "Failed to remove \"" + iscript.Name + "\"'s event handlers for event \"" + eventname + "\".");
                                instance.PrintException(e);
                            }
                        }

                        scripteventhandlers[iscript].Clear();

                        scripteventhandlers.Remove(iscript);
                    }
                }

                ServerScript script = ((ServerScript)iscript);

                if (script.timer != null)
                {
                    script.timer.Dispose();
                }

                try
                {
                    iscript.Unload();
                }
                catch (Exception e)
                {
                    instance.Print(PrintType.Error, "\"" + iscript.Name + "\"'s Unload() failed.");
                    instance.PrintException(e);
                }

                ((ILease)script.GetLifetimeService()).Unregister(instance);
            }

            lock (scripteventhandlers) scripteventhandlers.Clear();
            //assemblies.Clear();

            if (oldAppDomain != null)
            {
                AppDomain.Unload(oldAppDomain);
            }
        }
Exemple #2
0
        private static void Load(string path)
        {
            instance.Print("Loading scripts in \"" + path + "\"...");

            foreach (string file in Directory.GetFiles(path, "*.dll"))
            {
                if (AssemblyName.GetAssemblyName(file).Name == "ServerWrapper")
                {
                    instance.Print("Found ServerWrapper assembly in Scripts folder. Removing...");
                    try
                    {
                        File.Delete(file);
                    }
                    catch (Exception e)
                    {
                        instance.Print(PrintType.Warning, "Failed to remove ServerWrapper assembly from Scripts folder, this may cause issues.");
                        instance.PrintException(e);
                    }
                }
            }

            /*if (Directory.GetFiles(path, "*.cs").Length > 0)
             * {
             *  string localassembly = typeof(ServerScript).Assembly.Location;
             *  AppDomain domain = AppDomain.CreateDomain("Test");
             *  domain.DoCallBack(() =>
             *  {
             *      System.CodeDom.Compiler.CompilerParameters options = new System.CodeDom.Compiler.CompilerParameters();
             *      options.CompilerOptions = "/optimize /unsafe";
             *      options.GenerateInMemory = true;
             *      //options.GenerateInMemory = false;
             *      options.IncludeDebugInformation = true;
             *      options.ReferencedAssemblies.AddRange(new string[]
             *      {
             *          "System.dll",
             *          "System.Core.dll",
             *          "System.Drawing.dll",
             *          "System.Windows.Forms.dll",
             *          "System.XML.dll",
             *          "System.XML.Linq.dll",
             *          localassembly,
             *          "System.ComponentModel.Composition.dll"
             *      });
             *
             *      System.CodeDom.Compiler.CodeDomProvider compiler = new Microsoft.CSharp.CSharpCodeProvider();
             *
             *      foreach (string file in Directory.GetFiles(path, "*.cs"))
             *      {
             *          options.OutputAssembly = Path.ChangeExtension(file, ".dll");
             *
             *          System.CodeDom.Compiler.CompilerResults result = compiler.CompileAssemblyFromFile(options, file);
             *
             *          if (!result.Errors.HasErrors)
             *          {
             *              instance.RconPrint((result.CompiledAssembly == null).ToString());
             *              instance.RconPrint(result.PathToAssembly);
             *          }
             *          else
             *          {
             *              string errors = "";
             *
             *              foreach (System.CodeDom.Compiler.CompilerError error in result.Errors) errors += "   at line " + error.Line + ": " + error.ErrorText + "\r\n";
             *
             *              instance.RconPrint("[ERROR] Failed to compile '" + Path.GetFileName(file) + "' with " + result.Errors.Count + " error(s):\r\n" + errors.ToString());
             *          }
             *      }
             *  });
             *
             *  AppDomain.Unload(domain);
             * }*/

            MefLoader mefLoader = SeparateAppDomain.CreateInstance <MefLoader>(path, path);

            mefLoader.Domain.UnhandledException += (sender, e) =>
            {
                instance.Print(PrintType.Error, "Unhandled exception occured in script.");
                instance.PrintException((Exception)e.ExceptionObject);
            };

            /*mefLoader.Domain.AssemblyResolve += (sender, e) =>
             * {
             *
             * };*/

            List <IServerScript> scripts = mefLoader.Load <IServerScript>();

            if (scripts.Count == 0)
            {
                SeparateAppDomain.Delete(path);

                instance.Print("No scripts found in \"" + path + "\".");

                return;
            }

            //assemblies.Clear();

            _scripts.Add(path, scripts);

            instance.Print(scripts.Count + " script(s) found in \"" + path + "\".");
            instance.Print("");

            // Sorting logic from ScriptHookVDotNet
            Dictionary <IServerScript, List <string> > graph = new Dictionary <IServerScript, List <string> >();
            Queue <IServerScript> sorted = new Queue <IServerScript>();

            foreach (IServerScript script in scripts)
            {
                graph.Add(script, new List <string>(script.Dependencies));
            }

            while (graph.Count > 0)
            {
                IServerScript s = null;

                foreach (var kv in graph)
                {
                    if (kv.Value.Count == 0)
                    {
                        s = kv.Key;

                        break;
                    }
                }

                if (s == null)
                {
                    instance.Print(PrintType.Fatal, "Detected a circular script dependency. Aborting...");
                    instance.Print("");

                    return;
                }

                sorted.Enqueue(s);
                graph.Remove(s);

                foreach (var kv in graph)
                {
                    kv.Value.Remove(s.TypeName);
                }
            }

            if (graph.Count == 0)
            {
                LoadScripts(sorted);
            }
        }