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(); } }
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); } }