public static bool ValidateVersion(string vStr) { bool valid = true; try { LoadVersionInfo(); } catch (Exception e) { ConsoleUtils.ErrorLn(e.Message); ConsoleUtils.WarnLn("Compilation aborted."); valid = false; } if (valid) { Match m = _versionRegex.Match(vStr); valid = m.Success; if (valid) { int main = Convert.ToInt32(m.Groups[1].Value); valid = _versions.ContainsKey(main); if (valid) { Dictionary <int, Dictionary <int, int> > sub = _versions[main]; int major = Convert.ToInt32(m.Groups[2].Value); valid = sub.ContainsKey(major); if (valid) { if (m.Groups.Count == 4) { Dictionary <int, int> sub2 = sub[major]; int minor = Convert.ToInt32(m.Groups[3].Value); valid = sub2.ContainsKey(minor); if (!valid) { ConsoleUtils.ErrorLn("v" + vStr + " no such minor version exists - compilation aborted."); } } } else { ConsoleUtils.ErrorLn("v" + vStr + " no such major version exists - compilation aborted."); } } else { ConsoleUtils.ErrorLn("v" + vStr + " no such main version exists - compilation aborted."); } } else { ConsoleUtils.ErrorLn("v" + vStr + " is not a valid version string - compilation aborted."); } } return(valid); }
public static bool Load(string id, bool isName, OrderedDictionary <string, Mod> mods) { bool keepOpen = true; try { string modFile = id + Mod.DefinitionExtension; bool valid = true; if (isName) { Console.WriteLine("Searching for mod..."); id = id.ToLower(); var candidates = new Dictionary <string, (string File, int Index)>(); foreach (string file in Directory.GetFiles(Mod.DefinitionFolder)) { string f2 = Mod.ResolvePath(file); if (new FileInfo(f2).Extension == Mod.DefinitionExtension) { string name = Mod.FindName(f2); if (name != null) { int index = name.ToLower().IndexOf(id); if (index > -1) { candidates.Add(name, (File: f2, Index: index)); } } } } if (candidates.Count > 1) { Console.WriteLine("Found " + candidates.Count + " candidate mods."); Console.WriteLine(""); var names = new List <KeyValuePair <string, (string File, int Index)> >(candidates); names.Sort((a, b) => a.Value.Index - b.Value.Index); int i = 1; foreach (KeyValuePair <string, (string, int)> name in names) { Console.WriteLine(i + ". " + name.Key); i++; } Console.WriteLine(""); Console.Write("Input number corresponding to the mod you wish to load, or type \"exit\" to abort this load: "); bool reading = true; int n = -1; var ordinalRegex = new Regex(@"^\d+$"); do { string line = Console.ReadLine(); if (line != null) { line = line.Trim(); if (line == "exit") { Console.WriteLine(""); Console.WriteLine("Aborting load."); reading = false; valid = false; } else { Match m = ordinalRegex.Match(line); if (m.Success) { n = Convert.ToInt32(line); if (n >= 1 && n <= names.Count) { reading = false; } else { ConsoleUtils.Warn("Invalid argument. Please specify a number in the range [1, " + names.Count + "] or \"exit\": "); } } else { ConsoleUtils.Warn("Invalid argument. Please specify a number or \"exit\": "); } } } else { // Ctrl-C reading = false; valid = false; keepOpen = false; } } while (reading); if (valid && n > 0) { n--; Console.WriteLine(""); Console.WriteLine("Selected mod \"" + names[n].Key + "\"."); modFile = candidates[names[n].Key].File; } } else if (candidates.Count == 1) { Console.Write("Are you searching for \"" + candidates.First().Key + "\"? (y/n): "); bool reading = true; bool found = false; do { string line = Console.ReadLine(); if (line != null) { line = line.Trim().ToLower(); switch (line) { case "y": case "yes": reading = false; found = true; break; case "n": case "no": reading = false; break; default: ConsoleUtils.Warn("Invalid argument. Please specify y/n: "); break; } } else { // Ctrl-C reading = false; valid = false; keepOpen = false; } } while (reading); Console.WriteLine(""); if (found) { Console.WriteLine("Found mod."); modFile = candidates.First().Value.File; } else { ConsoleUtils.WarnLn("Incorrect mod and no alternatives available; aborting load."); valid = false; } } else { ConsoleUtils.ErrorLn("Found zero candidate mods."); valid = false; } if (valid) { modFile = Mod.ResolvePath(modFile); } } else { if (!modFile.EndsWith(Mod.DefinitionExtension)) { modFile += Mod.DefinitionExtension; } modFile = Mod.ResolvePath(modFile); Console.WriteLine("Attempting load of mod \"" + modFile + "\"..."); } if (valid) { if (mods.ContainsKey(modFile)) { ConsoleUtils.WarnLn("Redundant load: That mod has already been loaded."); } else { mods.Add(modFile, new Mod(modFile)); Console.WriteLine("Mod loaded."); } } } catch (Exception e) { ConsoleUtils.ErrorLn(e.Message); ConsoleUtils.ErrorLn("Mod has not been loaded."); } return(keepOpen); }
public static bool Compile(OrderedDictionary <string, Mod> mods, string targetVersion, bool clear) { bool keepOpen = true; if (mods.Count > 0) { bool valid = true; try { LoadVersionInfo(); } catch (Exception e) { ConsoleUtils.ErrorLn(e.Message); ConsoleUtils.WarnLn("Compilation aborted."); valid = false; } if (valid) { int i = 0; List <OrderedMod> mods2 = mods.Select(x => new OrderedMod(x.Value, i++)).ToList(); mods2.Sort((a, b) => { int res = VersionCompare(a.Mod.Version, b.Mod.Version); return(res != 0 ? res : a.Position.CompareTo(b.Position)); }); int[] vTarget = Mod.GetConcreteVersion(targetVersion); int[] currentVersion = mods2[0].Mod.Version; Repository repo = GitSetUp(mods2[0].Mod); foreach (OrderedMod mod in mods2) { if (VersionCompare(mod.Mod.Version, vTarget) > 0) { ConsoleUtils.WarnLn("Mod \"" + mod.Mod.Name + "\" is targeting a newer version of Stellaris then compilation is targeting."); ConsoleUtils.WarnLn("(Mod needs " + mod.Mod.VersionString + " but compilation is targeting " + targetVersion + ")."); ConsoleUtils.WarnLn("Skipping mod..."); } else { int cmp = VersionCompare(mod.Mod.Version, currentVersion); if (cmp > 0) { ChangeCoreVersion(currentVersion, mod.Mod); currentVersion = mod.Mod.Version; } ApplyMod(mod.Mod); } } string outDir = TearDownGit(repo); // int[] version = GetConcreteVersion(targetVersion); //string vStr = GetVersionString(version); //Console.WriteLine("Compiling against Stellaris " + vStr + "..."); //string gameFiles = GetGameFiles(version, "$CORE " + vStr, out valid); if (valid) { /* * var usedLines = new Dictionary<string, Dictionary<int, Mod>>(); * foreach (KeyValuePair<string, Mod> kvp in mods) { * Mod mod = kvp.Value; * //int[] modV = GetConcreteVersion(mod.Version); * //string modVStr = GetVersionString(modV); * bool compileThis = true; * if (vStr == modVStr) { * List<string> conflicts = GetConflicts(gameFiles, mod); * ConsoleUtils.WarnLn("Compilation is targeting " + vStr + " but mod \"" + mod.Name + "\" is targeting " + modVStr + "."); * if (conflicts.Count > 0) { * ConsoleUtils.WarnLn("Vanilla files have been overridden - compiling this mod may lead to an unstable end product."); * ConsoleUtils.WarnLn("List of overridden files:"); * foreach (string file in conflicts) { * ConsoleUtils.WarnLn(" " + file); * } * } else { * ConsoleUtils.WarnLn("No vanilla files have been overriden, but features used by the mod may have changed between versions."); * } * ConsoleUtils.Warn("Do you want to compile this mod? (y/n): "); * bool reading = true; * do { * string line = Console.ReadLine(); * if (line != null) { * line = line.Trim().ToLower(); * switch (line) { * case "y": * case "yes": * compileThis = true; * reading = false; * break; * case "n": * case "no": * compileThis = false; * reading = false; * break; * default: * ConsoleUtils.Warn("Invalid argument. Please specify y/n: "); * break; * } * } else { * reading = false; * valid = false; * keepOpen = false; * } * } while (reading); * Console.WriteLine(); * } * if (valid) { * if (compileThis) { * Console.WriteLine("Compiling \"" + ResolveName(mod.Name) + "\"..."); * ModDiffer.ApplyDiff(gameFiles, mod, usedLines); * } else { * Console.WriteLine("Skipping mod..."); * } * } * } * if (valid) { * if (clear) { * mods.Clear(); * } * } */ } } } else { ConsoleUtils.ErrorLn("No mods have been loaded - compilation aborted."); } return(keepOpen); }
public static void Main(string[] args) { var mods = new OrderedDictionary <string, Mod>(); SetConsoleCtrlHandler(eventType => { ClearTemp(); return(false); }, true); if (Directory.Exists(Globals.TempFolder)) { ClearTemp(); } else { Directory.CreateDirectory(Globals.TempFolder); } bool keepOpen = true; do { Console.Write("StellarisModMerge> "); string cmdStr = Console.ReadLine(); if (cmdStr != null) { try { var cmd = new ShellLikeCommand(cmdStr); if (cmd.Args.Count > 0) { Console.WriteLine(""); ShellLikeCommand.Arg arg0 = cmd.Args[0]; bool valid; switch (arg0.Text) { case "load": if (cmd.Args.Count > 3) { ConsoleUtils.ErrorLn("Command \"load\" doesn't take more than 2 arguments."); } else if (cmd.Args.Count == 1) { ConsoleUtils.ErrorLn("Command\"load\" no mod ID or search string specified."); } else { string id = null; bool isName = false; ShellLikeCommand.Arg arg1 = cmd.Args[1]; bool req3Args = false; valid = true; if (arg1.Type == ShellLikeCommand.ArgType.Switch) { if (arg1.Text == "s") { isName = true; req3Args = true; } else { ConsoleUtils.ErrorLn("Command \"load\" unknown switch " + arg1 + "."); valid = false; } } else { id = arg1.Text; } if (valid) { if (cmd.Args.Count == 3) { ShellLikeCommand.Arg arg2 = cmd.Args[2]; if (arg2.Type == ShellLikeCommand.ArgType.Text) { if (id != null) { ConsoleUtils.ErrorLn("Command \"load\" unknown 2nd argument: " + arg2 + "."); valid = false; } else { id = arg2.Text; } } else if (id == null) { ConsoleUtils.ErrorLn("Command \"load\" no mod ID or search string specified."); valid = false; } else if (arg2.Text == "s") { isName = true; } else { ConsoleUtils.ErrorLn("Command \"load\" unknown switch " + arg2 + "."); valid = false; } } else if (req3Args) { ConsoleUtils.ErrorLn("Command \"load\" no mod ID or search string specified."); valid = false; } } if (valid) { keepOpen = ModLoader.Load(id, isName, mods); } } break; case "compile": // TODO: Allow version specifier if (cmd.Args.Count > 3) { ConsoleUtils.ErrorLn("Command \"compile\" doesn't take more than 2 arguments."); } else { valid = true; string version = ""; try { version = ModCompiler.LatestVersion; } catch (Exception e) { ConsoleUtils.ErrorLn(e.Message); ConsoleUtils.WarnLn("Compilation aborted."); valid = false; } if (valid) { bool clear = false; bool expectVersion = false; for (int i = 1; valid && i < cmd.Args.Count; i++) { ShellLikeCommand.Arg arg = cmd.Args[i]; if (expectVersion) { if (arg.Type == ShellLikeCommand.ArgType.Text) { version = arg.Text.ToLower(); if (version.StartsWith("v")) { version = version.Substring(1); } expectVersion = false; } else { valid = false; } } else if (arg.Type == ShellLikeCommand.ArgType.Switch) { if (arg.Text == "c") { clear = true; } else if (arg.Text == "v") { expectVersion = true; } } else { ConsoleUtils.ErrorLn("Command \"compile\" unexpected text argument: " + arg + "."); valid = false; } } if (expectVersion) { ConsoleUtils.ErrorLn("Version not specified after -v switch - compilation aborted."); valid = false; } if (valid) { if (ModCompiler.ValidateVersion(version)) { keepOpen = ModCompiler.Compile(mods, version, clear); } } } } break; case "clear": if (cmd.Args.Count > 1) { ConsoleUtils.ErrorLn("Command \"clear\" doesn't take any arguments."); } else { mods.Clear(); Console.WriteLine("Unloaded all mods."); } break; case "list": valid = true; bool showFileName = false; bool showTargetVersion = false; for (int i = 1; valid && i < cmd.Args.Count; i++) { ShellLikeCommand.Arg arg = cmd.Args[i]; if (arg.Type == ShellLikeCommand.ArgType.Text) { ConsoleUtils.ErrorLn("Command \"list\" doesn't take any text arguments."); valid = false; } else { switch (arg.Text) { case "f": if (showFileName) { ConsoleUtils.ErrorLn("Command \"list\" duplicate switch " + arg + "."); valid = false; } else { showFileName = true; } break; case "v": if (showTargetVersion) { ConsoleUtils.ErrorLn("Command \"list\" duplicate switch " + arg + "."); valid = false; } else { showTargetVersion = true; } break; default: ConsoleUtils.ErrorLn("Command \"list\" unknown switch " + arg + "."); valid = false; break; } } } if (valid) { if (mods.Count > 0) { var ids = new string[mods.Count]; var names = new string[mods.Count]; var versions = new string[mods.Count]; int i = 0; foreach (KeyValuePair <string, Mod> kvp in mods) { ids[i] = new FileInfo(kvp.Value.ModFile).Name; names[i] = kvp.Value.Name ?? "$NONAME"; versions[i] = kvp.Value.VersionString; i++; } const string idHead = "MOD FILE"; const string nameHead = "MOD NAME"; const string versionHead = "GAME VERSION"; int idLength = Math.Max(idHead.Length, ids.Max(id => id.Length)); int nameLength = Math.Max(nameHead.Length, names.Max(name => name.Length)); int versionLength = Math.Max(versionHead.Length, versions.Max(version => version.Length)); int sumLength = nameLength; if (showFileName) { Console.Write(PadStr(idHead, idLength) + " | "); sumLength += idLength + 3; } Console.Write(PadStr(nameHead, nameLength)); if (showTargetVersion) { Console.Write(" | " + PadStr(versionHead, versionLength)); sumLength += versionLength + 3; } Console.WriteLine(); for (i = 0; i < sumLength; i++) { Console.Write('-'); } Console.WriteLine(); for (i = 0; i < ids.Length; i++) { if (showFileName) { Console.Write(PadStr(ids[i], idLength) + " | "); } Console.Write(PadStr(names[i], nameLength)); if (showTargetVersion) { Console.Write(" | " + PadStr(versions[i], versionLength)); } Console.WriteLine(); } } else { Console.WriteLine("No mods have been loaded."); } } break; case "exit": if (cmd.Args.Count > 1) { ConsoleUtils.ErrorLn("Command \"exit\" doesn't take any arguments."); } else { keepOpen = false; } break; case "help": if (cmd.Args.Count > 1) { ConsoleUtils.ErrorLn("Command \"help\" doesn't take any arguments."); } else { Console.WriteLine("## LIST OF COMMANDS ##"); Console.WriteLine(""); Console.WriteLine("load => Load a mod into the system. The order this command is called in defines load order - later mods will override older mods."); Console.WriteLine(" -s: Specifies that arg1 is a mod name search string."); Console.WriteLine(" arg1: The mod to load (file name if -s is not present, search string if it is)."); Console.WriteLine(""); Console.WriteLine("compile => Compiles all loaded mods into one super-mod."); Console.WriteLine(" -c: Clears all loaded mods when compilation is done."); Console.WriteLine(""); Console.WriteLine("exit => Exits the program."); Console.WriteLine(""); Console.WriteLine("clear => Clears all loaded mods."); Console.WriteLine(""); Console.WriteLine("help => This command."); } break; default: ConsoleUtils.WarnLn("Unknown command \"" + arg0.Text + "\". Type \"help\" for a list of commands."); break; } Console.WriteLine(""); } } catch (ArgumentException e) { Console.WriteLine(""); ConsoleUtils.ErrorLn("Invalid command: " + e.Message); Console.WriteLine(""); } } else { // Ctrl-C keepOpen = false; } } while (keepOpen); ClearTemp(); }