Ejemplo n.º 1
0
        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;
        }
Ejemplo n.º 2
0
        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);
        }
Ejemplo n.º 3
0
        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);
        }
Ejemplo n.º 4
0
        /// <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);
            }
        }
Ejemplo n.º 5
0
        /// <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);
            }
        }
Ejemplo n.º 6
0
        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);
        }
Ejemplo n.º 7
0
        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);
                    }

                }
            }
        }
Ejemplo n.º 8
0
        private void clearInterface()
        {
            lstPakContents.Items.Clear();
            tlblPakFileInfo.Text = string.Empty;
            clearInterfaceSearch();
            clearInterfaceQb();
            mnuEditQBFile.Enabled = false;
            tabPak.Text = "PAK File";

            _pakFile = null;
            _dbgFile = null;
        }
Ejemplo n.º 9
0
        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);
        }
Ejemplo n.º 10
0
        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
                {
                }
            }
        }
Ejemplo n.º 11
0
        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;
            }
        }
Ejemplo n.º 12
0
        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;
            }
        }
Ejemplo n.º 13
0
        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;
        }
Ejemplo n.º 14
0
        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
            }
        }
Ejemplo n.º 15
0
        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
        }
Ejemplo n.º 16
0
        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;
        }