private void CompileScripts() { if (!Directory.Exists(scriptsPath)) { Directory.CreateDirectory(scriptsPath); return; } var files = Directory.GetFiles(scriptsPath, "*.cs"); availableScripts = files.ToDictionary(f => f, ScriptInfo.FromTextFile); var ignoresPath = Path.Combine(scriptsPath, "scriptignores"); if (!File.Exists(ignoresPath)) { File.WriteAllText(ignoresPath, ""); } var ignores = new HashSet <string>(File.ReadAllLines(ignoresPath).Select(s => s.Trim())); var scriptsToCompile = files.Where(f => !ignores.Contains(Path.GetFileName(f))).ToList(); Logger.LogInfo( $"Found {files.Length} scripts to compile, skipping {files.Length - scriptsToCompile.Count} scripts because of `scriptignores`"); var md5 = MD5.Create(); var scriptDict = new Dictionary <string, byte[]>(); foreach (var scriptFile in scriptsToCompile) { var data = File.ReadAllBytes(scriptFile); md5.TransformBlock(data, 0, data.Length, null, 0); scriptDict[scriptFile] = data; } md5.TransformFinalBlock(new byte[0], 0, 0); var hash = Convert.ToBase64String(md5.Hash); if (hash == lastCompilationHash) { Logger.LogInfo("No changes detected! Skipping compilation!"); return; } foreach (var scriptFile in scriptsToCompile) { if (!availableScripts.TryGetValue(scriptFile, out var info) || info == null) { continue; } foreach (var infoReference in info.References) { Assembly.LoadFile(infoReference); } } var ass = MonoCompiler.Compile(scriptDict, loggerTextWriter); if (ass == null) { Logger.LogError("Skipping loading scripts because of errors above."); return; } if (lastCompilationAssembly != null) { foreach (var type in lastCompilationAssembly.GetTypes()) { var method = type.GetMethods(BindingFlags.Static | BindingFlags.Public) .FirstOrDefault(m => m.Name == "Unload" && m.GetParameters().Length == 0); if (method == null) { continue; } Logger.Log(LogLevel.Info, $"Unloading {type.Name}"); method.Invoke(null, new object[0]); } } lastCompilationAssembly = ass; lastCompilationHash = hash; foreach (var type in ass.GetTypes()) { var method = type.GetMethods(BindingFlags.Static | BindingFlags.Public) .FirstOrDefault(m => m.Name == "Main" && m.GetParameters().Length == 0); if (method == null) { continue; } Logger.Log(LogLevel.Info, $"Running {type.Name}"); method.Invoke(null, new object[0]); } }
private void CompileScripts() { if (!Directory.Exists(ScriptsPath)) { Directory.CreateDirectory(ScriptsPath); return; } try { var files = Directory.GetFiles(ScriptsPath, "*.cs"); AvailableScripts = files.ToDictionary(f => f, ScriptInfo.FromTextFile); Logger.Info($"Found {files.Length} scripts to compile"); var md5 = MD5.Create(); var scriptDict = new Dictionary <string, byte[]>(); foreach (var scriptFile in files) { var data = File.ReadAllBytes(scriptFile); md5.TransformBlock(data, 0, data.Length, null, 0); scriptDict[scriptFile] = data; } md5.TransformFinalBlock(new byte[0], 0, 0); var hash = Convert.ToBase64String(md5.Hash); if (hash == _lastCompilationHash) { Logger.Info("No changes detected! Skipping compilation!"); return; } foreach (var scriptFile in files) { if (!AvailableScripts.TryGetValue(scriptFile, out var info)) { continue; } foreach (var infoReference in info.References) { Assembly.LoadFile(infoReference); } } var ass = MonoCompiler.Compile(scriptDict, _loggerTextWriter); if (ass == null) { _lastCompilationHash = null; Logger.Error("Skipping loading scripts because of errors above."); return; } if (_lastCompilationAssembly != null) { foreach (var type in _lastCompilationAssembly.GetTypes()) { Api.CommandManager.UnregisterCommand(type); var method = type.GetMethods(BindingFlags.Static | BindingFlags.Public) .FirstOrDefault(m => m.Name == "Unload" && m.GetParameters().Length == 0); if (method == null) { continue; } SixModLoader.SixModLoader.Instance.EventManager.UnregisterStatic(type); Logger.Info($"Unloading {type.Name}"); method.Invoke(null, new object[0]); } } _lastCompilationAssembly = ass; _lastCompilationHash = hash; foreach (var type in ass.GetTypes()) { Api.CommandManager.RegisterCommand(type); var method = type.GetMethods(BindingFlags.Static | BindingFlags.Public) .FirstOrDefault(m => m.Name == "Main" && m.GetParameters().Length == 0); if (method == null) { continue; } SixModLoader.SixModLoader.Instance.EventManager.RegisterStatic(type); Logger.Info($"Running {type.Name}"); method.Invoke(null, new object[0]); } } catch (Exception e) { Logger.Error("Failed compiling scripts\n" + e); } }