internal FileManager(Project project, IPluginFileCopy fileCopyPlugin, string gameLocation) { _pakFormat = null; _pakEditor = null; _dbgEditor = null; _songListQbFile = null; _guitarProgressionQbFile = null; _project = project; _files = new Dictionary<string, GameFile>(); _fileCopy = fileCopyPlugin; _gameLocation = gameLocation; _backgroundAudioDatWad = null; }
public void RemoveIntroVids(PakEditor qbPak) { string bootupQb = @"scripts\guitar\menu\bootup_menu_flow.qb.ngc"; if (_project.GameInfo.Game == Game.GH3_Wii) bootupQb = bootupQb.Substring(1); //remove first char QbFile qb = qbPak.ReadQbFile(bootupQb); this.RemoveIntroVids(qb); qbPak.ReplaceFile(bootupQb, qb); }
public void ResetBonusArt(PakEditor qbPak) { string storeQb = @"scripts\guitar\store_data.qb.ngc"; if (_project.GameInfo.Game == Game.GH3_Wii) storeQb = storeQb.Substring(1); //remove first char QbFile qbStore = qbPak.ReadQbFile(storeQb); this.ResetBonusArt(qbStore); qbPak.ReplaceFile(storeQb, qbStore); }
/// <summary> /// Add new songs to GH3, this method requires that the partition 2 files are on the local disc /// </summary> public void AddSongs(DirectoryInfo rootPartitionPath, int adjustBy, string sourceSong, bool addNonCareerSongs, DirectoryInfo workingPath) { PakFormat pf = new PakFormat(string.Format(@"{0}\pak\{1}", rootPartitionPath.FullName, _project.FileManager.PakFormat.PakFilename), string.Empty, string.Empty, PakFormatType.Wii, false); PakEditor pe = new PakEditor(pf, false); string songlistQb = @"scripts\guitar\songlist.qb.ngc"; string storeDataQb = @"scripts\guitar\store_data.qb.ngc"; string guitProgQb = @"scripts\guitar\guitar_progression.qb.ngc"; if (_project.GameInfo.Game == Game.GH3_Wii) { songlistQb = songlistQb.Substring(1); //remove first char storeDataQb = storeDataQb.Substring(1); //remove first char guitProgQb = guitProgQb.Substring(1); //remove first char } if (_project.GameInfo.Game == Game.GH3_Wii || _project.GameInfo.Game == Game.GHA_Wii) { //add song to song list QbFile qb = pe.ReadQbFile(songlistQb); QbFile qbStore = pe.ReadQbFile(storeDataQb); QbFile qbGuitProg = pe.ReadQbFile(guitProgQb); string silentXbox = createBlankSourceAudio(workingPath); QbItemArray songsList = qb.FindItem(QbKey.Create("gh3_songlist"), false) as QbItemArray; List<QbKey> careerSongs = getAllCareerSongs(qbGuitProg); List<QbKey> bonusSongs = getAllBonusSongs(qbStore); List<QbKey> allSongs = new List<QbKey>(careerSongs); allSongs.AddRange(bonusSongs); //remove the boss battles. If we pick new files from the career then they will be removed anyway //QbKey[] bossSongs = new QbKey[] { QbKey.Create("bosstom"), QbKey.Create("bossslash"), QbKey.Create("bossdevil"), QbKey.Create("bossjoe") }; //foreach (QbKey qk in bossSongs) // careerSongs.Remove(qk); //insert the special songs on the end (that aren't in the career) List<QbKey> specialSongs = new List<QbKey>(); foreach (QbKey k in _specialSongs) { if (!careerSongs.Contains(k)) specialSongs.Add(k); } if (adjustBy > 0) { //Calculate extras int add = adjustBy + (addNonCareerSongs ? _nonCareerSongs.Count : 0); foreach (QbKey k in specialSongs) { if (!bonusSongs.Contains(k)) { if (_project.GameInfo.Game == Game.GH3_Wii) add--; //if bonus songs currently doesn't contian this special track then add one less song else add++; //GHA k&qcred will be added from not existing } } add = Math.Max(0, add); List<QbKey> newBonusList = new List<QbKey>(); //add the special songs on the end - DO THIS FIRST foreach (QbKey k in specialSongs) { if (!careerSongs.Contains(k)) newBonusList.Add(k); } int specialAdded = newBonusList.Count; //find the last _restoresong (a regular-song list in the correct order) in the career int start = -1; for (int i = careerSongs.Count - 1; i >= 0; i--) { start = _restoreSongs.IndexOf(careerSongs[i]); if (start >= 0) break; } if (start != -1) { start++; //move to the next item for (int i = start; i < _restoreSongs.Count; i++) { if (newBonusList.Count >= add + bonusSongs.Count) //add + existing bonussongs = correct count break; if (!careerSongs.Contains(_restoreSongs[i])) newBonusList.Insert(newBonusList.Count - specialAdded, _restoreSongs[i]); } } //nonCareer songs (only on GH3) if (addNonCareerSongs) { for (int i = 0; i < _nonCareerSongs.Count; i++) { if (newBonusList.Count >= add + bonusSongs.Count) break; if (!careerSongs.Contains(_nonCareerSongs[i])) newBonusList.Insert(newBonusList.Count - specialAdded, _nonCareerSongs[i]); } } //add ghost songs int num = 1; while (newBonusList.Count < add + bonusSongs.Count) { QbKey qk = QbKey.Create(string.Format("theghost{0}", (num++).ToString().PadLeft(3, '0'))); if (!careerSongs.Contains(qk)) newBonusList.Insert(newBonusList.Count - specialAdded, qk); } //remove any bonus songs not in our list foreach (QbKey k in bonusSongs) { if (!newBonusList.Contains(k)) { if (!careerSongs.Contains(k)) this.BonusSongRemoveFromGame(qbStore, qb, k); //remove from set list also else removeBonusSong(qbStore, k); } } //add all the missing items to the bonus lists foreach (QbKey k in newBonusList) { if (!bonusSongs.Contains(k)) { this.BonusSongAddToGame(qbStore, qb, k.Clone(), false); addBonusSongNotes(rootPartitionPath, QbKey.Create(sourceSong), k.Clone(), pe); createBonusSongAudio(rootPartitionPath, silentXbox, k); } } //set the correct order in the store list //find bonus song list QbItemArray qbBonusSongs = qbStore.FindItem(QbKey.Create("songs"), true) as QbItemArray; //add bonus song to list if (qbBonusSongs != null) (qbBonusSongs.Items[0] as QbItemQbKey).Values = newBonusList.ToArray(); qbStore.AlignPointers(); qbStore.IsValid(); qb.AlignPointers(); qb.IsValid(); } else if (adjustBy < 0) { if (addNonCareerSongs) //adds kings and queens credits if required this.AddBonusSongsFromNonCareer(qbStore, qb, qbGuitProg); bonusSongs = getAllBonusSongs(qbStore); //remove bonus songs that aren't required. keep any required int offset = 0; while (adjustBy != 0 && bonusSongs.Count > 0 && bonusSongs.Count - offset > 0) { int idx = (bonusSongs.Count - offset) - 1; if (bonusSongs[idx].Crc == QbKey.Create("kingsandqueenscredits").Crc || bonusSongs[idx].Crc == QbKey.Create("kingsandqueens").Crc || bonusSongs[idx].Crc == QbKey.Create("thrufireandflames").Crc) { offset++; continue; } if (!careerSongs.Contains(bonusSongs[idx])) this.BonusSongRemoveFromGame(qbStore, qb, bonusSongs[idx]); //remove from set list also else removeBonusSong(qbStore, bonusSongs[idx]); bonusSongs.RemoveAt(idx); adjustBy++; } } else if (adjustBy == 0 && addNonCareerSongs) { this.AddBonusSongsFromNonCareer(qbStore, qb, qbGuitProg); } qb.AlignPointers(); qb.IsValid(); qbStore.AlignPointers(); qbStore.IsValid(); FileHelper.Delete(silentXbox); pe.ReplaceFile(songlistQb, qb); pe.ReplaceFile(storeDataQb, qbStore); } }
/// <summary> /// Edits tiers using the files in Partition folder /// </summary> /// <param name="removeBossBattles"></param> /// <param name="bonusSongs"></param> /// <param name="songCounts"></param> public void EditTiers(PakEditor pak, bool removeBossBattles, int setTierCount, int bonusSongs, int[] songCounts, bool unlockTiers) { QbKey[] nonCareerSongs = new QbKey[0]; string progQb = @"scripts\guitar\guitar_progression.qb.ngc"; string coopQb = @"scripts\guitar\guitar_coop.qb.ngc"; string storeDataQb = @"scripts\guitar\store_data.qb.ngc"; string songlistQb = @"scripts\guitar\songlist.qb.ngc"; if (_project.GameInfo.Game == Game.GH3_Wii) { progQb = progQb.Substring(1); //remove first char coopQb = coopQb.Substring(1); //remove first char storeDataQb = storeDataQb.Substring(1); //remove first char songlistQb = songlistQb.Substring(1); //remove first char } if (_project.GameInfo.Game == Game.GH3_Wii || _project.GameInfo.Game == Game.GHA_Wii) { //add song to song list QbFile qbProg = pak.ReadQbFile(progQb); QbFile qbCoop = _project.GameInfo.Game == Game.GH3_Wii ? pak.ReadQbFile(coopQb) : null; QbFile qbStore = pak.ReadQbFile(storeDataQb); QbFile qbSonglist = pak.ReadQbFile(songlistQb); this.EditTiers(qbProg, qbStore, qbSonglist, qbCoop, removeBossBattles, setTierCount, bonusSongs, songCounts, unlockTiers); pak.ReplaceFile(progQb, qbProg); pak.ReplaceFile(storeDataQb, qbStore); if (qbCoop != null) pak.ReplaceFile(coopQb, qbCoop); pak.ReplaceFile(songlistQb, qbSonglist); } }
public void UnlockSetlists(PakEditor qbPak, bool unlockAllTiers, bool completeTier1Song) { string progQb = @"scripts\guitar\guitar_progression.qb.ngc"; string progCoopQb = @"scripts\guitar\guitar_coop.qb.ngc"; if (_project.GameInfo.Game == Game.GH3_Wii) progQb = progQb.Substring(1); //remove first char if (_project.GameInfo.Game == Game.GH3_Wii) progCoopQb = progCoopQb.Substring(1); //remove first char QbFile qb = qbPak.ReadQbFile(progQb); QbFile qbCoop = _project.GameInfo.Game == Game.GH3_Wii ? qbPak.ReadQbFile(progCoopQb) : null; this.UnlockSetlists(qb, qbCoop, unlockAllTiers, completeTier1Song); qbPak.ReplaceFile(progQb, qb); if (qbCoop != null) qbPak.ReplaceFile(progCoopQb, qbCoop); }
private void addBonusSongNotes(DirectoryInfo rootPath, QbKey source, QbKey dest, PakEditor qbPak) { string srcFolder = string.Format(@"{0}\songs", rootPath.FullName.TrimEnd('\\')); string srcMask = string.Format(@"{0}*.pak.ngc", source.Text); string[] srcFi = Directory.GetFiles(srcFolder, srcMask, SearchOption.TopDirectoryOnly); if (_project.GameInfo.Game == Game.GHA_Wii) { //GHA holds the section text in the main qb.pak file string destNotes = string.Format(@"songs\{0}.mid_text.qb.ngc", dest.Text); if (!qbPak.Headers.ContainsKey(destNotes.ToLower())) { QbFile qbNotes = qbPak.ReadQbFile(string.Format(@"songs\{0}.mid_text.qb.ngc", source.Text)); //copy notes section qb file to new file in qb.pak.ngc qbPak.AddFile(qbNotes, destNotes, QbKey.Create(".qb"), true); } } foreach (string src in srcFi) { FileInfo srcF = new FileInfo(src); string dst = string.Format(@"{0}\{1}{2}", srcF.Directory.FullName.TrimEnd('\\'), dest.Text, srcF.Name.Substring(source.Text.Length)); //skip if exists if (File.Exists(dst) || !Regex.IsMatch(src, string.Format(@"{0}(|_.)\.pak\.ngc$", source.Text))) //only allow "" or _<fgis> continue; File.Copy(src, dst, true); PakFormat pf = new PakFormat(dst, string.Empty, string.Empty, PakFormatType.Wii, false); PakEditor pe = new PakEditor(pf, false); string qbDst; QbFile qb; Dictionary<uint, string> srcQk; string dstS; foreach (string qbSrc in pe.QbFilenames) { qbDst = qbSrc.ToLower().Replace(source.Text.ToLower(), dest.Text.ToLower()); pe.RenameFile(qbSrc, qbDst, QbKey.Create(".mqb")); if (!qbSrc.Contains(".mid_text.")) { //map the section QbKeys qb = pe.ReadQbFile(qbDst); srcQk = getMidItems(source.Text); foreach (QbItemBase qib in qb.Items) { if (qib.ItemQbKey != null) { if (srcQk.ContainsKey(qib.ItemQbKey.Crc)) { dstS = string.Format("{0}{1}", dest.Text, srcQk[qib.ItemQbKey.Crc].Substring(source.Text.Length)); qib.ItemQbKey = QbKey.Create(dstS); } //else // throw new ApplicationException("Item QBKey not recognised"); } } pe.ReplaceFile(qbDst, qb); } } } }
private void clearInterface() { lstPakContents.Items.Clear(); tlblPakFileInfo.Text = string.Empty; clearInterfaceSearch(); clearInterfaceQb(); mnuEditQBFile.Enabled = false; tabPak.Text = "PAK File"; _pakFile = null; _dbgFile = null; }
public void SetCheats(PakEditor qbPak) { string cheatQb = @"scripts\guitar\menu\menu_cheats.qb.ngc"; if (_project.GameInfo.Game == Game.GH3_Wii) cheatQb = cheatQb.Substring(1); //remove first char QbFile qb = qbPak.ReadQbFile(cheatQb); this.SetCheats(qb); qbPak.ReplaceFile(cheatQb, qb); }
private void btnLoadPak_Click(object sender, EventArgs e) { try { this.Cursor = Cursors.WaitCursor; if (txtPakFile.Text.Trim().Length == 0) { showError("Pak File Error", "The PAK filename is blank"); return; } _pakFormat = new PakFormat(txtPakFile.Text, txtPabFile.Text, txtDebugFile.Text, formatToPakFormatType(cboFormatType.Text), false); if (_pakFormat.IsCompressed) { if (!_pakFormat.CompressedPakFileExists) { showError("Pak File Error", string.Format("The PAK file does not exist '{0}'", txtPakFile.Text)); return; } if (txtPabFile.Text.Length != 0 && !_pakFormat.CompressedPabFileExists) { showError("Pab File Error", string.Format("The PAB file does not exist '{0}'", txtPabFile.Text)); return; } if (txtDebugFile.Text.Length != 0 && !_pakFormat.CompressedDebugFileExists) { showError("Debug File Error", string.Format("The Debug file does not exist '{0}'", txtDebugFile.Text)); return; } } else { if (!_pakFormat.PakFileExists) { showError("Pak File Error", string.Format("The PAK file does not exist '{0}'", txtPakFile.Text)); return; } if (txtPabFile.Text.Length != 0 && !_pakFormat.PabFileExists) { showError("Pab File Error", string.Format("The PAB file does not exist '{0}'", txtPabFile.Text)); return; } if (txtDebugFile.Text.Length != 0 && !_pakFormat.DebugFileExists) { showError("Debug File Error", string.Format("The Debug file does not exist '{0}'", txtDebugFile.Text)); return; } } clearInterface(); AppState.InputFormat = cboFormatType.Text; AppState.PakFilename = txtPakFile.Text; AppState.PabFilename = txtPabFile.Text; AppState.DebugFilename = txtDebugFile.Text; AppState.Backup = chkBackup.Checked; try { if (chkBackup.Checked) { if (_pakFormat.PakFormatType == PakFormatType.XBox) { backup(_pakFormat.FullCompressedPakFilename); if (_pakFormat.PabFileExists) backup(_pakFormat.FullCompressedPabFilename); } else { backup(_pakFormat.FullPakFilename); if (_pakFormat.PabFileExists) backup(_pakFormat.FullPabFilename); } } } catch (Exception ex) { showException("PAK Backup Error", ex); clearInterface(); return; } try { _pakFile = new PakEditor(_pakFormat); } catch (Exception ex) { showException("PAK File Load/Parse Error", ex); clearInterface(); return; } if (_pakFile.RequiresPab && !_pakFormat.PabFileExists) { showError("PAK Error", "The data for this PAK is not present, it may require a PAB"); clearInterface(); return; } try { if (_pakFormat.DebugFileExists) _dbgFile = new PakEditor(_pakFormat, true); else _dbgFile = null; } catch (Exception ex) { showException("Debug File Load/Parse Error", ex); clearInterface(); return; } try { ListViewItem li; string[] fn; char[] sc = new char[] { '\\' }; lstPakContents.BeginUpdate(); lstPakContents.ListViewItemSorter = null; lstPakContents.Items.Clear(); foreach (PakHeaderItem phi in _pakFile.Headers.Values) { fn = phi.Filename.Split(sc); li = new ListViewItem(fn[fn.Length - 1]); li.SubItems.Add(phi.Filename); li.SubItems.Add(string.Format("{0} ({1})", (phi.HeaderStart + phi.FileOffset).ToString("X").PadLeft(8, '0'), (phi.HeaderStart + phi.FileOffset).ToString())); li.SubItems.Add(phi.FileLength.ToString()); li.SubItems.Add(phi.FileType.Text); li.ImageIndex = getPakFileImageIndex(phi.PakFileType); li.Tag = phi; lstPakContents.Items.Add(li); } lstPakContents.Focus(); updateStatusItems(); } catch (Exception ex) { showException("PAK List Population Error", ex); clearInterface(); return; } finally { lstPakContents.ListViewItemSorter = _lvwPakColumnSorter; lstPakContents.EndUpdate(); } lstPakContents.Sort(); if (lstPakContents.Items.Count > 0) { lstPakContents.Items[0].Selected = true; lstPakContents.Items[0].Focused = true; } tabPak.Text = string.Format("PAK: {0}", (new FileInfo(_pakFile.Filename)).Name); mnuEditQBFile.Enabled = true; } finally { this.Cursor = Cursors.Default; try { if (_pakFile.StructItemChildrenType == StructItemChildrenType.NotSet) { if (MessageBox.Show(this, @"Unable to detect StructItem Children Type. Is this a newer PAK file (GH:WT onwards)? New PAK files have array IDs within Struct types. Queen Bee can load these types without needing to know the type. It is required when creating new types This PAK has no StructItem children so this setting could not be detected.", "StructItem Children Type", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) { _pakFormat.StructItemChildrenType = StructItemChildrenType.ArrayItems; } else { _pakFormat.StructItemChildrenType = StructItemChildrenType.StructItems; } } } catch { } } }
private void btnTestSize_Click(object sender, EventArgs e) { PakEditor pak = null; try { pak = new PakEditor(_pakFormat); } catch (Exception ex) { showException("PAK Load Error", ex); return; } string saveQbName = string.Empty; try { int skipped = 0; foreach (PakHeaderItem phi in _pakFile.Headers.Values) { saveQbName = string.Format(@"C:\gh3temp\__\{0}", phi.Filename.Replace(@"\", "#")); if (phi.PakFileType == PakItemType.Qb || phi.PakFileType == PakItemType.Sqb || phi.PakFileType == PakItemType.Midi) { _pakFile.ExtractFile(phi.Filename, saveQbName); testQbFile(saveQbName); } else skipped++; } int c = (pak.Headers.Values.Count - skipped); MessageBox.Show(this, string.Format("PAK and {0} QB file{1} validated succesfully, {2} skipped", c.ToString(), c == 1 ? "" : "s", skipped.ToString()), "Information", MessageBoxButtons.OK, MessageBoxIcon.Information); } catch (Exception ex) { showError("Test Size Error", string.Format("{0} in '{1}'", ex.Message, saveQbName)); return; } }
private void mnuTestAllQbFiles_Click(object sender, EventArgs e) { PakEditor pak = null; try { pak = new PakEditor(_pakFormat); } catch (Exception ex) { showException("PAK Load Error", ex); return; } string filename = string.Empty; try { int skipped = 0; foreach (PakHeaderItem phi in pak.Headers.Values) { filename = phi.Filename; //System.Diagnostics.Debug.WriteLine(phi.Filename); //DEBUG FILENAME if (phi.PakFileType == PakItemType.Qb || phi.PakFileType == PakItemType.Sqb || phi.PakFileType == PakItemType.Midi) { //showError("Error", "Only QB files can be tested."); //return; QbFile qbf = pak.ReadQbFile(phi.Filename); QbItemBase qib = qbf.IsValid(); if (qib != null) throw new ApplicationException(string.Format("{0} at position 0x{1}", QbFile.FormatIsValidErrorMessage(qib, qib.IsValid), qib.Position.ToString("X").PadLeft(8, '0'))); } else skipped++; } int c = (pak.Headers.Values.Count - skipped); MessageBox.Show(this, string.Format("PAK and {0} QB file{1} validated succesfully, {2} skipped", c.ToString(), c == 1 ? "" : "s", skipped.ToString()), "Information", MessageBoxButtons.OK, MessageBoxIcon.Information); } catch (Exception ex) { showError("QB Test Error", string.Format("{0} in '{1}'", ex.Message, filename)); return; } }
private void replaceDataPartition(int songsToAdd, bool addNonCareerToBonus, bool removeBossBattles, int bonusSongs, int[] tierSongs) { //#if (!DEBUG) /////////////////////////////////////////////////////////// // SHRINK UPDATE PARTITION /////////////////////////////////////////////////////////// lblStatus.Text = "Shrinking Update Partition..."; lblStatus.Update(); if (_prepProps.RemoveUpdatePartition != YesNo.Yes) replaceUpdatePartition(false); prgInc(_shrinkPrgSize); /////////////////////////////////////////////////////////// // EXTRACT PARTITION /////////////////////////////////////////////////////////// lblStatus.Text = "Extracting Data Partition..."; lblStatus.Update(); //#endif DirectoryInfo pt = new DirectoryInfo(string.Format(@"{0}\PartitionData", _project.WorkingPath.TrimEnd('\\'))); //#if (!DEBUG) int i = 5; //try 5 times bool er = true; if (pt.Exists) { do { try { pt.Delete(true); er = false; } catch { er = true; System.Threading.Thread.Sleep(100); if (--i == 0) throw; } } while (er == true); } pt.Create(); ExtractPartition(_project.SourcePath, _partitionNo, pt.FullName); prgInc(_shrinkPrgSize); //#endif /////////////////////////////////////////////////////////// // EDIT FILES /////////////////////////////////////////////////////////// lblStatus.Text = "Editing Files..."; lblStatus.Update(); prepMovies(new DirectoryInfo(string.Format(@"{0}\movies", pt.FullName))); prepRemoveFiles(pt); if (_prepProps.EnableTierEditing == YesNo.Yes || songsToAdd != 0 || _prepProps.AddNonCareerTracksToBonus == YesNo.Yes) _project.GameMods.AddSongs(pt, songsToAdd, rdbGameGh3.Checked ? "lagrange" : "dreampolice", addNonCareerToBonus, new DirectoryInfo(_project.WorkingPath)); PakFormat pf = new PakFormat(string.Format(@"{0}\pak\{1}", pt.FullName, _project.FileManager.PakFormat.PakFilename), string.Empty, string.Empty, PakFormatType.Wii, false); PakEditor pe = new PakEditor(pf, false); if (_prepProps.EnableTierEditing == YesNo.Yes && (removeBossBattles || tierSongs != null)) _project.GameMods.EditTiers(pe, removeBossBattles, _prepProps.Tiers, bonusSongs, tierSongs, _prepProps.UnlockSetlistTiers == YesNo.Yes); if (_prepProps.SetCheats == YesNo.Yes) _project.GameMods.SetCheats(pe); if (_prepProps.RemoveIntroVideos == YesNo.Yes) _project.GameMods.RemoveIntroVids(pe); if (_prepProps.FreeStore == YesNo.Yes) _project.GameMods.FreeStore(pe); if (_prepProps.DefaultBonusSongArt == YesNo.Yes) _project.GameMods.ResetBonusArt(pe); if (_prepProps.DefaultBonusSongInfo == YesNo.Yes) _project.GameMods.ResetBonusInfoText(pe, _prepProps.DefaultBonusSongInfoText); //perform this step after edit tiers as edit tiers set the unlock values if (_prepProps.UnlockSetlistTiers == YesNo.Yes || _prepProps.CompleteTier1Song == YesNo.Yes) _project.GameMods.UnlockSetlists(pe, _prepProps.UnlockSetlistTiers == YesNo.Yes, _prepProps.CompleteTier1Song == YesNo.Yes); prgInc(_shrinkPrgSize); if (_prepProps.ManualEditing == YesNo.Yes) { lblStatus.Text = "Manual Editing..."; lblStatus.Update(); if (MessageBox.Show(this, string.Format("Edit the partition files here: {0}{1}{1}You can use TheGHOST with the File System plugin at this point to replace songs, or make manual adjustments.{1}{1}Press OK to build the partition and insert it into the ISO.", pt.FullName, Environment.NewLine), "Continue", MessageBoxButtons.OKCancel, MessageBoxIcon.Information) == DialogResult.Cancel) return; } Application.DoEvents(); int songNo = 0; DirectoryInfo ghostDir = new DirectoryInfo(string.Format(@"{0}\-TheGHOST-", pt.FullName)); string fileName = string.Format(@"{0}\info.txt", ghostDir.FullName); if (ghostDir.Exists) { if (File.Exists(fileName)) { string[] txt = File.ReadAllLines(fileName); if (txt.Length > 1) { if (txt[1].StartsWith("TheGHOSTSongs=")) songNo = int.Parse(txt[1].Split('=')[1]); } } } else ghostDir.Create(); //don't save the count of songs added with TheGHOST anymore //if (_prepProps.AddSongsCount > songNo) // songNo = _prepProps.AddSongsCount; string info = string.Format("{1} - v{2} / v{3}{0}TheGHOSTSongs={4}{0}", Environment.NewLine, TheGhostCore.AppName, TheGhostCore.AppVersion, TheGhostCore.CoreVersion, songNo.ToString()); info = string.Concat(info, new string(' ', 1024 - info.Length)); File.WriteAllText(fileName, info); /////////////////////////////////////////////////////////// // MOVING PARTITION ////////////////////////////////////////////////////////// //#if (!DEBUG) lblStatus.Text = "Moving Partition..."; lblStatus.Update(); ShufflePartitions(_project.SourcePath); prgInc(_shrinkPrgSize); //#endif /////////////////////////////////////////////////////////// // BUILD PARTITION /////////////////////////////////////////////////////////// lblStatus.Text = "Building Partition..."; lblStatus.Update(); GameFile[] files = _project.FileManager.Import(GameFileType.Other, null, @"\partition.bin", @"\main.dol", @"\apploader.img", @"\bi2.bin", @"\boot.bin"); FileInfo ptImg = new FileInfo(string.Format(@"{0}.img", pt.FullName)); WiiIso.BuildPartition(files[0].LocalName, files[1].LocalName, files[2].LocalName, files[3].LocalName, files[4].LocalName, pt.FullName, ptImg.FullName, true); _project.FileManager.RemoveAndDeleteAllFiles(); //remove extracted files (partition.bin etc) prgInc(_shrinkPrgSize); /////////////////////////////////////////////////////////// // REPLACE PARTITION ////////////////////////////////////////////////////////// lblStatus.Text = "Replacing Partition..."; lblStatus.Update(); LoadPartition(_project.SourcePath, ptImg.FullName, _partitionNo); FileHelper.Delete(ptImg.FullName); prgInc(_shrinkPrgSize); /////////////////////////////////////////////////////////// // COMPLETE /////////////////////////////////////////////////////////// MaxPartition(_project.SourcePath, _partitionNo); //ISO IS LOCKED BY WIISCRUBBER //if (chkRenameIso.Checked) //{ // FileInfo iso = new FileInfo(_project.SourcePath); // File.Move(iso.FullName, string.Format("{0}_prepped{1}", iso.Name.Substring(0, iso.Name.Length - iso.Extension.Length), iso.Extension)); //} lblStatus.Text = "Complete, Backup this ISO and use a copy of it when replacing songs."; prg.Value = prg.Maximum; }
private void parsePak(PakFormat pakFormat, bool debugFile) { _debugFile = debugFile; _pakFormat = pakFormat; _pakFilename = (!_debugFile ? _pakFormat.FullPakFilename : _pakFormat.FullDebugFilename); Dictionary <uint, PakDbgQbKey> qbKeyFilenames = new Dictionary <uint, PakDbgQbKey>(); //if PC or xbox then we need to look up the filename from the debug file //create a PakEditor and load the debug pak, then load all internal debug files, add the first line to our filenames dictionary if (!debugFile) // && (_pakFormat.PakFormatType == PakFormatType.PC || _pakFormat.PakFormatType == PakFormatType.XBox)) { try { _pakFormat.Decompress(); _pakFilename = _pakFormat.FullPakFilename; } catch (Exception ex) { throw new Exception("Decompression Error", ex); } if (_pakFormat.DebugFileExists && _debugFile) // cancer { string debugFileContents; string filename; uint crc; PakEditor pakDebug = new PakEditor(new PakFormat(_pakFormat.FullDebugFilename, "", _pakFormat.FullDebugFilename, _pakFormat.PakFormatType), true); foreach (PakHeaderItem dphi in pakDebug.Headers.Values) { debugFileContents = string.Empty; filename = string.Empty; crc = 0; if (dphi.FullFilenameQbKey != 0) { crc = dphi.FullFilenameQbKey; } else if (dphi.PakFullFileNameQbKey != 0) { crc = dphi.PakFullFileNameQbKey; } else if (dphi.NameOnlyCrc != 0) { crc = dphi.NameOnlyCrc; } if (crc != 0) { filename = crc.ToString("X").PadLeft(8, '0'); if (pakDebug.Headers.ContainsKey(filename.ToLower())) { debugFileContents = pakDebug.ExtractFileToString(filename); if (debugFileContents.Length != 0) { addDebugFilename(debugFileContents, qbKeyFilenames, crc); } } } } } } long minOffset = uint.MaxValue; long maxOffset = 0; _pakHeaders = new Dictionary <string, PakHeaderItem>(); using (Stream st = File.Open(_pakFilename, FileMode.Open, FileAccess.Read)) { _pakFileLength = st.Length; using (BinaryEndianReader br = new BinaryEndianReader(st)) { PakHeaderItem phi = null; QbKey lastQbKey = QbKey.Create("last"); QbKey dotLastQbKey = QbKey.Create(".last"); do { phi = new PakHeaderItem(); phi.HeaderStart = (uint)st.Position; phi.IsStoredInPak = true; phi.FileType = QbKey.Create(br.ReadUInt32(_pakFormat.EndianType)); //if the entry has the file type of last then we're done if (phi.FileType == lastQbKey || phi.FileType == dotLastQbKey) { break; } phi.FileOffset = br.ReadUInt32(_pakFormat.EndianType); phi.FileLength = br.ReadUInt32(_pakFormat.EndianType); phi.PakFullFileNameQbKey = br.ReadUInt32(_pakFormat.EndianType); phi.FullFilenameQbKey = br.ReadUInt32(_pakFormat.EndianType); phi.NameOnlyCrc = br.ReadUInt32(_pakFormat.EndianType); phi.Unknown = br.ReadUInt32(_pakFormat.EndianType); phi.Flags = (PakHeaderFlags)br.ReadUInt32(_pakFormat.EndianType); if ((phi.Flags & PakHeaderFlags.Filename) != PakHeaderFlags.Filename) { uint crc = 0; //get any Crc if (phi.FullFilenameQbKey != 0) { crc = phi.FullFilenameQbKey; } else if (phi.PakFullFileNameQbKey != 0) { crc = phi.PakFullFileNameQbKey; } else if (phi.NameOnlyCrc != 0) { crc = phi.NameOnlyCrc; } if (!debugFile) { uint crc2 = 0; //get a crc that exists in the debug names if (qbKeyFilenames.ContainsKey(phi.FullFilenameQbKey)) { crc2 = phi.FullFilenameQbKey; } else if (qbKeyFilenames.ContainsKey(phi.PakFullFileNameQbKey)) { crc2 = phi.PakFullFileNameQbKey; } else if (qbKeyFilenames.ContainsKey(phi.NameOnlyCrc)) { crc2 = phi.NameOnlyCrc; } //if 0 then get any crc if (crc2 != 0) { phi.Filename = qbKeyFilenames[crc2].Filename; phi.DebugQbKey = qbKeyFilenames[crc2].DebugQbKey; crc = crc2; } } if (phi.Filename == null) { if (crc != 0) { phi.Filename = crc.ToString("X").PadLeft(8, '0'); } else { phi.Filename = string.Format("Unknown={0}", phi.HeaderStart.ToString("X").PadLeft(8, '0')); } } } else { phi.Filename = UTF8Encoding.UTF8.GetString(br.ReadBytes(PakHeaderItem.FileNameMaxLength)).TrimEnd(new char[] { '\0' }); } try { _pakHeaders.Add(phi.Filename.ToLower(), phi); } catch (Exception ex) { throw new ApplicationException(string.Format("Error adding '{0}' to headers: {1}", phi.Filename, ex.Message)); } if (phi.HeaderStart + phi.FileOffset < minOffset) { minOffset = phi.HeaderStart + phi.FileOffset; } if (phi.HeaderStart + phi.FileOffset > maxOffset) { maxOffset = phi.HeaderStart + phi.FileOffset; } }while (1 == 1); //minOffset > fs.Position + 0x100); //drop out if we reach the data //this is a simple hack/fix to cater for padding on PAK files, //it relies on the data starting at the top of the PAB file (which it always does, currently) _requiresPab = maxOffset >= st.Length; if (!debugFile) //only when loading pak { _pakFormat.PakPabMinDataOffset = minOffset; //remember this value } //detect GH5 PAB files if (_requiresPab) { foreach (PakHeaderItem ph in _pakHeaders.Values) { ph.FileOffset += (uint)(_pakFileLength - _pakFormat.PakPabMinDataOffset) - (_pakFormat.PakPabMinDataOffset == 0 ? ph.HeaderStart : 0); //gh5 doesn't hold the offset in relation to the data. } minOffset = _pakFileLength; } } } _qbFilenames = new string[_pakHeaders.Count]; int i = 0; foreach (PakHeaderItem hi in _pakHeaders.Values) { _qbFilenames[i++] = hi.Filename; } StructItemChildrenType s; if (!debugFile) { s = this.StructItemChildrenType; //auto detect the structitemchildren type } }
private void parsePak(PakFormat pakFormat, bool debugFile) { _debugFile = debugFile; _pakFormat = pakFormat; _pakFilename = (!_debugFile ? _pakFormat.FullPakFilename : _pakFormat.FullDebugFilename); Dictionary<uint, PakDbgQbKey> qbKeyFilenames = new Dictionary<uint, PakDbgQbKey>(); //if PC or xbox then we need to look up the filename from the debug file //create a PakEditor and load the debug pak, then load all internal debug files, add the first line to our filenames dictionary if (!debugFile) // && (_pakFormat.PakFormatType == PakFormatType.PC || _pakFormat.PakFormatType == PakFormatType.XBox)) { try { _pakFormat.Decompress(); _pakFilename = _pakFormat.FullPakFilename; } catch (Exception ex) { throw new Exception("Decompression Error", ex); } if (_pakFormat.DebugFileExists) { string debugFileContents; string filename; uint crc; PakEditor pakDebug = new PakEditor(new PakFormat(_pakFormat.FullDebugFilename, "", _pakFormat.FullDebugFilename, _pakFormat.PakFormatType), true); foreach (PakHeaderItem dphi in pakDebug.Headers.Values) { debugFileContents = string.Empty; filename = string.Empty; crc = 0; if (dphi.FullFilenameQbKey != 0) crc = dphi.FullFilenameQbKey; else if (dphi.PakFullFileNameQbKey != 0) crc = dphi.PakFullFileNameQbKey; else if (dphi.NameOnlyCrc != 0) crc = dphi.NameOnlyCrc; if (crc != 0) { filename = crc.ToString("X").PadLeft(8, '0'); if (pakDebug.Headers.ContainsKey(filename.ToLower())) { debugFileContents = pakDebug.ExtractFileToString(filename); if (debugFileContents.Length != 0) addDebugFilename(debugFileContents, qbKeyFilenames, crc); } } } } } long minOffset = uint.MaxValue; long maxOffset = 0; _pakHeaders = new Dictionary<string, PakHeaderItem>(); using (Stream st = File.Open(_pakFilename, FileMode.Open, FileAccess.Read)) { _pakFileLength = st.Length; using (BinaryEndianReader br = new BinaryEndianReader(st)) { PakHeaderItem phi = null; QbKey lastQbKey = QbKey.Create("last"); QbKey dotLastQbKey = QbKey.Create(".last"); do { phi = new PakHeaderItem(); phi.HeaderStart = (uint)st.Position; phi.IsStoredInPak = true; phi.FileType = QbKey.Create(br.ReadUInt32(_pakFormat.EndianType)); //if the entry has the file type of last then we're done if (phi.FileType == lastQbKey || phi.FileType == dotLastQbKey) break; phi.FileOffset = br.ReadUInt32(_pakFormat.EndianType); phi.FileLength = br.ReadUInt32(_pakFormat.EndianType); phi.PakFullFileNameQbKey = br.ReadUInt32(_pakFormat.EndianType); phi.FullFilenameQbKey = br.ReadUInt32(_pakFormat.EndianType); phi.NameOnlyCrc = br.ReadUInt32(_pakFormat.EndianType); phi.Unknown = br.ReadUInt32(_pakFormat.EndianType); phi.Flags = (PakHeaderFlags)br.ReadUInt32(_pakFormat.EndianType); if ((phi.Flags & PakHeaderFlags.Filename) != PakHeaderFlags.Filename) { uint crc = 0; //get any Crc if (phi.FullFilenameQbKey != 0) crc = phi.FullFilenameQbKey; else if (phi.PakFullFileNameQbKey != 0) crc = phi.PakFullFileNameQbKey; else if (phi.NameOnlyCrc != 0) crc = phi.NameOnlyCrc; if (!debugFile) { uint crc2 = 0; //get a crc that exists in the debug names if (qbKeyFilenames.ContainsKey(phi.FullFilenameQbKey)) crc2 = phi.FullFilenameQbKey; else if (qbKeyFilenames.ContainsKey(phi.PakFullFileNameQbKey)) crc2 = phi.PakFullFileNameQbKey; else if (qbKeyFilenames.ContainsKey(phi.NameOnlyCrc)) crc2 = phi.NameOnlyCrc; //if 0 then get any crc if (crc2 != 0) { phi.Filename = qbKeyFilenames[crc2].Filename; phi.DebugQbKey = qbKeyFilenames[crc2].DebugQbKey; crc = crc2; } } if (phi.Filename == null) { if (crc != 0) phi.Filename = crc.ToString("X").PadLeft(8, '0'); else phi.Filename = string.Format("Unknown={0}", phi.HeaderStart.ToString("X").PadLeft(8, '0')); } } else phi.Filename = UTF8Encoding.UTF8.GetString(br.ReadBytes(PakHeaderItem.FileNameMaxLength)).TrimEnd(new char[] { '\0' }); try { _pakHeaders.Add(phi.Filename.ToLower(), phi); } catch (Exception ex) { throw new ApplicationException(string.Format("Error adding '{0}' to headers: {1}", phi.Filename, ex.Message)); } if (phi.HeaderStart + phi.FileOffset < minOffset) minOffset = phi.HeaderStart + phi.FileOffset; if (phi.HeaderStart + phi.FileOffset > maxOffset) maxOffset = phi.HeaderStart + phi.FileOffset; } while (1 == 1); //minOffset > fs.Position + 0x100); //drop out if we reach the data //this is a simple hack/fix to cater for padding on PAK files, //it relies on the data starting at the top of the PAB file (which it always does, currently) _requiresPab = maxOffset >= st.Length; if (!debugFile) //only when loading pak _pakFormat.PakPabMinDataOffset = minOffset; //remember this value //detect GH5 PAB files if (_requiresPab) { foreach (PakHeaderItem ph in _pakHeaders.Values) ph.FileOffset += (uint)(_pakFileLength - _pakFormat.PakPabMinDataOffset) - (_pakFormat.PakPabMinDataOffset == 0 ? ph.HeaderStart : 0); //gh5 doesn't hold the offset in relation to the data. minOffset = _pakFileLength; } } } _qbFilenames = new string[_pakHeaders.Count]; int i = 0; foreach (PakHeaderItem hi in _pakHeaders.Values) _qbFilenames[i++] = hi.Filename; StructItemChildrenType s; if (!debugFile) s = this.StructItemChildrenType; //auto detect the structitemchildren type }
private int replaceNotesItems() { int notesLength = 0; //position of final notes item (last fret) QbKey song = this.SongQb.Id; string songName = song.Text; GameFile gf = _project.FileManager.File(_project.GameInfo.GetNotesFilename(song)); if (gf == null) return notesLength; //return 0, this prevents exceptions in the ISO tool which doesn't replace notes string notesPak = gf.LocalName; PakFormat pf = new PakFormat(notesPak, "", "", _project.GameInfo.PakFormatType); PakEditor pak = new PakEditor(pf); QbFile qb = pak.ReadQbFile(_project.GameInfo.GetNotesQbFilename(song)); //modify the mid file //clearAllQbItems(qb, this.Notes.GhItems, // QbKey.Create(string.Format("{0}_TimeSig", songName)), // QbKey.Create(string.Format("{0}_FretBars", songName)), // QbKey.Create(string.Format("{0}_Markers", songName))); QbFile qbText; if (!_project.GameInfo.MidTextInQbPak) qbText = pak.ReadQbFile(_project.GameInfo.GetNotesTextQbFilename(song)); else { qbText = _project.FileManager.QbPakEditor.ReadQbFile(_project.GameInfo.GetNotesTextQbFilename(song)); } QbItemArray ar; int[] ints; int offset; //calculate ms to add to wav to ensure notes don't start before the given time (in seconds) if (this.Notes.MinNoteOffsetSynced < this.MinMsBeforeNotesStart) _startPaddingMs = this.MinMsBeforeNotesStart - this.Notes.MinNoteOffsetSynced; this.Length = this.Audio.AudioLength + _startPaddingMs; offset = this.Notes.BaseFile.NonNoteSyncOffset + _startPaddingMs; int[] frets = (int[])this.Notes.BaseFile.Frets.Clone(); //clone in case class is holding reference for (int i = 0; i < frets.Length; i++) frets[i] += offset; //this function sets _fretPadding, another padding value. It adds padding to allow a properly spaced fret to be at position 0 frets = adjustFrets(frets); notesLength = frets[frets.Length - 1]; //set the track length to the notes length if it's longer if (this.Length < notesLength) this.Length = notesLength; else this.Length += _fretPadding; offset += _fretPadding; int[] timeSig = (int[])this.Notes.BaseFile.Parser.GetTimeSig().Clone(); //clone in case class is holding reference if (timeSig.Length == 0) timeSig = new int[] { 0, 4, 4 }; for (int i = 0; i < timeSig.Length; i += 3) timeSig[i] = (int)findNearestFret((uint)(timeSig[i] + offset), frets); timeSig[0] = 0; //if the first item is not 0 the song won't load??. NotesMarker[] markers = (NotesMarker[])this.Notes.BaseFile.Parser.GetNotesMarkers().Clone(); //clone in case class is holding reference for (int i = 0; i < markers.Length; i += 3) markers[i] = new NotesMarker(markers[i].Title, markers[i].Offset + offset); //perform deep clone int oldSustainTrigger; int sustainTrigger; int nextNote; int[] faceOffP1Ints = new int[0]; int[] faceOffP2Ints = new int[0]; GhNotesItem faceOffItem = null; //we have a face off item for each mapping, GH3 only has one per song, find the one with the hardest difficulty (They're always the same anyway) foreach (GhNotesItem ghi in this.Notes.GhItems) { if (ghi.IsMapped && ghi.MappedFileItem.FaceOffP1Count != 0 && ghi.MappedFileItem.FaceOffP2Count != 0) { //non generated overrides generated if (faceOffItem == null || faceOffItem.MappedFileItem.HasGeneratedFaceOff || (ghi.MappedFileItem.HasGeneratedFaceOff == faceOffItem.MappedFileItem.HasGeneratedFaceOff)) { if (faceOffItem == null || ((int)faceOffItem.Difficulty < (int)ghi.Difficulty && ghi.Type == NotesType.Guitar)) //guitar is more reliable faceOffItem = ghi; } } } if (faceOffItem != null) { offset = faceOffItem.MappedFileItem.SyncOffset + _startPaddingMs + _fretPadding; faceOffP1Ints = (int[])faceOffItem.MappedFileItem.FaceOffP1.Clone(); for (int i = 0; i < faceOffP1Ints.Length; i += 2) faceOffP1Ints[i] += offset; faceOffP2Ints = (int[])faceOffItem.MappedFileItem.FaceOffP2.Clone(); for (int i = 0; i < faceOffP2Ints.Length; i += 2) faceOffP2Ints[i] += offset; } foreach (GhNotesItem ghi in this.Notes.GhItems) { if (ghi.IsMapped) { oldSustainTrigger = ghi.MappedFileItem.SustainTrigger; sustainTrigger = (int)((float)(frets[1] - frets[0]) / 2F); ghi.MappedFileItem.SustainTrigger = sustainTrigger; //Offset notes offset = ghi.MappedFileItem.SyncOffset + _startPaddingMs + _fretPadding; ints = (int[])ghi.MappedFileItem.Notes.Clone(); //don't modify original notes int startFret = 0; for (int i = 0; i < ints.Length; i += 3) { ints[i] += offset; if (i + 3 < ints.Length) nextNote = ints[i + 3] + offset; else nextNote = 0; //loop to find fret length note is in to calculate if note is sustained int fpos; int fretLen = 0; bool isSustained = false; for (int c = startFret; c < frets.Length; c++) { if ((fpos = frets[c]) > ints[i] && c > 0) //careful fpos is assigned here { startFret = c; //next time start from here fretLen = fpos - frets[c - 1]; isSustained = ints[i + 1] > ((fretLen / 192.0) * (double)(192 >> 2)); //(fretLen / 192.0 == bpmUnit break; } } //clip sustained notes to GH3 mode if (isSustained) ints[i + 1] = setSustain(ints[i], ints[i + 1], nextNote, oldSustainTrigger / 2, sustainTrigger / 2, this.Notes.Gh3SustainClipping); } int[] notes = ints; //if this is a boss battle then remove notes that are not within the face off sections if (this.IsBoss && faceOffItem != null) ints = convertBossNotesToFaceOff(ints, ghi.Type == NotesType.Guitar ? faceOffP1Ints : faceOffP2Ints); ints = adjustNotes(ints); //merge any notes that are really close together //replace track notes ar = (QbItemArray)qb.FindItem(ghi.SongNotesQbKey, false); replaceQbItems(ar, ints, false); setLength(ar, this.Length, 3, frets, false); //Offset star power ints = (int[])ghi.MappedFileItem.StarPower.Clone(); //don't modify original starpower for (int i = 0; i < ints.Length; i += 3) ints[i] += offset; //if (faceOffItem != null) // alignBattleStarPowerToFaceOff(ints, ghi.Type == NotesType.Guitar ? faceOffP1Ints : faceOffP2Ints); ints = adjustBattleStarPower(ints, notes); //replace star power ar = (QbItemArray)qb.FindItem(ghi.SongStarPowerQbKey, false); replaceQbItems(ar, this.Notes.ForceNoStarPower ? new int[0] : ints, true); //optionally set to no star power setLength(ar, this.Length, 3, frets, false); int[] sp = ints; //Offset star battle mode ints = (int[])ghi.MappedFileItem.BattlePower.Clone(); for (int i = 0; i < ints.Length; i += 3) ints[i] += offset; //if (faceOffItem != null) // alignBattleStarPowerToFaceOff(ints, ghi.Type == NotesType.Guitar ? faceOffP1Ints : faceOffP2Ints); ints = adjustBattleStarPower(ints, notes); if (ints.Length == 0) //if no ints then use star power ints = (int[])sp.Clone(); //just to ensure there's no issue with 2 references pointing at the same array //replace star battle notes ar = (QbItemArray)qb.FindItem(ghi.SongStarPowerBattleQbKey, false); replaceQbItems(ar, ints, true); setLength(ar, this.Length, 3, frets, false); } else { ar = (QbItemArray)qb.FindItem(ghi.SongNotesQbKey, false); clearQbItems(ar); ar = (QbItemArray)qb.FindItem(ghi.SongStarPowerQbKey, false); clearQbItems(ar); ar = (QbItemArray)qb.FindItem(ghi.SongStarPowerBattleQbKey, false); clearQbItems(ar); } } ar = (QbItemArray)qb.FindItem(QbKey.Create(string.Format("{0}_Song_GuitarCoop_{1}", songName, NotesDifficulty.Easy.ToString())), false); clearQbItems(ar); ar = (QbItemArray)qb.FindItem(QbKey.Create(string.Format("{0}_Song_GuitarCoop_{1}", songName, NotesDifficulty.Medium.ToString())), false); clearQbItems(ar); ar = (QbItemArray)qb.FindItem(QbKey.Create(string.Format("{0}_Song_GuitarCoop_{1}", songName, NotesDifficulty.Hard.ToString())), false); clearQbItems(ar); ar = (QbItemArray)qb.FindItem(QbKey.Create(string.Format("{0}_Song_GuitarCoop_{1}", songName, NotesDifficulty.Expert.ToString())), false); clearQbItems(ar); ar = (QbItemArray)qb.FindItem(QbKey.Create(string.Format("{0}_Song_RhythmCoop_{1}", songName, NotesDifficulty.Easy.ToString())), false); clearQbItems(ar); ar = (QbItemArray)qb.FindItem(QbKey.Create(string.Format("{0}_Song_RhythmCoop_{1}", songName, NotesDifficulty.Medium.ToString())), false); clearQbItems(ar); ar = (QbItemArray)qb.FindItem(QbKey.Create(string.Format("{0}_Song_RhythmCoop_{1}", songName, NotesDifficulty.Hard.ToString())), false); clearQbItems(ar); ar = (QbItemArray)qb.FindItem(QbKey.Create(string.Format("{0}_Song_RhythmCoop_{1}", songName, NotesDifficulty.Expert.ToString())), false); clearQbItems(ar); ar = (QbItemArray)qb.FindItem(QbKey.Create(string.Format("{0}_BossBattleP1", songName)), false); clearQbItems(ar); ar = (QbItemArray)qb.FindItem(QbKey.Create(string.Format("{0}_BossBattleP2", songName)), false); clearQbItems(ar); //start with expert guitar and work down the difficulties to find a GHItem with Face off, copy in to BOss Battle also if (faceOffItem != null) { QbItemArray fo1 = (QbItemArray)qb.FindItem(QbKey.Create(string.Format("{0}_FaceOffP1", songName)), false); QbItemArray fo2 = (QbItemArray)qb.FindItem(QbKey.Create(string.Format("{0}_FaceOffP2", songName)), false); if (faceOffItem.IsMapped && faceOffItem.MappedFileItem != null && faceOffItem.MappedFileItem.FaceOffP1Count + faceOffItem.MappedFileItem.FaceOffP2Count != 0) { faceOffP1Ints = adjustFaceOff(faceOffP1Ints); replaceQbItems(fo1, faceOffP1Ints, true, 2); //ar = (QbItemArray)qb.FindItem(QbKey.Create(string.Format("{0}_BossBattleP1", songName)), false); //replaceQbItems(ar, faceOffP1Ints, true, 2); faceOffP2Ints = adjustFaceOff(faceOffP2Ints); replaceQbItems(fo2, faceOffP2Ints, true, 2); //ar = (QbItemArray)qb.FindItem(QbKey.Create(string.Format("{0}_BossBattleP2", songName)), false); //replaceQbItems(ar, faceOffP2Ints, true, 2); } else { clearQbItems(fo1); clearQbItems(fo2); } } ar = (QbItemArray)qb.FindItem(QbKey.Create(string.Format("{0}_TimeSig", songName)), false); replaceQbItems(ar, timeSig, true); setLength(ar, this.Length, 3, frets, false); ar = (QbItemArray)qb.FindItem(QbKey.Create(string.Format("{0}_FretBars", songName)), false); replaceQbItems(ar, frets, false); ar = (QbItemArray)qb.FindItem(QbKey.Create(string.Format("{0}_Markers", songName)), false); if (markers.Length != 0) setMarkers(frets, ar, qbText, markers); else calculateMarkers(frets, ar, qbText); ar = (QbItemArray)qb.FindItem(QbKey.Create(string.Format("{0}_Scripts_Notes", songName)), false); setLength(ar, this.Length, 3, frets, true); //clearQbItems(ar); ar = (QbItemArray)qb.FindItem(QbKey.Create(string.Format("{0}_Anim_Notes", songName)), false); setLength(ar, this.Length, 3, frets, true); //clearQbItems(ar); ar = (QbItemArray)qb.FindItem(QbKey.Create(string.Format("{0}_Triggers_Notes", songName)), false); setLength(ar, this.Length, 3, frets, true); //clearQbItems(ar); ar = (QbItemArray)qb.FindItem(QbKey.Create(string.Format("{0}_Cameras_Notes", songName)), false); setLength(ar, this.Length, 3, frets, true); clearQbItems(ar); ar = (QbItemArray)qb.FindItem(QbKey.Create(string.Format("{0}_Lightshow_Notes", songName)), false); setLength(ar, this.Length, 3, frets, true); //clearQbItems(ar); ar = (QbItemArray)qb.FindItem(QbKey.Create(string.Format("{0}_Crowd_Notes", songName)), false); setLength(ar, this.Length, 3, frets, true); //clearQbItems(ar); ar = (QbItemArray)qb.FindItem(QbKey.Create(string.Format("{0}_Drums_Notes", songName)), false); ////setLength(ar, this.Length, 3, frets, true); clearQbItems(ar); ar = (QbItemArray)qb.FindItem(QbKey.Create(string.Format("{0}_Performance_Notes", songName)), false); setLength(ar, this.Length, 3, frets, true); //clearQbItems(ar); ar = (QbItemArray)qb.FindItem(QbKey.Create(string.Format("{0}_Scripts", songName)), false); if (this.SongQb.IsBoss) //set the death drain marker to the correct location setDeathDrain(ar, markers); else setLength(ar, this.Length, 3, frets, true); //clearQbItems(ar); ar = (QbItemArray)qb.FindItem(QbKey.Create(string.Format("{0}_Anim", songName)), false); setLength(ar, this.Length, 3, frets, true); //clearQbItems(ar); ar = (QbItemArray)qb.FindItem(QbKey.Create(string.Format("{0}_Triggers", songName)), false); setLength(ar, this.Length, 3, frets, true); //clearQbItems(ar); ar = (QbItemArray)qb.FindItem(QbKey.Create(string.Format("{0}_Cameras", songName)), false); setLength(ar, this.Length, 3, frets, true); //clearQbItems(ar); ar = (QbItemArray)qb.FindItem(QbKey.Create(string.Format("{0}_Lightshow", songName)), false); setLength(ar, this.Length, 3, frets, true); //clearQbItems(ar); ar = (QbItemArray)qb.FindItem(QbKey.Create(string.Format("{0}_Crowd", songName)), false); setLength(ar, this.Length, 3, frets, true); //clearQbItems(ar); ar = (QbItemArray)qb.FindItem(QbKey.Create(string.Format("{0}_Drums", songName)), false); ////setLength(ar, this.Length, 3, frets, true); clearQbItems(ar); ar = (QbItemArray)qb.FindItem(QbKey.Create(string.Format("{0}_Performance", songName)), false); setLength(ar, this.Length, 3, frets, true); //clearQbItems(ar); qb.AlignPointers(); qb.IsValid(); qbText.AlignPointers(); qbText.IsValid(); long origPakLen = pak.FileLength; string tmpPak = string.Format("{0}_{1}", notesPak, Guid.NewGuid().ToString("N")); File.Copy(notesPak, tmpPak); if (_project.GameInfo.MidTextInQbPak) { //save markers to qbPak _project.FileManager.QbPakEditor.ReplaceFile(_project.GameInfo.GetNotesTextQbFilename(song), qbText); } else //save markers to mid pak { pak.ReplaceFile(_project.GameInfo.GetNotesTextQbFilename(song), qbText); } //replace notes to mid pak pak.ReplaceFile(_project.GameInfo.GetNotesQbFilename(song), qb); //pad notes pak with original file //add padding to ensure song works - This took over a month of testing to find!! //////////using (FileStream fs = new FileStream(notesPak, FileMode.Open, FileAccess.ReadWrite)) //////////{ ////////// using (FileStream fsI = new FileStream(tmpPak, FileMode.Open, FileAccess.Read)) ////////// { ////////// fs.Seek(0, SeekOrigin.End); ////////// string tag = " -=> NANOOK <=- PADDING BELOW "; ////////// if (fs.Position + tag.Length < fsI.Length) ////////// fs.Write(Encoding.Default.GetBytes(tag), 0, tag.Length); ////////// if (fs.Position < fsI.Length) ////////// { ////////// fsI.Seek(fs.Position, SeekOrigin.Begin); ////////// copy(fsI, fs, fsI.Length - fsI.Position); ////////// } ////////// } //////////} FileHelper.Delete(tmpPak); return notesLength; }