private static int unpatchModpack(string modpackname) { try { modpackCfg modpackConfig = getModpackConfig(modpackname); using (ZipArchive archive = ZipFile.OpenRead(Config.modpack_dir + @"\" + modpackname + ".zip")) { if (modpackConfig == null) { form1.showMsg("Could not unpatch '" + modpackname + "' because the modpack's configuration is corrupted or missing." + "\r\nPlease restore from backups using the Backups tab or verify integrity of game files on Steam.", "Error"); return(2); } List <modpackEntry> restored = new List <modpackEntry>(); // track restored files in case of failure mid unpatch foreach (modpackEntry entry in modpackConfig.entries) { if (String.IsNullOrEmpty(entry.type) || entry.type == "replace" || entry.type == "patch") // assume replace type entry if null { if (!Backups.restoreBak(expandPath(entry.dest))) { // repatch restored mod files foreach (modpackEntry e in restored) { int r = patchFile(archive, e); if (r == 2 || r == 3) { form1.showMsg("Critical error encountered while unpatching '" + modpackname + "'." + "\r\nYou may need to verify your game files on steam or reinstall.", "Error"); } } return(2); } } else if (entry.type == "create") { if (!IO.DeleteFile(expandPath(entry.dest))) { form1.showMsg("Could not delete the file '" + expandPath(entry.dest) + "'. This may affect your game. " + "if you encounter issue please delete this file manually.", "Warning"); } } else { form1.showMsg("Unknown modfile type in modpack config.\r\nCould not install the '" + modpackname + "' modpack.", "Error"); } restored.Add(entry); } } } catch (FileNotFoundException) { form1.showMsg("Could not unpatch '" + modpackname + "'. Could not find the modpack file to read the config from.", "Error"); return(2); } catch (InvalidDataException) { form1.showMsg("Could not unpatch '" + modpackname + "'. The modpack file appears corrupted and the config cannot be read.", "Error"); return(2); } return(0); }
public static bool loadModpacks() { ensureModpackFolderExists(); form1.modListPanel_clear(); string[] fileEntries = Directory.GetFiles(Config.modpack_dir); foreach (string file in fileEntries) { string modpackName = Path.GetFileName(file).Replace(".zip", ""); modpackCfg modpackConfig = getModpackConfig(modpackName); if (modpackConfig != null) { form1.modListPanel_add(modpackName, modpackConfig.MCC_version == Config.getCurrentBuild()); } } return(true); }
private static List <string> filterNeededBackups(List <string> paths) { List <string> requiredBaks = new List <string>(); foreach (string enabledModpack in Config.getEnabledModpacks()) { modpackCfg modpackConfig = Modpacks.getModpackConfig(enabledModpack); foreach (modpackEntry entry in modpackConfig.entries) { foreach (string path in paths) { if (path == Modpacks.expandPath(entry.dest)) { requiredBaks.Add(path); } } } } return(requiredBaks); }
public static bool addPatched(string modpackName) { Dictionary <string, string> modfiles = new Dictionary <string, string>(); modpackCfg mCfg = Modpacks.getModpackConfig(modpackName); using (ZipArchive archive = ZipFile.OpenRead(Config.modpack_dir + @"\" + modpackName + ".zip")) { if (mCfg == null) { form1.showMsg("Cannot set state to enabled. The file '" + modpackName + ".zip' is either not a compatible modpack or the config is corrupted.", "Error"); return(false); } List <string> patched = new List <string>(); // track patched files in case of failure mid patch foreach (modpackEntry entry in mCfg.entries) { modfiles[entry.dest] = Modpacks.getMD5(Modpacks.expandPath(entry.dest)); } } patched[modpackName] = modfiles; return(true); }
private static string willOverwriteOtherMod(string modpack) { modpackCfg primaryConfig = getModpackConfig(modpack); foreach (string enabledModpack in Config.getEnabledModpacks()) { modpackCfg modpackConfig = getModpackConfig(enabledModpack); // Deliberately not checking for null so program throws a stack trace // This should never happen, but if it does I want the user to let me know about it foreach (modpackEntry entry in modpackConfig.entries) { foreach (modpackEntry primary in primaryConfig.entries) { if (entry.dest == primary.dest) { return(enabledModpack); } } } } return(null); }
private static int patchModpack(string modpackname) { string retStr = willOverwriteOtherMod(modpackname); if (!String.IsNullOrEmpty(retStr)) { form1.showMsg("Installing '" + modpackname + "' would overwrite files for '" + retStr + "'. Modpack will be skipped.", "Error"); return(2); } bool baksMade = false; try { modpackCfg modpackConfig = getModpackConfig(modpackname); using (ZipArchive archive = ZipFile.OpenRead(Config.modpack_dir + @"\" + modpackname + ".zip")) { if (modpackConfig == null) { form1.showMsg("The file '" + modpackname + ".zip' is either not a compatible modpack or the config is corrupted." + "\r\nTry using the 'Create Modpack' Tab to convert this mod into a compatible modpack.", "Error"); return(2); } List <string> patched = new List <string>(); // track patched files in case of failure mid patch foreach (modpackEntry entry in modpackConfig.entries) { int r = patchFile(archive, entry); if (r != 0 && r != 1) { string errMsg; if (r == 2) { errMsg = "File Access Exception. If the game is running, exit it and try again."; } else if (r == 3) { errMsg = "This modpack appears to be missing files."; } else // r == 4 { errMsg = "Unknown modfile type in modpack config."; } form1.showMsg(errMsg + "\r\nCould not install the '" + modpackname + "' modpack.", "Error"); if (Backups.restoreBaks(patched) != 0) { form1.showMsg("At least one file restore failed. Your game is likely in an unstable state.", "Warning"); } return(2); } else if (r == 1) { baksMade = true; } patched.Add(expandPath(entry.dest)); } } } catch (FileNotFoundException) { form1.showMsg("Could not find the '" + modpackname + "' modpack.", "Error"); return(2); } catch (InvalidDataException) { form1.showMsg("The modpack '" + modpackname + "' appears corrupted." + "\r\nThis modpack cannot be installed.", "Error"); return(2); } if (baksMade) { return(1); } else { return(0); } }
public static void createModpack(string modpackName, IEnumerable <Panel> modFilesList) { if (modFilesList.Count() == 0) { form1.showMsg("Please add at least one modded file entry", "Error"); return; } if (String.IsNullOrEmpty(modpackName)) { form1.showMsg("Please enter a modpack name", "Error"); return; } List <String> chk = new List <string>(); modpackCfg mCfg = new modpackCfg(); mCfg.MCC_version = IO.readFirstLine(Config.MCC_home + @"\build_tag.txt"); foreach (Panel row in modFilesList) { string srcText = row.GetChildAtPoint(Config.sourceTextBoxPoint).Text; TextBox origTextbox = new TextBox(); // setting this to an empty value to avoid compile error on an impossible CS0165 string destText; if ((string)row.Tag == "normal") { destText = row.GetChildAtPoint(Config.destTextBoxPoint).Text; } else { origTextbox = (TextBox)row.GetChildAtPoint(Config.origTextBoxPoint); destText = row.GetChildAtPoint(Config.destTextBoxPointAlt).Text; } if (string.IsNullOrEmpty(srcText) || string.IsNullOrEmpty(destText) || ((string)row.Tag == "alt" && string.IsNullOrEmpty(origTextbox.Text))) { form1.showMsg("Filepaths cannot be empty.", "Error"); return; } if (!File.Exists(srcText)) { form1.showMsg("The source file '" + srcText + "' does not exist.", "Error"); return; } if (!destText.StartsWith(Config.MCC_home)) { form1.showMsg("Destination files must be located within the MCC install directory. " + "You may need to configure this directory if you haven't done so already.", "Error"); return; } if ((string)row.Tag == "alt" && origTextbox.Enabled && !origTextbox.Text.StartsWith(Config.MCC_home)) { form1.showMsg("Unmodified map files must be selected at their default install location within the MCC install directory to allow the patch " + "to be correctly applied when this modpack is installed. The file you selected does not appear to lie inside the MCC install directory." + "\r\nYou may need to configure this directory if you haven't done so already.", "Error"); return; } string patchType; if (Path.GetExtension(srcText) == ".asmp") { patchType = "patch"; } else { bool isOriginalFile; try { isOriginalFile = IO.isHaloFile(compressPath(destText)); } catch (JsonReaderException) { form1.showMsg(@"MCC Mod Manager could not parse Formats\filetree.json", "Error"); return; } if (isOriginalFile) { patchType = "replace"; } else { patchType = "create"; } } mCfg.entries.Add(new modpackEntry { src = srcText, orig = (patchType == "patch") ? compressPath(origTextbox.Text) : null, dest = compressPath(destText), // make modpack compatable with any MCC_home directory type = patchType }); chk.Add(destText); } if (chk.Distinct().Count() != chk.Count()) { form1.showMsg("You have multiple files trying to write to the same destination.", "Error"); return; } ensureModpackFolderExists(); String modpackFilename = modpackName + ".zip"; String zipPath = Config.modpack_dir + @"\" + modpackFilename; if (File.Exists(zipPath)) { form1.showMsg("A modpack with that name already exists.", "Error"); return; } form1.pBar_show(mCfg.entries.Count()); try { using (var archive = ZipFile.Open(zipPath, ZipArchiveMode.Create)) { foreach (var entry in mCfg.entries) { form1.pBar_update(); String fileName = Path.GetFileName(entry.src); archive.CreateEntryFromFile(entry.src, fileName); // TODO: Fix issues when two source files have same name but diff path entry.src = fileName; // change src path to just modpack after archive creation but before json serialization } ZipArchiveEntry configFile = archive.CreateEntry("modpack_config.cfg"); string json = JsonConvert.SerializeObject(mCfg, Formatting.Indented); using (StreamWriter writer = new StreamWriter(configFile.Open())) { writer.WriteLine(json); } ZipArchiveEntry readmeFile = archive.CreateEntry("README.txt"); using (StreamWriter writer = new StreamWriter(readmeFile.Open())) { writer.WriteLine("Install using MCC Mod Manager: https://github.com/executionByFork/MCC_Mod_Manager/tree/master"); } } } catch (NotSupportedException) { form1.showMsg("The modpack name you have provided is not a valid filename on Windows.", "Error"); return; } form1.showMsg("Modpack '" + modpackFilename + "' created.", "Info"); form1.pBar_hide(); form1.resetCreateModpacksTab(); loadModpacks(); return; }