コード例 #1
0
        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;
        }
コード例 #2
0
        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);
                }
            }
        }
コード例 #3
0
        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);
        }
コード例 #4
0
 public static void Info(this IBasicLogger logger, string message) => logger.Log(LogType.Log, message);
コード例 #5
0
 public PatchProgress(IBasicLogger logger, ProgressCounter counter)
 {
     this.logger  = logger;
     this.Counter = counter;
 }
コード例 #6
0
        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));
                    }
                }
コード例 #7
0
        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();
        }
コード例 #8
0
 public InGameTestRunnerTest()
 {
     logger       = Substitute.For <IBasicLogger>();
     databaseRoot = UrlBuilder.CreateRoot();
     testRunner   = new InGameTestRunner(logger);
 }
コード例 #9
0
 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));
 }
コード例 #10
0
 public void LogTo(IBasicLogger logger)
 {
     logger.Exception(message, exception);
 }
コード例 #11
0
 public PatchContext(UrlDir.UrlConfig patchUrl, IEnumerable <IProtoUrlConfig> databaseConfigs, IBasicLogger logger, IPatchProgress progress)
 {
     this.patchUrl        = patchUrl;
     this.databaseConfigs = databaseConfigs;
     this.logger          = logger;
     this.progress        = progress;
 }
コード例 #12
0
        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);
        }
コード例 #13
0
 public PatchApplier(IPatchProgress progress, IBasicLogger logger)
 {
     this.progress = progress ?? throw new ArgumentNullException(nameof(progress));
     this.logger   = logger ?? throw new ArgumentNullException(nameof(logger));
 }
コード例 #14
0
        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();
            });
        }
コード例 #15
0
        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);
                    }
                }
            }
        }
コード例 #16
0
 public InGameTestRunner(IBasicLogger logger)
 {
     this.logger = logger ?? throw new ArgumentNullException(nameof(logger));
 }
コード例 #17
0
 public PrefixLoggerTest()
 {
     innerLogger = Substitute.For <IBasicLogger>();
     logger      = new PrefixLogger("MyMod", innerLogger);
 }
コード例 #18
0
 public IBasicLoggerExtensionsTest()
 {
     logger = Substitute.For <IBasicLogger>();
 }
コード例 #19
0
 public PatchProgressTest()
 {
     logger   = Substitute.For <IBasicLogger>();
     progress = new PatchProgress(logger);
 }
コード例 #20
0
        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);
        }
コード例 #21
0
ファイル: LogSplitter.cs プロジェクト: ysdavy/ModuleManager
 public LogSplitter(IBasicLogger logger1, IBasicLogger logger2)
 {
     this.logger1 = logger1 ?? throw new ArgumentNullException(nameof(logger1));
     this.logger2 = logger2 ?? throw new ArgumentNullException(nameof(logger2));
 }
コード例 #22
0
        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);
        }
コード例 #23
0
        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));
        }
コード例 #24
0
 public PatchProgress(IBasicLogger logger)
 {
     this.logger = logger;
     Counter     = new ProgressCounter();
 }
コード例 #25
0
 public MMPatchRunner(IBasicLogger kspLogger)
 {
     this.kspLogger = kspLogger ?? throw new ArgumentNullException(nameof(kspLogger));
 }
コード例 #26
0
 public PatchProgress(IPatchProgress progress, IBasicLogger logger)
 {
     this.logger = logger;
     Counter     = progress.Counter;
 }
コード例 #27
0
 public static void Error(this IBasicLogger logger, string message) => logger.Log(LogType.Error, message);
コード例 #28
0
        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);
        }
コード例 #29
0
 public static void Warning(this IBasicLogger logger, string message) => logger.Log(LogType.Warning, message);
コード例 #30
0
        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);
        }