public bool Equals(BundleMod guest) { if (ReferenceEquals(guest, null)) { return(false); } if (ReferenceEquals(this, guest)) { return(true); } return(this == guest); }
/// <summary> /// The markup mods for reinstall /// </summary> private Dictionary<string, List<BundleMod>> markupModCollision(BundleMod newMod, bool reverse = false) { Dictionary<string, BundleMod> modsList = this.mods_db.modsList; Dictionary<string, List<BundleMod>> return_list = new Dictionary<string, List<BundleMod>>(); BundleMod return_item; foreach (BundleMod localmod in modsList.Values) { if (newMod == localmod) continue; if (this.mods_db.InstalledModsListContains(localmod) != -1 && (localmod.actionStatus != BundleMod.ModActionStatus.Remove && localmod.actionStatus != BundleMod.ModActionStatus.ForcedReinstall)) { return_item = new BundleMod(); foreach (BundleRewriteItem bri in newMod.ItemQueue) { foreach (BundleRewriteItem briLocal in localmod.ItemQueue) { if (bri == briLocal) { if (reverse) { bri.toReinstall = false; briLocal.toReinstall = false; bri.toShared = false; briLocal.toShared = false; } else { bri.toReinstall = true; briLocal.toReinstall = true; bri.toShared = true; briLocal.toShared = true; } return_item.ItemQueue.Add(bri); } } } if (localmod.ItemQueue.Any(items => items.toReinstall == true)) localmod.actionStatus = BundleMod.ModActionStatus.Reinstall; else localmod.actionStatus = BundleMod.ModActionStatus.None; if (localmod.actionStatus == BundleMod.ModActionStatus.Reinstall) { return_item.Author = localmod.Author; return_item.Description = localmod.Description; return_item.Name = localmod.Name; foreach (var item in return_item.ItemQueue) { string file_name = ""; file_name += StaticStorage.Known_Index.GetPath(item.BundlePath); if (item.IsLanguageSpecific) file_name += "." + item.BundleLanguage; file_name += "." + StaticStorage.Known_Index.GetExtension(item.BundleExtension); if (return_list.ContainsKey(file_name)) return_list[file_name].Add(return_item); else { List<BundleMod> newModList = new List<BundleMod>(); newModList.Add(newMod); newModList.Add(return_item); return_list.Add(file_name, newModList); } } } } } return return_list; }
/// <summary> /// The load mod. /// </summary> private void LoadMod() { try { using (var zip = new ZipFile(this.modZipFile)) { foreach (ZipEntry entry in zip.Entries) { if (entry.UsesEncryption) { entry.Password = "******"; //entry.Encryption = EncryptionAlgorithm.WinZipAes256; } if (entry.FileName == "pdmod.json") { var ms = new MemoryStream(); entry.Extract(ms); ms.Seek(0, SeekOrigin.Begin); this.currentMod = BundleMod.Deserialize(ms); if (this.currentMod.Version > Version) throw new Exception("This mod is not compatible with your Bundle Modder. Please update your Bundle Modder to the latest version. (" + this.currentMod.Version + ")"); this.ModNameText.Text = this.currentMod.Name; this.AuthorText.Text = this.currentMod.Author; this.DescriptionText.Text = this.currentMod.Description; this.ApplyButton.Enabled = true; } } } } catch (Exception e) { this.ModNameText.Text = "Failed to load mod."; this.DescriptionText.Text = e.Message; } }
private void createModLoad_Click(object sender, EventArgs e) { var openDialog = new OpenFileDialog(); openDialog.Filter = "PAYDAY Mod Project|*.*"; openDialog.CheckFileExists = true; if (openDialog.ShowDialog() != DialogResult.OK) { return; } this.newMod = new BundleMod(); this.modScriptPath = Path.GetDirectoryName(openDialog.FileName); try { ParseModScript(openDialog.FileName); } catch (Exception exc) { System.Windows.Forms.MessageBox.Show(exc.Message, "Mod Script Error", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error); } this.AddedFilesView.DataSource = this.newMod.ItemQueue.ToList(); this.AddedFilesView.Refresh(); }
private void availiableMods_listView_MouseClick(object sender, MouseEventArgs e) { ListView listView = sender as ListView; if (e.Button == System.Windows.Forms.MouseButtons.Right) { ListViewItem item = listView.GetItemAt(e.X, e.Y); if (item != null) { this._rightclickedMod = (BundleMod)item.Tag; item.Selected = true; modContextMenuStrip.Show(listView, e.Location); } } }
private void availableMods_listView_SelectedIndexChanged(object sender, EventArgs e) { if (availiableMods_listView.SelectedItems.Count == 1) { this._selectedMod = (BundleMod)availiableMods_listView.SelectedItems[0].Tag; this.ModNameText.Text = this._selectedMod.Name; this.AuthorText.Text = this._selectedMod.Author; this.DescriptionText.Text = this._selectedMod.Description; this.moreModDetails_button.Enabled = true; this.availiableMods_listView.SelectedItems[0].Focused = false; this.availiableMods_listView.SelectedItems[0].Selected = false; this.availiableMods_listView.Update(); } }
/// <summary> /// The serialize. /// </summary> /// <param name="mod"> /// The mod. /// </param> /// <returns> /// The <see cref="string"/>. /// </returns> public static string Serialize(BundleMod mod) { return(JsonConvert.SerializeObject(mod, Formatting.Indented)); }
/// <summary> /// The apply button_ click. /// </summary> /// <param name="sender"> /// The sender. /// </param> /// <param name="e"> /// The e. /// </param> private void ApplyButtonClick(object sender, EventArgs e) { if (!String.IsNullOrEmpty(StaticStorage.settings.GameProcess)) { Process[] pname = Process.GetProcessesByName(StaticStorage.settings.GameProcess); if (pname.Length != 0) { MessageBox.Show(StaticStorage.settings.Game + " is currently running, cannot patch.\nPlease close the game before applying mods."); return; } } if (!this.TestAssetsFolder()) { MessageBox.Show("Your assets folder appears to be invalid. Please select a valid assets folder in Options.", "Invalid assets folder."); return; } if (this.rewriter != null) return; if (this.ExtractTimer != null) { if (this.ExtractTimer.Enabled) { MessageBox.Show("Cannot perform 2 actions at once"); return; } } this.TotalProgressLabel.Text = "Preparing to Apply Changes"; this.savedStateApplyMod = this.ApplyButton.Enabled; this.savedStateOpenMod = this.OpenModButton.Enabled; this.savedStateRefreshButton = this.refreshButton.Enabled; this.savedStateFileControlButton = this.filecontrol_button.Enabled; this.availiableMods_listView.Enabled = false; this.availiableModsSearch_textbox.Enabled = false; this.ApplyButton.Enabled = false; this.OpenModButton.Enabled = false; this.refreshButton.Enabled = false; this.filecontrol_button.Enabled = false; this.ExtraOptions1.Enabled = false; List<BundleMod> uninstall = new List<BundleMod>(); List<BundleMod> reinstall = new List<BundleMod>(); List<BundleMod> install = new List<BundleMod>(); List<BundleMod> install_combo = new List<BundleMod>(); Queue<BundleRewriteItem> mix_bri = new Queue<BundleRewriteItem>(); BundleMod mix = new BundleMod(); // 0 = Nothing, 1 = Marked for install (limegreen), 2 = Marked for removal (red), 3 = Marked for reinstallation (yellow), 4 = Dictionary<string, BundleMod> modsList = this.mods_db.modsList; install = modsList.Values.Where(mod => mod.actionStatus == BundleMod.ModActionStatus.Install).ToList(); reinstall = modsList.Values.Where(mod => mod.actionStatus == BundleMod.ModActionStatus.Reinstall || mod.actionStatus == BundleMod.ModActionStatus.ForcedReinstall).ToList(); uninstall = modsList.Values.Where(mod => mod.actionStatus == BundleMod.ModActionStatus.Remove).ToList(); //Perform other actions //Generate install/reinstall/uninstall mods if (uninstall.Count > 0) { //Generate Bundle Mod foreach (BundleMod uninstMod in uninstall) { if (uninstMod.type == BundleMod.ModType.lua) { Directory.Delete(uninstMod.file, true); } else { foreach (BundleRewriteItem bri in uninstMod.ItemQueue) { if (uninstMod.type == BundleMod.ModType.mod_override) { if (bri.isOverrideable() //&& !bri.ReplacementFile.EndsWith(".script") ) { if (!string.IsNullOrEmpty(StaticStorage.Known_Index.GetPath(bri.BundlePath)) && !string.IsNullOrEmpty(StaticStorage.Known_Index.GetExtension(bri.BundleExtension))) { string extrname = ""; extrname += StaticStorage.Known_Index.GetPath(bri.BundlePath); extrname += "." + StaticStorage.Known_Index.GetExtension(bri.BundleExtension); string modName = bri.ModName; modName = Path.GetInvalidFileNameChars().Aggregate(modName, (current, c) => current.Replace(c.ToString(), "_")); if (File.Exists(Path.Combine(StaticStorage.settings.AssetsFolder, "mod_overrides", modName))) { if (File.Exists(Path.Combine(StaticStorage.settings.AssetsFolder, "mod_overrides", modName, extrname))) { File.Delete(Path.Combine(StaticStorage.settings.AssetsFolder, "mod_overrides", modName, extrname)); DeleteEmptyDirs(Path.Combine(StaticStorage.settings.AssetsFolder, "mod_overrides", modName)); } } } } } else { if (!mix_bri.Contains(bri)) { BundleRewriteItem newBri = bri; newBri.toRemove = true; mix_bri.Enqueue(newBri); } } } if (File.Exists(Path.Combine(StaticStorage.settings.AssetsFolder, "mod_overrides", uninstMod.getEscapedName(), "mod.txt"))) { File.Delete(Path.Combine(StaticStorage.settings.AssetsFolder, "mod_overrides", uninstMod.getEscapedName(), "mod.txt")); } } } } if (reinstall.Count > 0) { //Generate Bundle Mod foreach (BundleMod bm in reinstall) { foreach (BundleRewriteItem bri in bm.ItemQueue) { if (!bri.ReplacementFile.EndsWith(".script") && filecontrolSelectedDictionary.ContainsKey(bri.getBundleEntryPath())) { if (filecontrolSelectedDictionary[bri.getBundleEntryPath()] != bm.Name) { BundleRewriteItem newBri = bri; newBri.toRemove = true; mix_bri.Enqueue(newBri); continue; } } if (bri.toReinstall && !mix_bri.Contains(bri)) { BundleRewriteItem newBri = bri; newBri.toRemove = false; mix_bri.Enqueue(newBri); } } if (bm.UtilizesOverride) { if (File.Exists(Path.Combine(StaticStorage.settings.AssetsFolder, "mod_overrides", bm.getEscapedName())) && File.Exists(Path.Combine(StaticStorage.settings.AssetsFolder, "mod_overrides", bm.getEscapedName(), "mod.txt"))) { using (StreamWriter modsw = File.CreateText(Path.Combine(StaticStorage.settings.AssetsFolder, "mod_overrides", bm.getEscapedName(), "mod.txt"))) { modsw.Write(OverrideMod.Serialize(new OverrideMod(bm.Name, bm.Author, bm.Description))); } } } } } if (install.Count > 0) { //Generate Bundle Mod foreach (BundleMod bm in install) { foreach (BundleRewriteItem bri in bm.ItemQueue) { if (!bri.ReplacementFile.EndsWith(".script") && filecontrolSelectedDictionary.ContainsKey(bri.getBundleEntryPath())) { if (filecontrolSelectedDictionary[bri.getBundleEntryPath()] != bm.Name) continue; } if (!mix_bri.Contains(bri)) { BundleRewriteItem newBri = bri; newBri.toRemove = false; mix_bri.Enqueue(newBri); } } if (bm.UtilizesOverride) { if (!Directory.Exists(Path.Combine(StaticStorage.settings.AssetsFolder, "mod_overrides", bm.getEscapedName()))) Directory.CreateDirectory(Path.Combine(StaticStorage.settings.AssetsFolder, "mod_overrides", bm.getEscapedName())); using (StreamWriter modsw = File.CreateText(Path.Combine(StaticStorage.settings.AssetsFolder, "mod_overrides", bm.getEscapedName(), "mod.txt"))) { modsw.Write(OverrideMod.Serialize(new OverrideMod(bm.Name, bm.Author, bm.Description))); } } } } install_combo.AddRange(install); install_combo.AddRange(reinstall); mix.ItemQueue = new HashSet<BundleRewriteItem>(mix_bri.ToList()); int BufferSize; if (!Int32.TryParse(this.patchingBufferSize.Text, out BufferSize)) { BufferSize = 4096; } this.rewriter = new BundleRewriter( "", mix, BufferSize, StaticStorage.settings.AssetsFolder, StaticStorage.settings.BackupType, StaticStorage.settings.OverrideFolder, StaticStorage.settings.OverrideFolderDummies, StaticStorage.settings.OverrideFolderShared, true, false); this.progressTimer = new Timer(); this.progressTimer.Interval = 500; this.progressTimer.Tick += this.MultiProgressTimerElapsed; this.progressTimer.Enabled = true; this.progressTimer.Start(); rewriterThread = new Thread(() => this.rewriter.ApplyChanges(install_combo.ToArray(), false)); rewriterThread.IsBackground = true; rewriterThread.Start(); }
/// <summary> /// The apply changes. /// </summary> public void ApplyChanges(BundleMod[] toAddModsList, bool method) { this.Done = false; using (this.Zip = new ZipFile(this._zipPath)) { bool wasSuccessful = false; this._mod.ItemQueue.RemoveWhere(i => i.BundleExtension == 0xAB2664BF82E646UL); this._mod.ItemQueue.RemoveWhere(i => i.BundleExtension == 0xAB2664BF82E6460C); this._mod.ItemQueue.RemoveWhere(i => i.BundleExtension == 0x29104BC4AC649965); if (!this.LocateChangeIds()) return; var toRemove = this._mod.ItemQueue.Where(p => p.toRemove); //var toReinstall = this._mod.ItemQueue.Where(p => p.toReinstall); var toInstall = this._mod.ItemQueue.Where(p => !p.toRemove); if (this._overrideFolder) { this.SetTotalProgress("Utilizing Override Folder", -1); HashSet<BundleEntryPath> toSharedFolder = new HashSet<BundleEntryPath>(); HashSet<BundleEntryPath> overrideApplied = new HashSet<BundleEntryPath>(); Dictionary<BundleEntryPath, HashSet<BundleRewriteItem>> bep_sorted = new Dictionary<BundleEntryPath, HashSet<BundleRewriteItem>>(); foreach (BundleRewriteItem bri in this._mod.ItemQueue) { if (bri.toRemove) continue; if (bep_sorted.ContainsKey(bri.getBundleEntryPath())) { if (this._overrideFolderShared && !toSharedFolder.Contains(bri.getBundleEntryPath())) toSharedFolder.Add(bri.getBundleEntryPath()); bep_sorted[bri.getBundleEntryPath()].Add(bri); } else { HashSet<BundleRewriteItem> newbrihs = new HashSet<BundleRewriteItem>(); newbrihs.Add(bri); bep_sorted.Add(bri.getBundleEntryPath(), newbrihs); } } HashSet<BundleRewriteItem> reducedItemQueue = new HashSet<BundleRewriteItem>(); int override_count = 1; foreach (BundleRewriteItem bri in this._mod.ItemQueue) { this.SetBundleProgress( string.Format("Processing {0}/{1}", override_count, this._mod.ItemQueue.Count), (int)((override_count / (float)this._mod.ItemQueue.Count) * 100.0f)); if (bri.isOverrideable() //&& !bri.ReplacementFile.EndsWith(".script") ) { if (!string.IsNullOrEmpty(StaticStorage.Known_Index.GetPath(bri.BundlePath)) && !string.IsNullOrEmpty(StaticStorage.Known_Index.GetExtension(bri.BundleExtension)) ) { string extrname = ""; extrname += StaticStorage.Known_Index.GetPath(bri.BundlePath); extrname += "." + StaticStorage.Known_Index.GetExtension(bri.BundleExtension); string modName = bri.getEscapedName(); if (bri.toRemove) { if (!toSharedFolder.Contains(bri.getBundleEntryPath()) && File.Exists(Path.Combine(this._assetFolder, "mod_overrides", "Bundle_Modder_Shared", extrname))) File.Delete(Path.Combine(this._assetFolder, "mod_overrides", "Bundle_Modder_Shared", extrname)); else if (File.Exists(Path.Combine(this._assetFolder, "mod_overrides", modName, extrname))) File.Delete(Path.Combine(this._assetFolder, "mod_overrides", modName, extrname)); DeleteEmptyDirs(Path.Combine(this._assetFolder, "mod_overrides", modName)); } else { if (bri.toReinstall) { if (File.Exists(Path.Combine(this._assetFolder, "mod_overrides", modName, extrname))) File.Delete(Path.Combine(this._assetFolder, "mod_overrides", modName, extrname)); } String path; if (this._overrideFolderShared && toSharedFolder.Contains(bri.getBundleEntryPath())) path = Path.Combine(this._assetFolder, "mod_overrides", "Bundle_Modder_Shared", extrname); else path = Path.Combine(this._assetFolder, "mod_overrides", modName, extrname); if (!Directory.Exists(Path.GetDirectoryName(path))) Directory.CreateDirectory(Path.GetDirectoryName(path)); HashSet<BundleRewriteItem> bep_items = new HashSet<BundleRewriteItem>(); if (bep_sorted.ContainsKey(bri.getBundleEntryPath())) bep_items = bep_sorted[bri.getBundleEntryPath()]; var outOverride = new FileStream( path, FileMode.Create, FileAccess.ReadWrite); int runningcount = 0; foreach (var item in bep_items) { if (item.SourceFile != null) { if(this.Zip == null) this.Zip = new ZipFile(item.SourceFile); if (!this.Zip.Name.Equals(item.SourceFile)) { this.Zip.Dispose(); this.Zip = new ZipFile(item.SourceFile); } } else continue; ZipEntry zip_entry = this.Zip[item.ReplacementFile]; if (zip_entry != null) { if (zip_entry.UsesEncryption) { zip_entry.Password = "******"; //zip_entry.Encryption = EncryptionAlgorithm.WinZipAes256; } MemoryStream zipEntryData = new MemoryStream(); if (item.ReplacementFile.EndsWith(".script")) { MemoryStream scriptData = new MemoryStream(); zip_entry.Extract(scriptData); scriptData.Seek(0, SeekOrigin.Begin); MemoryStream bundleData = new MemoryStream(); if (RetrieveFile(item, out bundleData)) { if (runningcount > 0) { bundleData.SetLength(0); outOverride.Seek(0, SeekOrigin.Begin); outOverride.CopyTo(bundleData); } StreamReader scriptStream = new StreamReader(scriptData); List<BundleRewriteScriptAction> scriptActions = ParseScriptActions(ref scriptStream, zip_entry.FileName); scriptData.Close(); scriptStream.Close(); //apply script functions here bundleData.Seek(0, SeekOrigin.Begin); List<byte> entryBytes = bundleData.ToArray().ToList(); outOverride.Seek(0, SeekOrigin.Begin); ApplyScriptActions(ref entryBytes, ref scriptActions); foreach (byte b in entryBytes) outOverride.WriteByte(b); } else { reducedItemQueue.Add(item); } } else { outOverride.Position = 0L; zipEntryData.Position = 0L; zip_entry.Extract(zipEntryData); zipEntryData.Position = 0L; zipEntryData.CopyTo(outOverride, this.bufferSize); //foreach (byte b in zipEntryData.ToArray().ToList()) // outOverride.WriteByte(b); } outOverride.Flush(); } runningcount++; } outOverride.Close(); } } else { reducedItemQueue.Add(bri); } } else { if (this._overrideFolderDummies) { string modName = bri.ModName; modName = Path.GetInvalidFileNameChars().Aggregate(modName, (current, c) => current.Replace(c.ToString(), "_")); if (bri.toRemove) { if (Directory.Exists(Path.Combine(this._assetFolder, "mod_overrides", modName))) { //Directory.Delete(Path.Combine(this._assetFolder, "mod_overrides", modName), true); DeleteDirectory(Path.Combine(this._assetFolder, "mod_overrides", modName)); } } else { if (!Directory.Exists(Path.Combine(this._assetFolder, "mod_overrides", modName))) Directory.CreateDirectory(Path.Combine(this._assetFolder, "mod_overrides", modName)); } } reducedItemQueue.Add(bri); } override_count++; } this.SetBundleProgress("Done", 100); this._mod.ItemQueue = reducedItemQueue; } HashSet<string> bundles = this.LocateBundlesToRewrite(out wasSuccessful); if (!wasSuccessful) return; if (!this._patchAllBundles) bundles.RemoveWhere(i => i.StartsWith("all_")); if (bundles.Count <= 0 && !this._overrideFolder) { this.Error = "Unable to locate any bundles with the requested items in them.\n" + "If the changed file(s) only exists within an all_x.bundle file you will need to enable the option to patch all_x.bundle files.\n" + "Refer to the patch description for if this is required."; return; } this.SetTotalProgress("Backing up Bundles", -1); this.CurrentBundlesCount = 1; this.TotalBundlesCount = bundles.Count; foreach (var bundle in bundles) { this.SetBundleProgress( string.Format("Backing up Bundle {0}/{1}", this.CurrentBundlesCount, this.TotalBundlesCount), (int)((this.CurrentBundlesCount / (float)this.TotalBundlesCount) * 100.0f)); if (this._backupType == 1) { this.BackupEntries(this._mod, Path.Combine(this._assetFolder, bundle)); } else { this.BackupFile(Path.Combine(this._assetFolder, bundle + "_h.bundle")); this.BackupFile(Path.Combine(this._assetFolder, bundle + ".bundle")); } this.CurrentBundlesCount += 1; } foreach (BundleMod bm in toAddModsList) { BackupEntry multibackupEntry = new BackupEntry(); multibackupEntry.Name = bm.Name; multibackupEntry.Author = bm.Author; multibackupEntry.Description = bm.Description; multibackupEntry.BackupType = (this._backupType == 0) ? "Bundles" : "Bundle Entries"; multibackupEntry.InstallDate = DateTime.Now; multibackupEntry.RewriteAll = this._patchAllBundles; HashSet<BundleRewriteItem> backupQueue = new HashSet<BundleRewriteItem>(); foreach (BundleRewriteItem bri in bm.ItemQueue) { BundleRewriteItem newbri = new BundleRewriteItem(); newbri.BundleExtension = bri.BundleExtension; newbri.BundleLanguage = bri.BundleLanguage; newbri.BundlePath = bri.BundlePath; newbri.Ids = bri.Ids; newbri.IsLanguageSpecific = bri.IsLanguageSpecific; if (this._backupType == 0) newbri.ReplacementFile = bri.ReplacementFile; else newbri.ReplacementFile = bri.BundlePath.ToString("x") + '.' + bri.BundleLanguage.ToString("x") + '.' + bri.BundleExtension.ToString("x"); newbri.SourceFile = bri.SourceFile; backupQueue.Add(newbri); } multibackupEntry.ItemQueue = backupQueue; backupEntries.Add(multibackupEntry); } allowBackup = true; foreach (var rewriteItem in this._mod.ItemQueue) { foreach (var id in rewriteItem.Ids) { if (this._rewriteItems.ContainsKey(id)) { if (rewriteItem.toRemove) this._rewriteItems[id].toRestore = true; if (rewriteItem.ReplacementFile.EndsWith(".script")) { this._rewriteItems[id].BundleRewriteItem_queue.Add(rewriteItem); } else { if (rewriteItem.priority) { this._rewriteItems[id].priorityBundleRewriteItem = rewriteItem; } else { //Don't add... it's not part of priority this._rewriteItems[id].BundleRewriteItem_queue.Add(rewriteItem); } } } else { BundleRewriteEntryID breid = new BundleRewriteEntryID(); if (rewriteItem.toRemove) breid.toRestore = true; if (rewriteItem.ReplacementFile.EndsWith(".script")) { breid.BundleRewriteItem_queue.Add(rewriteItem); } else { if (rewriteItem.priority) { breid.priorityBundleRewriteItem = rewriteItem; } else { //Don't add, it's not part of priority breid.BundleRewriteItem_queue.Add(rewriteItem); } } this._rewriteItems.Add(id, breid); } } } this.CurrentBundlesCount = 1; TotalElapsedTime.Start(); SpeedElapsedTime.Start(); foreach (var bundle in bundles) { CurrentBundle = bundle; this.SetTotalProgress( string.Format("Patching Bundle {0}/{1}", this.CurrentBundlesCount, this.TotalBundlesCount), (int)((this.CurrentBundlesCount / (float)this.TotalBundlesCount) * 100.0f)); if (!this.PatchBundle(bundle)) return; this.CurrentBundlesCount += 1; } TotalElapsedTime.Stop(); SpeedElapsedTime.Stop(); } this.Zip.Dispose(); this.SetTotalProgress("Done", 100); this.Done = true; }
/// <summary> /// Initializes a new instance of the <see cref="BundleRewriter"/> class. /// </summary> /// <param name="zipPath"> /// The zip path. /// </param> /// <param name="mod"> /// The mod. /// </param> /// <param name="assetsPath"> /// The assets path. /// </param> /// <param name="includeAllBundles"> /// The include all bundles. /// </param> /// </param> /// <param name="multiMods"> /// The multiple mod involvement. /// </param> public BundleRewriter(string zipPath, BundleMod mod, int bufferSize, string assetsPath, int backupType, bool overridefolder, bool overridefolderdummies, bool overridefoldershared, bool includeAllBundles, bool multiMods) { this._zipPath = zipPath; this._mod = mod; this.bufferSize = bufferSize; this._assetFolder = assetsPath; this._backupType = backupType; this._overrideFolder = overridefolder; this._overrideFolderDummies = overridefolderdummies; this._overrideFolderShared = overridefolderdummies; this._patchAllBundles = includeAllBundles; this._multiMods = multiMods; }
/// <summary> /// The patch bundle restore. /// </summary> /// <param name="bundleId"> /// The bundle id. /// </param> /// <returns> /// The <see cref="bool"/>. /// </returns> private bool PatchBundleRestore(BundleMod mod, string bundleId, bool method) { if (method) { if (!File.Exists(Path.Combine(this._assetFolder, bundleId + ".bundle")) || !File.Exists(Path.Combine(this._assetFolder, bundleId + "_h.bundle")) || !File.Exists(Path.Combine(this._assetFolder, "asset_backups", bundleId + ".bundle")) || !File.Exists(Path.Combine(this._assetFolder, "asset_backups", bundleId + "_h.bundle"))) return false; File.Delete(Path.Combine(this._assetFolder, bundleId + ".bundle")); File.Delete(Path.Combine(this._assetFolder, bundleId + "_h.bundle")); File.Copy(Path.Combine(this._assetFolder, "asset_backups", bundleId + ".bundle"), Path.Combine(this._assetFolder, bundleId + ".bundle"), true); File.Copy(Path.Combine(this._assetFolder, "asset_backups", bundleId + "_h.bundle"), Path.Combine(this._assetFolder, bundleId + "_h.bundle"), true); this.SetBundleProgress("Done", 100); return true; } var inHeader = new BundleHeader(); var inRestoreHeader = new BundleHeader(); Dictionary<uint, BundleEntry> inRestoreDictionary = new Dictionary<uint, BundleEntry>(); if (!inHeader.Load(Path.Combine(this._assetFolder, bundleId))) { return false; } if (!inRestoreHeader.Load(Path.Combine(this._assetFolder, "asset_backups", bundleId))) return false; foreach (BundleEntry entry in inRestoreHeader.Entries) { if (!inRestoreDictionary.ContainsKey(entry.Id)) inRestoreDictionary.Add(entry.Id, entry); } var outHeader = new BundleHeader(); outHeader.Footer = inHeader.Footer; outHeader.Header = inHeader.Header; outHeader.HasLengthField = inHeader.HasLengthField; var inRestoreBundle = new FileStream(Path.Combine(this._assetFolder, "asset_backups", bundleId + ".bundle"), FileMode.Open, FileAccess.Read); var inBundle = new FileStream(Path.Combine(this._assetFolder, bundleId + ".bundle"), FileMode.Open, FileAccess.Read); var outBundle = new FileStream( Path.Combine(this._assetFolder, bundleId + ".bundle.new"), FileMode.OpenOrCreate, FileAccess.ReadWrite); int currentAddress = 0; int currentEntry = 1; int entryCount = inHeader.Entries.Count; foreach (BundleEntry entry in inHeader.Entries) { if (currentEntry % 100 == 0) { this.SetBundleProgress( string.Format("Writing entry {0}/{1}", currentEntry, entryCount), (int)((currentEntry / (float)entryCount) * 100.0f)); } var newEntry = new BundleEntry(); newEntry.Id = entry.Id; newEntry.Length = entry.Length; newEntry.Address = (uint)currentAddress; bool replaced = false; foreach (int length in from rewriteItem in mod.ItemQueue where rewriteItem.Ids.Contains(entry.Id) select this.RestoreEntry(inRestoreDictionary[entry.Id], (uint)currentAddress, inRestoreBundle, outBundle)) { currentAddress += length; newEntry.Length = length; replaced = true; break; } outHeader.Entries.Add(newEntry); if (!replaced) { inBundle.Seek(entry.Address, SeekOrigin.Begin); long entryLength = entry.Length == -1 ? inBundle.Length - inBundle.Position : entry.Length; var br = new BinaryReader(inBundle); var bw = new BinaryWriter(outBundle); bw.Write(br.ReadBytes((int)entryLength)); currentAddress += (int)entryLength; } currentEntry += 1; } inBundle.Close(); inRestoreBundle.Close(); outBundle.Close(); var outHeaderStream = new FileStream( Path.Combine(this._assetFolder, bundleId + "_h.bundle"), FileMode.OpenOrCreate, FileAccess.Write); var outHeaderBr = new BinaryWriter(outHeaderStream); outHeader.WriteHeader(outHeaderBr); foreach (BundleEntry entry in outHeader.Entries) { entry.WriteEntry(outHeaderBr, outHeader.HasLengthField); } outHeader.WriteFooter(outHeaderBr); outHeaderBr.Close(); outHeaderStream.Close(); File.Delete(Path.Combine(this._assetFolder, bundleId + ".bundle")); File.Move(Path.Combine(this._assetFolder, bundleId + ".bundle.new"), Path.Combine(this._assetFolder, bundleId + ".bundle")); this.SetBundleProgress("Done", 100); return true; }
/// <summary> /// The backup bundle entry. /// </summary> /// <param name="bundlePath"> /// The bundle path. /// </param> private void BackupEntries(BundleMod mod, string bundlePath) { string backupFolder = Path.Combine(this._assetFolder, "asset_backups") + "\\"; Directory.CreateDirectory(backupFolder); var header = new BundleHeader(); if (!header.Load(bundlePath)) { this.Error = "Failed to parse bundle header: " + bundlePath; } var bundleFS = new FileStream(bundlePath + ".bundle", FileMode.Open, FileAccess.Read); var bundleBR = new BinaryReader(bundleFS); foreach (BundleEntry entry in header.Entries) { BundleRewriteItem rewriteEntryItem; BundleRewriteItem backupRewriteItem = new BundleRewriteItem(); if (mod.ItemQueue.Any(rewriteItem => rewriteItem.Ids.Contains(entry.Id))) { NameEntry ne = StaticStorage.Index.Id2Name(entry.Id); rewriteEntryItem = mod.ItemQueue.First(rewriteItem => rewriteItem.Ids.Contains(entry.Id)); if (!File.Exists(backupFolder + ne.ToString())) { using (FileStream exportFS = new FileStream(backupFolder + ne.ToString(), FileMode.CreateNew, FileAccess.Write)) { using (BinaryWriter exportBW = new BinaryWriter(exportFS)) { long entryLength = entry.Length == -1 ? bundleFS.Length - bundleFS.Position : entry.Length; bundleFS.Seek(entry.Address, SeekOrigin.Begin); exportBW.Write(bundleBR.ReadBytes((int)entryLength)); } } } } } bundleBR.Close(); bundleFS.Close(); }
/// <summary> /// The apply mods. /// </summary> public void ApplyMods(BundleMod[] toAddModsList) { this.Done = false; using (this.Zip = new ZipFile(this._zipPath)) { bool wasSuccessful = false; this._mod.ItemQueue.RemoveWhere(i => i.BundleExtension == 0xAB2664BF82E646UL); this._mod.ItemQueue.RemoveWhere(i => i.BundleExtension == 0xAB2664BF82E6460C); this._mod.ItemQueue.RemoveWhere(i => i.BundleExtension == 0x29104BC4AC649965); if (!this.LocateChangeIds()) return; HashSet<string> bundles = this.LocateBundlesToRewrite(out wasSuccessful); if (!wasSuccessful) return; if (!this._patchAllBundles) bundles.RemoveWhere(i => i.StartsWith("all_")); if (bundles.Count <= 0) { this.Error = "Unable to locate any bundles with the requested items in them.\n" + "If the changed file(s) only exists within an all_x.bundle file you will need to enable the option to patch all_x.bundle files.\n" + "Refer to the patch description for if this is required."; return; } this.SetTotalProgress("Backing up Bundles", -1); this.CurrentBundlesCount = 1; this.TotalBundlesCount = bundles.Count; foreach (var bundle in bundles) { this.SetBundleProgress( string.Format("Backing up Bundle {0}/{1}", CurrentBundlesCount, TotalBundlesCount), (int)((CurrentBundlesCount / (float)TotalBundlesCount) * 100.0f)); if (this._backupType == 1) { this.BackupEntries(this._mod, Path.Combine(this._assetFolder, bundle)); } else { this.BackupFile(Path.Combine(this._assetFolder, bundle + "_h.bundle")); this.BackupFile(Path.Combine(this._assetFolder, bundle + ".bundle")); } CurrentBundlesCount += 1; } foreach (BundleMod bm in toAddModsList) { BackupEntry multibackupEntry = new BackupEntry(); multibackupEntry.Name = bm.Name; multibackupEntry.Author = bm.Author; multibackupEntry.Description = bm.Description; multibackupEntry.BackupType = (this._backupType == 0) ? "Bundles" : "Bundle Entries"; multibackupEntry.InstallDate = DateTime.Now; multibackupEntry.RewriteAll = this._patchAllBundles; HashSet<BundleRewriteItem> backupQueue = new HashSet<BundleRewriteItem>(); foreach (BundleRewriteItem bri in bm.ItemQueue) { BundleRewriteItem newbri = new BundleRewriteItem(); newbri.BundleExtension = bri.BundleExtension; newbri.BundleLanguage = bri.BundleLanguage; newbri.BundlePath = bri.BundlePath; newbri.Ids = bri.Ids; newbri.IsLanguageSpecific = bri.IsLanguageSpecific; if (this._backupType == 0) newbri.ReplacementFile = bri.ReplacementFile; else newbri.ReplacementFile = bri.BundlePath.ToString("x") + '.' + bri.BundleLanguage.ToString("x") + '.' + bri.BundleExtension.ToString("x"); newbri.SourceFile = bri.SourceFile; backupQueue.Add(newbri); } multibackupEntry.ItemQueue = backupQueue; backupEntries.Add(multibackupEntry); } allowBackup = true; CurrentBundlesCount = 1; TotalElapsedTime.Start(); foreach (var bundle in bundles) { this.SetTotalProgress( string.Format("Patching Bundle {0}/{1}", CurrentBundlesCount, TotalBundlesCount), (int)((CurrentBundlesCount / (float)TotalBundlesCount) * 100.0f)); if (!this.PatchBundle(bundle)) return; CurrentBundlesCount += 1; } TotalElapsedTime.Stop(); } this.SetTotalProgress("Done", 100); this.Done = true; }
private bool searchMod(BundleMod mod, String text) { if (String.IsNullOrWhiteSpace(this.availiableModsSearch_textbox.Text) || this.searchWatermark) return true; text = text.ToLower(CultureInfo.InvariantCulture); //special logic if (text.StartsWith("status:")) { if (text.TrimStart("status:".ToCharArray()).Equals("installed") && mod.status == BundleMod.ModStatus.Installed) return true; else if ((text.TrimStart("status:".ToCharArray()).Equals("not installed") || text.TrimStart("status:".ToCharArray()).Equals("!installed")) && mod.status == BundleMod.ModStatus.NotInstalled) return true; else if ((text.TrimStart("status:".ToCharArray()).Equals("partially installed") || text.TrimStart("status:".ToCharArray()).Equals("partly installed") || text.TrimStart("status:".ToCharArray()).Equals("part installed")) && mod.status == BundleMod.ModStatus.ParticallyInstalled) return true; else if ((text.TrimStart("status:".ToCharArray()).Equals("unknown") || text.TrimStart("status:".ToCharArray()).Equals("?")) && mod.status == BundleMod.ModStatus.Unrecognized) return true; } else if (text.StartsWith("type:")) { if (text.TrimStart("type:".ToCharArray()).Equals("pdmod") && mod.type == BundleMod.ModType.PDMod) return true; else if (text.TrimStart("type:".ToCharArray()).Equals("override") && mod.type == BundleMod.ModType.mod_override) return true; else if (text.TrimStart("type:".ToCharArray()).Equals("lua") && mod.type == BundleMod.ModType.lua) return true; } else if (text.StartsWith("marked:")) { if ((text.TrimStart("marked:".ToCharArray()).Equals("install") || text.TrimStart("marked:".ToCharArray()).Equals("installation")) && mod.actionStatus == BundleMod.ModActionStatus.Install) return true; else if ((text.TrimStart("marked:".ToCharArray()).Equals("remove") || text.TrimStart("marked:".ToCharArray()).Equals("removal") || text.TrimStart("marked:".ToCharArray()).Equals("uninstall") || text.TrimStart("marked:".ToCharArray()).Equals("delete")) && mod.actionStatus == BundleMod.ModActionStatus.Remove) return true; else if ((text.TrimStart("marked:".ToCharArray()).Equals("reinstall") || text.TrimStart("marked:".ToCharArray()).Equals("reinstallation")) && mod.actionStatus == BundleMod.ModActionStatus.Reinstall) return true; else if ((text.TrimStart("marked:".ToCharArray()).Equals("force reinstall") || text.TrimStart("marked:".ToCharArray()).Equals("force reinstallation") || text.TrimStart("marked:".ToCharArray()).Equals("freinstall")) && mod.actionStatus == BundleMod.ModActionStatus.ForcedReinstall) return true; else if ((text.TrimStart("marked:".ToCharArray()).Equals("missing")) && mod.actionStatus == BundleMod.ModActionStatus.Missing) return true; } if (mod.Name.ToLower(CultureInfo.InvariantCulture).Contains(this.availiableModsSearch_textbox.Text.ToLower(CultureInfo.InvariantCulture)) || mod.Author.ToLower(CultureInfo.InvariantCulture).Contains(this.availiableModsSearch_textbox.Text.ToLower(CultureInfo.InvariantCulture)) || mod.Description.ToLower(CultureInfo.InvariantCulture).Contains(this.availiableModsSearch_textbox.Text.ToLower(CultureInfo.InvariantCulture)) ) return true; return false; }
/// <summary> /// The serialize. /// </summary> /// <param name="mod"> /// The mod. /// </param> /// <returns> /// The <see cref="string"/>. /// </returns> public static string Serialize(BundleMod mod) { return JsonConvert.SerializeObject(mod, Formatting.Indented); }
/// <summary> /// The update local mods. /// </summary> private void updateModsListView() { //Regen the missingfile list Dictionary<string, BundleMod> modsList = this.mods_db.modsList; List<BackupEntry> missingfile_list = this.mods_db.installedModsList_missing; this.allowCheck = false; //Clear items //this.availiableMods_listView.Items.Clear(); List<ListViewItem> new_availiableMods = new List<ListViewItem>(); //Populate with local mods foreach (BundleMod localMod in modsList.Values.ToList()) { ListViewItem lvdi = new ListViewItem(); if (this.mods_db.InstalledModsListContains(localMod) >= 0 || localMod.status == BundleMod.ModStatus.Installed) { localMod.status = BundleMod.ModStatus.Installed; lvdi.Checked = true; } else lvdi.Checked = false; if (localMod.IncludesPatchScriptWithinOverride) { lvdi.Text = "[*]" + localMod.Name; lvdi.ToolTipText = "This mod uses the override folder with scripts, which may need to be reinstalled with game updates."; } else if (localMod.UtilizesBundles) { lvdi.Text = "[#]" + localMod.Name; lvdi.ToolTipText = "This mod will need to be reinstalled with each game update."; } else { lvdi.Text = localMod.Name; } lvdi.Tag = localMod; lvdi.Group = this.availiableMods_listView.Groups[0]; if(localMod.type == BundleMod.ModType.mod_override) lvdi.Group = this.availiableMods_listView.Groups[1]; else if (localMod.type == BundleMod.ModType.lua) { lvdi.Group = this.availiableMods_listView.Groups[2]; lvdi.Checked = localMod.enabled; } if (localMod.actionStatus == BundleMod.ModActionStatus.Install) { lvdi.BackColor = Color.LimeGreen; lvdi.ForeColor = Color.Black; lvdi.Checked = true; } else if (localMod.actionStatus == BundleMod.ModActionStatus.Remove) { lvdi.BackColor = Color.Red; lvdi.ForeColor = Color.White; lvdi.Checked = false; } else if (localMod.actionStatus == BundleMod.ModActionStatus.Reinstall) { lvdi.BackColor = Color.Yellow; lvdi.ForeColor = Color.Black; lvdi.Checked = true; } else if (localMod.actionStatus == BundleMod.ModActionStatus.ForcedReinstall) { lvdi.BackColor = Color.Orange; lvdi.ForeColor = Color.Black; lvdi.Checked = true; } else if (localMod.actionStatus == BundleMod.ModActionStatus.Missing) { localMod.canInstall = false; localMod.canUninstall = true; lvdi.BackColor = Color.LightBlue; lvdi.ForeColor = Color.Black; lvdi.Checked = true; } else { lvdi.BackColor = Color.White; lvdi.ForeColor = Color.Black; } if (searchMod(localMod, this.availiableModsSearch_textbox.Text) && (!(localMod.type == BundleMod.ModType.mod_override && !StaticStorage.settings.ShowOverrideMods))) new_availiableMods.Add(lvdi); //this.availiableMods_listView.Items.Add( lvdi ); } //Populate with other mods //population here if (missingfile_list.Count > 0) { foreach (var missing in missingfile_list) { ListViewItem lvdi = new ListViewItem(); BundleMod missingMod = new BundleMod(); missingMod.Name = missing.Name; missingMod.Author = missing.Author; missingMod.Description = missing.Description; missingMod.ItemQueue = missing.ItemQueue; missingMod.canInstall = false; missingMod.canUninstall = true; missingMod.actionStatus = BundleMod.ModActionStatus.Missing; lvdi.BackColor = Color.LightBlue; lvdi.ForeColor = Color.Black; lvdi.Checked = true; lvdi.Text = missingMod.Name; lvdi.Tag = missingMod; lvdi.Group = this.availiableMods_listView.Groups[0]; if (searchMod(missingMod, this.availiableModsSearch_textbox.Text)) new_availiableMods.Add(lvdi); //this.availiableMods_listView.Items.Add(lvdi); } } //this.availiableMods_listView.Items = (this.availiableMods_listView.Items.).OrderByDescending(o => o.Checked).ToList(); this.availiableMods_listView.Items.Clear(); this.availiableMods_listView.Items.AddRange(new_availiableMods.ToArray()); this.availiableMods_listView.Update(); this.refreshModsListView(); this.allowCheck = true; }
public bool Equals(BundleMod guest) { if (ReferenceEquals(guest, null)) return false; if (ReferenceEquals(this, guest)) return true; return this == guest; }
public ModDetails(BundleMod mod) : this() { this._mod = mod; }