Ejemplo n.º 1
0
        private void InitCScriptPlugin(Package p, ref CSharpCodeProvider csProvider, ref CompilerParameters csParams, ref PluginGlobal csGlobal)
        {
            if (!System.IO.File.Exists(p.Path + "\\__init__.cs"))
            {
                throw new InvalidOperationException("Unable to find file __init__.cs");
            }

            CompilerParameters scriptParams = CopyParams(csParams);

            if (p.Metadata.DllIncludes != null && p.Metadata.DllIncludes.Length > 0)
            {
                foreach (String dllInclude in p.Metadata.DllIncludes)
                {
                    String dllPath = ExpandPluginPathVars(dllInclude, p);
                    if (!System.IO.File.Exists(dllPath))
                    {
                        throw new System.IO.FileNotFoundException("Unable to find .dll file", dllPath);
                    }

                    if (!scriptParams.ReferencedAssemblies.Contains(dllPath))
                    {
                        scriptParams.ReferencedAssemblies.Add(dllPath);
                    }
                }
            }

            CompilerResults results = csProvider.CompileAssemblyFromFile(scriptParams, p.Path + "\\__init__.cs");

            if (results.Errors.HasErrors)
            {
                System.Text.StringBuilder sbErrors = new System.Text.StringBuilder();
                foreach (CompilerError error in results.Errors)
                {
                    sbErrors.AppendLine(String.Format("Error ({0}): {1}", error.ErrorNumber, error.ErrorText));
                }

                throw new InvalidOperationException(sbErrors.ToString());
            }
            else
            {
                Type[] pluginTypes = results.CompiledAssembly.GetTypes().Where(t => t.IsSubclassOf(typeof(PluginClass))).ToArray();

                if (pluginTypes.Length == 0)
                {
                    throw new InvalidOperationException(p.Path.Split('\\').Last() + " doesn't have an instance of PluginClass");
                }
                else if (pluginTypes.Length > 1)
                {
                    throw new InvalidOperationException(p.Path.Split('\\').Last() + " has more than 1 instance of PluginClass");
                }

                PluginClass pluginInstance = (PluginClass)Activator.CreateInstance(pluginTypes[0]);
                pluginInstance.PluginDir = p.Path;
                pluginInstance.Global    = csGlobal;
                pluginInstance.Init();
            }
        }
Ejemplo n.º 2
0
        public void Start()
        {
            try
            {
                var reload = PackageManager.Packages != null && PackageManager.Packages.Count > 0;
                if (!reload)
                {
                    Console.WriteLine($"[{nameof(PluginManager)}] START");
                }
                else
                {
                    Console.WriteLine($"[{nameof(PluginManager)}] RESTART");
                }

                loadPackages();
                var packages = PackageManager.Packages.ToArray();
                var paths    = PackageManager.Packages.ConvertAll(package =>
                                                                  package.Path.Split('\\').Last()).ToArray();

                var engine      = Python.CreateEngine();
                var searchPaths = engine.GetSearchPaths();
                searchPaths.Add(PackageManager.RootDir);
                engine.SetSearchPaths(searchPaths);

                Console.WriteLine($"[{nameof(PluginManager)}] Executing packages");
                var scope = engine.Runtime.CreateScope();

                scope.SetVariable("GameDir", PackageManager.GameDir);
                scope.SetVariable("Globals", engine.Runtime.Globals.GetVariableNames());
                scope.SetVariable("Packages", packages);
                scope.SetVariable("PluginManager", this);
                scope.SetVariable("RootDir", PackageManager.RootDir);
                scope.SetVariable("Versions", typeof(Versions));

                CSharpCodeProvider csProvider = new CSharpCodeProvider();
                CompilerParameters csParams   = new CompilerParameters();
                csParams.GenerateInMemory   = true;
                csParams.GenerateExecutable = false;
                csParams.ReferencedAssemblies.Add(Assembly.GetAssembly(typeof(Game.GameStates.GameShipEditor)).Location);
                csParams.ReferencedAssemblies.Add(Assembly.GetAssembly(typeof(Game.Framework.IUpdatable)).Location);
                csParams.ReferencedAssemblies.Add(Assembly.GetAssembly(typeof(PluginClass)).Location);
                PluginGlobal csGlobal = new PluginGlobal(PackageManager.GameDir, packages, this, PackageManager.RootDir);

                PackageManager.Packages.ForEach((Package p) => {
                    try
                    {
                        if (p.Metadata.PackageType == PackageType.Python)
                        {
                            InitPythonPlugin(p, ref engine, ref scope);
                        }
                        else if (p.Metadata.PackageType == PackageType.CScript)
                        {
                            InitCScriptPlugin(p, ref csProvider, ref csParams, ref csGlobal);
                        }
                        else
                        {
                            throw new InvalidOperationException("Missing or invalid PackageType in plugin.json");
                        }
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine($"[{nameof(PluginManager)}] Error while executing {p.Path.Split('\\').Last()}");
                        Console.WriteLine(ex);
                    }
                });
                Console.WriteLine($"[{nameof(PluginManager)}] All packages invoked");

                if (reload && gameClient != null)
                {
                    OnClientHotReload?.Invoke(gameClient);
                }
                if (reload && gameEditor != null)
                {
                    OnEditorHotReload?.Invoke(gameEditor);
                }
                if (reload && gameMenu != null)
                {
                    OnMenuHotReload?.Invoke(gameMenu);
                }
                if (reload && gameServer != null)
                {
                    OnServerHotReload?.Invoke(gameServer);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"[{nameof(PluginManager)}] Error while starting plugins");
                Console.WriteLine(ex);
            }
        }