public void Run(IBasicLogger logger) { if (state != State.Initialized) { throw new InvalidOperationException($"Cannot run from {state} state"); } if (logger == null) { throw new ArgumentNullException(nameof(logger)); } state = State.Running; System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch(); while (state == State.Running) { stopwatch.Start(); foreach (ILogMessage message in logQueue.TakeAll()) { message.LogTo(logger); } long timeRemaining = timeToWaitForLogsMs - stopwatch.ElapsedMilliseconds; if (timeRemaining > 0) { System.Threading.Thread.Sleep((int)timeRemaining); } stopwatch.Reset(); } foreach (ILogMessage message in logQueue.TakeAll()) { message.LogTo(logger); } state = State.Stopped; }
public void Apply(UrlDir.UrlFile file, IPatchProgress progress, IBasicLogger logger) { if (file == null) { throw new ArgumentNullException(nameof(file)); } if (progress == null) { throw new ArgumentNullException(nameof(progress)); } if (logger == null) { throw new ArgumentNullException(nameof(logger)); } int i = 0; while (i < file.configs.Count) { UrlDir.UrlConfig url = file.configs[i]; try { if (NodeMatcher.IsMatch(url.config)) { progress.ApplyingDelete(url, UrlConfig); file.configs.RemoveAt(i); } else { i++; } } catch (Exception ex) { progress.Exception(UrlConfig, $"Exception while applying delete {UrlConfig.SafeUrl()} to {url.SafeUrl()}", ex); } } }
public void TestApply() { UrlDir.UrlFile file = UrlBuilder.CreateFile("abc/def.cfg"); UrlDir.UrlConfig urlConfig1 = UrlBuilder.CreateConfig(new ConfigNode("NODE"), file); UrlDir.UrlConfig urlConfig2 = UrlBuilder.CreateConfig(new ConfigNode("NODE"), file); UrlDir.UrlConfig urlConfig3 = UrlBuilder.CreateConfig(new ConfigNode("NODE"), file); UrlDir.UrlConfig urlConfig4 = UrlBuilder.CreateConfig(new ConfigNode("NODE"), file); INodeMatcher nodeMatcher = Substitute.For <INodeMatcher>(); nodeMatcher.IsMatch(urlConfig1.config).Returns(false); nodeMatcher.IsMatch(urlConfig2.config).Returns(true); nodeMatcher.IsMatch(urlConfig3.config).Returns(false); nodeMatcher.IsMatch(urlConfig4.config).Returns(true); DeletePatch patch = new DeletePatch(UrlBuilder.CreateConfig("ghi/jkl", new ConfigNode("!NODE")), nodeMatcher, Substitute.For <IPassSpecifier>()); IPatchProgress progress = Substitute.For <IPatchProgress>(); IBasicLogger logger = Substitute.For <IBasicLogger>(); patch.Apply(file, progress, logger); Assert.Equal(new[] { urlConfig1, urlConfig3 }, file.configs); Received.InOrder(delegate { progress.ApplyingDelete(urlConfig2, patch.UrlConfig); progress.ApplyingDelete(urlConfig4, patch.UrlConfig); }); progress.DidNotReceiveWithAnyArgs().ApplyingUpdate(null, null); progress.DidNotReceiveWithAnyArgs().ApplyingCopy(null, null); progress.DidNotReceiveWithAnyArgs().Error(null, null); progress.DidNotReceiveWithAnyArgs().Exception(null, null); progress.DidNotReceiveWithAnyArgs().Exception(null, null, null); }
public static void Info(this IBasicLogger logger, string message) => logger.Log(LogType.Log, message);
public PatchProgress(IBasicLogger logger, ProgressCounter counter) { this.logger = logger; this.Counter = counter; }
public void Apply(LinkedList <IProtoUrlConfig> databaseConfigs, IPatchProgress progress, IBasicLogger logger) { if (databaseConfigs == null) { throw new ArgumentNullException(nameof(databaseConfigs)); } if (progress == null) { throw new ArgumentNullException(nameof(progress)); } if (logger == null) { throw new ArgumentNullException(nameof(logger)); } PatchContext context = new PatchContext(UrlConfig, databaseConfigs, logger, progress); for (LinkedListNode <IProtoUrlConfig> listNode = databaseConfigs.First; listNode != null; listNode = listNode.Next) { IProtoUrlConfig protoConfig = listNode.Value; try { if (!NodeMatcher.IsMatch(protoConfig.Node)) { continue; } ConfigNode clone = MMPatchLoader.ModifyNode(new NodeStack(protoConfig.Node), UrlConfig.config, context); if (protoConfig.Node.GetValue("name") is string name && name == clone.GetValue("name")) { progress.Error(UrlConfig, $"Error - when applying copy {UrlConfig.SafeUrl()} to {protoConfig.FullUrl} - the copy needs to have a different name than the parent (use @name = xxx)"); } else { progress.ApplyingCopy(protoConfig, UrlConfig); listNode = databaseConfigs.AddAfter(listNode, new ProtoUrlConfig(protoConfig.UrlFile, clone)); } }
public PatchApplier(PatchList patchList, UrlDir databaseRoot, IPatchProgress progress, IBasicLogger logger) { this.patchList = patchList; this.databaseRoot = databaseRoot; this.progress = progress; this.logger = logger; allConfigFiles = databaseRoot.AllConfigFiles.ToArray(); }
public InGameTestRunnerTest() { logger = Substitute.For <IBasicLogger>(); databaseRoot = UrlBuilder.CreateRoot(); testRunner = new InGameTestRunner(logger); }
public NeedsChecker(IEnumerable <string> mods, UrlDir gameData, IPatchProgress progress, IBasicLogger logger) { this.mods = mods ?? throw new ArgumentNullException(nameof(mods)); this.gameData = gameData ?? throw new ArgumentNullException(nameof(gameData)); this.progress = progress ?? throw new ArgumentNullException(nameof(progress)); this.logger = logger ?? throw new ArgumentNullException(nameof(logger)); }
public void LogTo(IBasicLogger logger) { logger.Exception(message, exception); }
public PatchContext(UrlDir.UrlConfig patchUrl, IEnumerable <IProtoUrlConfig> databaseConfigs, IBasicLogger logger, IPatchProgress progress) { this.patchUrl = patchUrl; this.databaseConfigs = databaseConfigs; this.logger = logger; this.progress = progress; }
public void TestApply() { UrlDir.UrlFile file = UrlBuilder.CreateFile("abc/def.cfg"); ConfigNode config1 = new TestConfigNode("NODE") { { "foo", "bar" }, }; ConfigNode config2 = new TestConfigNode("NODE") { { "foo", "bar" }, }; ConfigNode config3 = new ConfigNode("NODE"); ConfigNode config4 = new ConfigNode("NODE"); INodeMatcher nodeMatcher = Substitute.For <INodeMatcher>(); nodeMatcher.IsMatch(config1).Returns(false); nodeMatcher.IsMatch(config2).Returns(true); nodeMatcher.IsMatch(config3).Returns(false); nodeMatcher.IsMatch(config4).Returns(true); EditPatch patch = new EditPatch(UrlBuilder.CreateConfig("ghi/jkl", new TestConfigNode("@NODE") { { "@foo", "baz" }, { "pqr", "stw" }, }), nodeMatcher, Substitute.For <IPassSpecifier>()); IProtoUrlConfig urlConfig1 = Substitute.For <IProtoUrlConfig>(); IProtoUrlConfig urlConfig2 = Substitute.For <IProtoUrlConfig>(); IProtoUrlConfig urlConfig3 = Substitute.For <IProtoUrlConfig>(); IProtoUrlConfig urlConfig4 = Substitute.For <IProtoUrlConfig>(); urlConfig1.Node.Returns(config1); urlConfig2.Node.Returns(config2); urlConfig3.Node.Returns(config3); urlConfig4.Node.Returns(config4); urlConfig1.UrlFile.Returns(file); urlConfig2.UrlFile.Returns(file); urlConfig3.UrlFile.Returns(file); urlConfig4.UrlFile.Returns(file); LinkedList <IProtoUrlConfig> configs = new LinkedList <IProtoUrlConfig>(); configs.AddLast(urlConfig1); configs.AddLast(urlConfig2); configs.AddLast(urlConfig3); configs.AddLast(urlConfig4); IPatchProgress progress = Substitute.For <IPatchProgress>(); IBasicLogger logger = Substitute.For <IBasicLogger>(); patch.Apply(configs, progress, logger); IProtoUrlConfig[] newConfigs = configs.ToArray(); Assert.Equal(4, newConfigs.Length); Assert.Same(urlConfig1, newConfigs[0]); AssertNodesEqual(new TestConfigNode("NODE") { { "foo", "bar" }, }, newConfigs[0].Node); AssertNodesEqual(new TestConfigNode("NODE") { { "foo", "baz" }, { "pqr", "stw" }, }, newConfigs[1].Node); Assert.Same(file, newConfigs[1].UrlFile); Assert.Same(urlConfig3, newConfigs[2]); AssertNodesEqual(new ConfigNode("NODE"), newConfigs[2].Node); AssertNodesEqual(new TestConfigNode("NODE") { { "pqr", "stw" }, }, newConfigs[3].Node); Assert.Same(file, newConfigs[3].UrlFile); Received.InOrder(delegate { progress.ApplyingUpdate(urlConfig2, patch.UrlConfig); progress.ApplyingUpdate(urlConfig4, patch.UrlConfig); }); progress.DidNotReceiveWithAnyArgs().ApplyingCopy(null, null); progress.DidNotReceiveWithAnyArgs().ApplyingDelete(null, null); progress.DidNotReceiveWithAnyArgs().Error(null, null); progress.DidNotReceiveWithAnyArgs().Exception(null, null); progress.DidNotReceiveWithAnyArgs().Exception(null, null, null); }
public PatchApplier(IPatchProgress progress, IBasicLogger logger) { this.progress = progress ?? throw new ArgumentNullException(nameof(progress)); this.logger = logger ?? throw new ArgumentNullException(nameof(logger)); }
public void TestApplyPatches() { IBasicLogger logger = Substitute.For <IBasicLogger>(); IPatchProgress progress = Substitute.For <IPatchProgress>(); PatchApplier patchApplier = new PatchApplier(progress, logger); IPass pass1 = Substitute.For <IPass>(); IPass pass2 = Substitute.For <IPass>(); IPass pass3 = Substitute.For <IPass>(); pass1.Name.Returns(":PASS1"); pass2.Name.Returns(":PASS2"); pass3.Name.Returns(":PASS3"); UrlDir.UrlConfig[] patchUrlConfigs = new UrlDir.UrlConfig[9]; IPatch[] patches = new IPatch[9]; for (int i = 0; i < patches.Length; i++) { patches[i] = Substitute.For <IPatch>(); } patches[0].CountsAsPatch.Returns(false); patches[1].CountsAsPatch.Returns(false); patches[2].CountsAsPatch.Returns(false); patches[3].CountsAsPatch.Returns(true); patches[4].CountsAsPatch.Returns(true); patches[5].CountsAsPatch.Returns(true); patches[6].CountsAsPatch.Returns(true); patches[7].CountsAsPatch.Returns(true); patches[8].CountsAsPatch.Returns(true); pass1.GetEnumerator().Returns(new ArrayEnumerator <IPatch>(patches[0], patches[1], patches[2])); pass2.GetEnumerator().Returns(new ArrayEnumerator <IPatch>(patches[3], patches[4], patches[5])); pass3.GetEnumerator().Returns(new ArrayEnumerator <IPatch>(patches[6], patches[7], patches[8])); IPass[] patchList = new IPass[] { pass1, pass2, pass3 }; LinkedList <IProtoUrlConfig> databaseConfigs = Assert.IsType <LinkedList <IProtoUrlConfig> >(patchApplier.ApplyPatches(new[] { pass1, pass2, pass3 })); progress.DidNotReceiveWithAnyArgs().Error(null, null); progress.DidNotReceiveWithAnyArgs().Exception(null, null); progress.DidNotReceiveWithAnyArgs().Exception(null, null, null); logger.AssertNoWarning(); logger.AssertNoError(); logger.AssertNoException(); Received.InOrder(delegate { progress.PassStarted(pass1); patches[0].Apply(databaseConfigs, progress, logger); patches[1].Apply(databaseConfigs, progress, logger); patches[2].Apply(databaseConfigs, progress, logger); progress.PassStarted(pass2); patches[3].Apply(databaseConfigs, progress, logger); progress.PatchApplied(); patches[4].Apply(databaseConfigs, progress, logger); progress.PatchApplied(); patches[5].Apply(databaseConfigs, progress, logger); progress.PatchApplied(); progress.PassStarted(pass3); patches[6].Apply(databaseConfigs, progress, logger); progress.PatchApplied(); patches[7].Apply(databaseConfigs, progress, logger); progress.PatchApplied(); patches[8].Apply(databaseConfigs, progress, logger); progress.PatchApplied(); }); }
public static void CheckNeeds(UrlDir gameDatabaseRoot, IEnumerable <string> mods, IPatchProgress progress, IBasicLogger logger) { UrlDir gameData = gameDatabaseRoot.children.First(dir => dir.type == UrlDir.DirectoryType.GameData && dir.name == ""); foreach (UrlDir.UrlConfig mod in gameDatabaseRoot.AllConfigs.ToArray()) { UrlDir.UrlConfig currentMod = mod; try { if (mod.config.name == null) { progress.Error(currentMod, "Error - Node in file " + currentMod.parent.url + " subnode: " + currentMod.type + " has config.name == null"); } UrlDir.UrlConfig newMod; if (currentMod.type.IndexOf(":NEEDS[", StringComparison.OrdinalIgnoreCase) >= 0) { string type = currentMod.type; if (CheckNeeds(ref type, mods, gameData)) { ConfigNode copy = new ConfigNode(type); copy.ShallowCopyFrom(currentMod.config); int index = mod.parent.configs.IndexOf(currentMod); newMod = new UrlDir.UrlConfig(currentMod.parent, copy); mod.parent.configs[index] = newMod; } else { progress.NeedsUnsatisfiedRoot(currentMod); mod.parent.configs.Remove(currentMod); continue; } } else { newMod = currentMod; } // Recursively check the contents PatchContext context = new PatchContext(newMod, gameDatabaseRoot, logger, progress); CheckNeeds(new NodeStack(newMod.config), context, mods, gameData); } catch (Exception ex) { try { mod.parent.configs.Remove(currentMod); } catch (Exception ex2) { logger.Exception("Exception while attempting to ensure config removed", ex2); } try { progress.Exception(mod, "Exception while checking needs on root node :\n" + mod.PrettyPrint(), ex); } catch (Exception ex2) { progress.Exception("Exception while attempting to log an exception", ex2); } } } }
public InGameTestRunner(IBasicLogger logger) { this.logger = logger ?? throw new ArgumentNullException(nameof(logger)); }
public PrefixLoggerTest() { innerLogger = Substitute.For <IBasicLogger>(); logger = new PrefixLogger("MyMod", innerLogger); }
public IBasicLoggerExtensionsTest() { logger = Substitute.For <IBasicLogger>(); }
public PatchProgressTest() { logger = Substitute.For <IBasicLogger>(); progress = new PatchProgress(logger); }
public void TestApply__Loop() { UrlDir.UrlFile file = UrlBuilder.CreateFile("abc/def.cfg"); UrlDir.UrlConfig urlConfig = UrlBuilder.CreateConfig(new TestConfigNode("NODE") { { "name", "000" }, { "aaa", "1" }, }, file); INodeMatcher nodeMatcher = Substitute.For <INodeMatcher>(); nodeMatcher.IsMatch(Arg.Is <ConfigNode>(node => int.Parse(node.GetValue("aaa")) < 10)).Returns(true); EditPatch patch = new EditPatch(UrlBuilder.CreateConfig("ghi/jkl", new TestConfigNode("@NODE") { { "@aaa *", "2" }, { "bbb", "002" }, new ConfigNode("MM_PATCH_LOOP"), }), nodeMatcher, Substitute.For <IPassSpecifier>()); IPatchProgress progress = Substitute.For <IPatchProgress>(); IBasicLogger logger = Substitute.For <IBasicLogger>(); List <UrlDir.UrlConfig> modifiedUrlConfigs = new List <UrlDir.UrlConfig>(); progress.ApplyingUpdate(Arg.Do <UrlDir.UrlConfig>(url => modifiedUrlConfigs.Add(url)), patch.UrlConfig); patch.Apply(file, progress, logger); Assert.Equal(1, file.configs.Count); Assert.NotSame(urlConfig, file.configs[0]); AssertNodesEqual(new TestConfigNode("NODE") { { "name", "000" }, { "aaa", "16" }, { "bbb", "002" }, { "bbb", "002" }, { "bbb", "002" }, { "bbb", "002" }, }, file.configs[0].config); Assert.Same(urlConfig, modifiedUrlConfigs[0]); Assert.NotSame(urlConfig, modifiedUrlConfigs[1]); Assert.NotSame(urlConfig, modifiedUrlConfigs[2]); Assert.NotSame(urlConfig, modifiedUrlConfigs[3]); Received.InOrder(delegate { logger.Log(LogType.Log, "Looping on ghi/jkl/@NODE to abc/def/NODE"); progress.ApplyingUpdate(urlConfig, patch.UrlConfig); progress.ApplyingUpdate(modifiedUrlConfigs[1], patch.UrlConfig); progress.ApplyingUpdate(modifiedUrlConfigs[2], patch.UrlConfig); progress.ApplyingUpdate(modifiedUrlConfigs[3], patch.UrlConfig); }); progress.DidNotReceiveWithAnyArgs().ApplyingCopy(null, null); progress.DidNotReceiveWithAnyArgs().ApplyingDelete(null, null); progress.DidNotReceiveWithAnyArgs().Error(null, null); progress.DidNotReceiveWithAnyArgs().Exception(null, null); progress.DidNotReceiveWithAnyArgs().Exception(null, null, null); }
public LogSplitter(IBasicLogger logger1, IBasicLogger logger2) { this.logger1 = logger1 ?? throw new ArgumentNullException(nameof(logger1)); this.logger2 = logger2 ?? throw new ArgumentNullException(nameof(logger2)); }
public void TestApply() { UrlDir.UrlFile file = UrlBuilder.CreateFile("abc/def.cfg"); UrlDir.UrlConfig urlConfig1 = UrlBuilder.CreateConfig(new TestConfigNode("NODE") { { "foo", "bar" }, }, file); UrlDir.UrlConfig urlConfig2 = UrlBuilder.CreateConfig(new TestConfigNode("NODE") { { "foo", "bar" }, }, file); UrlDir.UrlConfig urlConfig3 = UrlBuilder.CreateConfig(new ConfigNode("NODE"), file); UrlDir.UrlConfig urlConfig4 = UrlBuilder.CreateConfig(new ConfigNode("NODE"), file); INodeMatcher nodeMatcher = Substitute.For <INodeMatcher>(); nodeMatcher.IsMatch(urlConfig1.config).Returns(false); nodeMatcher.IsMatch(urlConfig2.config).Returns(true); nodeMatcher.IsMatch(urlConfig3.config).Returns(false); nodeMatcher.IsMatch(urlConfig4.config).Returns(true); EditPatch patch = new EditPatch(UrlBuilder.CreateConfig("ghi/jkl", new TestConfigNode("@NODE") { { "@foo", "baz" }, { "pqr", "stw" }, }), nodeMatcher, Substitute.For <IPassSpecifier>()); IPatchProgress progress = Substitute.For <IPatchProgress>(); IBasicLogger logger = Substitute.For <IBasicLogger>(); patch.Apply(file, progress, logger); Assert.Equal(4, file.configs.Count); Assert.Same(urlConfig1, file.configs[0]); AssertNodesEqual(new TestConfigNode("NODE") { { "foo", "bar" }, }, file.configs[0].config); Assert.NotSame(urlConfig2, file.configs[1]); AssertNodesEqual(new TestConfigNode("NODE") { { "foo", "baz" }, { "pqr", "stw" }, }, file.configs[1].config); Assert.Same(urlConfig3, file.configs[2]); AssertNodesEqual(new ConfigNode("NODE"), file.configs[2].config); Assert.NotSame(urlConfig4, file.configs[3]); AssertNodesEqual(new TestConfigNode("NODE") { { "pqr", "stw" }, }, file.configs[3].config); Received.InOrder(delegate { progress.ApplyingUpdate(urlConfig2, patch.UrlConfig); progress.ApplyingUpdate(urlConfig4, patch.UrlConfig); }); progress.DidNotReceiveWithAnyArgs().ApplyingCopy(null, null); progress.DidNotReceiveWithAnyArgs().ApplyingDelete(null, null); progress.DidNotReceiveWithAnyArgs().Error(null, null); progress.DidNotReceiveWithAnyArgs().Exception(null, null); progress.DidNotReceiveWithAnyArgs().Exception(null, null, null); }
public void Apply(LinkedList <IProtoUrlConfig> configs, IPatchProgress progress, IBasicLogger logger) { if (configs == null) { throw new ArgumentNullException(nameof(configs)); } if (progress == null) { throw new ArgumentNullException(nameof(progress)); } if (logger == null) { throw new ArgumentNullException(nameof(logger)); } ConfigNode node = UrlConfig.config.DeepCopy(); node.name = NodeType; configs.AddLast(new ProtoUrlConfig(UrlConfig.parent, node)); }
public PatchProgress(IBasicLogger logger) { this.logger = logger; Counter = new ProgressCounter(); }
public MMPatchRunner(IBasicLogger kspLogger) { this.kspLogger = kspLogger ?? throw new ArgumentNullException(nameof(kspLogger)); }
public PatchProgress(IPatchProgress progress, IBasicLogger logger) { this.logger = logger; Counter = progress.Counter; }
public static void Error(this IBasicLogger logger, string message) => logger.Log(LogType.Error, message);
public static IEnumerable <string> GenerateModList(IEnumerable <ModAddedByAssembly> modsAddedByAssemblies, IPatchProgress progress, IBasicLogger logger) { #region List of mods //string envInfo = "ModuleManager env info\n"; //envInfo += " " + Environment.OSVersion.Platform + " " + ModuleManager.intPtr.ToInt64().ToString("X16") + "\n"; //envInfo += " " + Convert.ToString(ModuleManager.intPtr.ToInt64(), 2) + " " + Convert.ToString(ModuleManager.intPtr.ToInt64() >> 63, 2) + "\n"; //string gamePath = Environment.GetCommandLineArgs()[0]; //envInfo += " Args: " + gamePath.Split(Path.DirectorySeparatorChar).Last() + " " + string.Join(" ", Environment.GetCommandLineArgs().Skip(1).ToArray()) + "\n"; //envInfo += " Executable SHA256 " + FileSHA(gamePath); // //log(envInfo); List <string> mods = new List <string>(); StringBuilder modListInfo = new StringBuilder(); modListInfo.Append("compiling list of loaded mods...\nMod DLLs found:\n"); string format = " {0,-40}{1,-25}{2,-25}{3,-25}{4}\n"; modListInfo.AppendFormat( format, "Name", "Assembly Version", "Assembly File Version", "KSPAssembly Version", "SHA256" ); modListInfo.Append('\n'); foreach (AssemblyLoader.LoadedAssembly mod in AssemblyLoader.loadedAssemblies) { if (string.IsNullOrEmpty(mod.assembly.Location)) //Diazo Edit for xEvilReeperx AssemblyReloader mod { continue; } FileVersionInfo fileVersionInfo = FileVersionInfo.GetVersionInfo(mod.assembly.Location); AssemblyName assemblyName = mod.assembly.GetName(); string kspAssemblyVersion; if (mod.versionMajor == 0 && mod.versionMinor == 0) { kspAssemblyVersion = ""; } else { kspAssemblyVersion = mod.versionMajor + "." + mod.versionMinor; } string fileSha = ""; try { fileSha = FileUtils.FileSHA(mod.assembly.Location); } catch (Exception e) { progress.Exception("Exception while generating SHA for assembly " + assemblyName.Name, e); } modListInfo.AppendFormat( format, assemblyName.Name, assemblyName.Version, fileVersionInfo.FileVersion, kspAssemblyVersion, fileSha ); // modlist += String.Format(" {0,-50} SHA256 {1}\n", modInfo, FileSHA(mod.assembly.Location)); if (!mods.Contains(assemblyName.Name, StringComparer.OrdinalIgnoreCase)) { mods.Add(assemblyName.Name); } } modListInfo.Append("Non-DLL mods added (:FOR[xxx]):\n"); foreach (UrlDir.UrlConfig cfgmod in GameDatabase.Instance.root.AllConfigs) { if (CommandParser.Parse(cfgmod.type, out string name) != Command.Insert) { if (name.Contains(":FOR[")) { name = name.RemoveWS(); // check for FOR[] blocks that don't match loaded DLLs and add them to the pass list try { string dependency = name.Substring(name.IndexOf(":FOR[") + 5); dependency = dependency.Substring(0, dependency.IndexOf(']')); if (!mods.Contains(dependency, StringComparer.OrdinalIgnoreCase)) { // found one, now add it to the list. mods.Add(dependency); modListInfo.AppendFormat(" {0}\n", dependency); } } catch (ArgumentOutOfRangeException) { progress.Error(cfgmod, "Skipping :FOR init for line " + name + ". The line most likely contains a space that should be removed"); } } } } modListInfo.Append("Mods by directory (sub directories of GameData):\n"); UrlDir gameData = GameDatabase.Instance.root.children.First(dir => dir.type == UrlDir.DirectoryType.GameData); foreach (UrlDir subDir in gameData.children) { string cleanName = subDir.name.RemoveWS(); if (!mods.Contains(cleanName, StringComparer.OrdinalIgnoreCase)) { mods.Add(cleanName); modListInfo.AppendFormat(" {0}\n", cleanName); } } modListInfo.Append("Mods added by assemblies:\n"); foreach (ModAddedByAssembly mod in modsAddedByAssemblies) { if (!mods.Contains(mod.modName, StringComparer.OrdinalIgnoreCase)) { mods.Add(mod.modName); modListInfo.AppendFormat(" {0}\n", mod); } } logger.Info(modListInfo.ToString()); mods.Sort(); #endregion List of mods return(mods); }
public static void Warning(this IBasicLogger logger, string message) => logger.Log(LogType.Warning, message);
public static IEnumerable <ModAddedByAssembly> GetAdditionalModsFromStaticMethods(IBasicLogger logger) { List <ModAddedByAssembly> result = new List <ModAddedByAssembly>(); foreach (Assembly ass in AppDomain.CurrentDomain.GetAssemblies()) { try { foreach (Type type in ass.GetTypes()) { MethodInfo method = type.GetMethod("ModuleManagerAddToModList", BindingFlags.Public | BindingFlags.Static); if (method != null && method.GetParameters().Length == 0 && typeof(IEnumerable <string>).IsAssignableFrom(method.ReturnType)) { string methodName = $"{ass.GetName().Name}.{type.Name}.{method.Name}()"; try { logger.Info("Calling " + methodName); IEnumerable <string> modsToAdd = (IEnumerable <string>)method.Invoke(null, null); if (modsToAdd == null) { logger.Error("ModuleManagerAddToModList returned null: " + methodName); continue; } foreach (string mod in modsToAdd) { result.Add(new ModAddedByAssembly(mod, ass.GetName().Name)); } } catch (Exception e) { logger.Exception("Exception while calling " + methodName, e); } } } } catch (Exception e) { logger.Exception("Add to mod list threw an exception in loading " + ass.FullName, e); } } foreach (MonoBehaviour obj in UnityEngine.Object.FindObjectsOfType <MonoBehaviour>()) { MethodInfo method = obj.GetType().GetMethod("ModuleManagerAddToModList", BindingFlags.Public | BindingFlags.Instance); if (method != null && method.GetParameters().Length == 0 && typeof(IEnumerable <string>).IsAssignableFrom(method.ReturnType)) { string methodName = $"{obj.GetType().Name}.{method.Name}()"; try { logger.Info("Calling " + methodName); IEnumerable <string> modsToAdd = (IEnumerable <string>)method.Invoke(obj, null); if (modsToAdd == null) { logger.Error("ModuleManagerAddToModList returned null: " + methodName); continue; } foreach (string mod in modsToAdd) { result.Add(new ModAddedByAssembly(mod, obj.GetType().Assembly.GetName().Name)); } } catch (Exception e) { logger.Exception("Exception while calling " + methodName, e); } } } return(result); }