Inheritance: QbItemBase
        public override void Construct(BinaryEndianReader br, QbItemType type)
        {
            //System.Diagnostics.Debug.WriteLine(string.Format("{0} - 0x{1}", type.ToString(), (base.StreamPos(br) - 4).ToString("X").PadLeft(8, '0')));

            base.Construct(br, type);

            QbItemBase qib;
            QbItemType headerType;
            uint       headerValue;

            for (int i = 0; i < base.ItemCount; i++)
            {
                if (base.StreamPos(br) != base.Pointers[i]) //pointer test
                {
                    throw new ApplicationException(QbFile.FormatBadPointerExceptionMessage(this, base.StreamPos(br), base.Pointers[i]));
                }

                headerValue = br.ReadUInt32(this.Root.PakFormat.EndianType);
                headerType  = this.Root.PakFormat.GetQbItemType(headerValue);

                switch (headerType)
                {
                case QbItemType.StructHeader:
                    qib = new QbItemStruct(this.Root);
                    break;

                default:
                    throw new ApplicationException(string.Format("Location 0x{0}: Not a struct header type 0x{1}", (base.StreamPos(br) - 4).ToString("X").PadLeft(8, '0'), headerValue.ToString("X").PadLeft(8, '0')));
                }
                qib.Construct(br, headerType);
                AddItem(qib);
            }

            base.ConstructEnd(br);
        }
Example #2
0
        /// <summary>
        /// Deep clones this item and all children.  Positions and lengths are not cloned.  When inserted in to another item they should be calculated.
        /// </summary>
        /// <returns></returns>
        public override QbItemBase Clone()
        {
            QbItemStruct s = new QbItemStruct(this.Root);
            s.Create(this.QbItemType);

            if (this.ItemQbKey != null)
                s.ItemQbKey = this.ItemQbKey.Clone();

            foreach (QbItemBase qib in this.Items)
                s.Items.Add(qib.Clone());

            s.ItemCount = this.ItemCount;

            return s;
        }
Example #3
0
        /// <summary>
        /// Deep clones this item and all children.  Positions and lengths are not cloned.  When inserted in to another item they should be calculated.
        /// </summary>
        /// <returns></returns>
        public override QbItemBase Clone()
        {
            QbItemStruct s = new QbItemStruct(this.Root);

            s.Create(this.QbItemType);

            if (this.ItemQbKey != null)
            {
                s.ItemQbKey = this.ItemQbKey.Clone();
            }

            foreach (QbItemBase qib in this.Items)
            {
                s.Items.Add(qib.Clone());
            }

            s.ItemCount = this.ItemCount;

            return(s);
        }
Example #4
0
        /// <summary>
        /// Clones Tier1 to the battle tiers.
        /// </summary>
        /// <param name="guitarProgressionQb"></param>
        public void EditTiers(QbFile guitarProgressionQb, QbFile storeQb, QbFile songlistQb, QbFile coopQb, bool removeBossBattles, int setTierCount, int bonusSongCount, int[] songCounts, bool unlockTiers)
        {
            bool isGh3 = _project.GameInfo.Game == Game.GH3_Wii;
            int minTierSongCount = int.MaxValue; //so we can work out the encore unlock values

            QbKey qkUnlockSong = _project.GameInfo.Game == Game.GH3_Wii ? QbKey.Create("thrufireandflames") : QbKey.Create("kingsandqueens");
            QbKey qkCreditsSong = QbKey.Create("kingsandqueenscredits");
            bool unlockSongExists = false;
            bool creditsSongExists = false;

            QbKey qkDevil = _project.GameInfo.Game == Game.GH3_Wii ? QbKey.Create("bossdevil") : QbKey.Create(""); //don't do it for Aerosmith
            QbKey[] bossSongs = new QbKey[] { QbKey.Create("bosstom"), QbKey.Create("bossslash"), QbKey.Create("bossdevil"), QbKey.Create("bossjoe") };

            string tierSongsComplete = "career_tier{0}_songscomplete";
            QbFile qb = guitarProgressionQb; //short ref

            QbKey tname = QbKey.Create("name");
            QbKey tcomp = QbKey.Create(string.Format(tierSongsComplete, "1"));

            QbItemStruct[] progs = new QbItemStruct[4];
            string[][] masks = new string[4][];

            List<QbKey> careerSongs = getAllCareerSongs(guitarProgressionQb);
            List<QbKey> bonusSongs = getAllBonusSongs(storeQb);
            int usedSong = 0;

            if (removeBossBattles)
            {
                foreach (QbKey qk in bossSongs)
                    careerSongs.Remove(qk);
            }

            if (songCounts != null)
            {
                //find TTFAF or KQ and remove, it will be added as the last song of the career
                for (int c = careerSongs.Count - 1; c >= 0; c--)
                {
                    QbKey qk = careerSongs[c];
                    if (qk.Crc == qkUnlockSong.Crc || qk.Crc == qkCreditsSong.Crc) //TTFAF or KQ (no credits)
                    {
                        careerSongs.Remove(qk);
                        if (qk.Crc == qkUnlockSong.Crc)
                            unlockSongExists = true;
                        else
                            creditsSongExists = true;
                    }
                }

                for (int c = bonusSongs.Count - 1; c >= 0; c--)
                {
                    QbKey qk = bonusSongs[c];
                    if (qk.Crc == qkUnlockSong.Crc || qk.Crc == qkCreditsSong.Crc) //TTFAF or KQ (no credits)
                    {
                        removeBonusSong(storeQb, qk);
                        bonusSongs.Remove(qk);
                        if (qk.Crc == qkUnlockSong.Crc)
                            unlockSongExists = true;
                        else
                            creditsSongExists = true;
                    }
                }
            }
            else if (removeBossBattles && isGh3) //add TTFAF to the end of the career tiers
            {
                for (int c = bonusSongs.Count - 1; c >= 0; c--)
                {
                    QbKey qk = bonusSongs[c];
                    if (qk.Crc == qkUnlockSong.Crc) //TTFAF
                    {
                        removeBonusSong(storeQb, qk);
                        bonusSongs.Remove(qk);
                        unlockSongExists = true;
                        break;
                    }
                }
            }

            //remove the boss items and set to encore
            QbItemStruct careerSongsSec = qb.FindItem(QbKey.Create("GH3_Career_Songs"), false) as QbItemStruct;
            QbItemInteger qbNumTiers = careerSongsSec.FindItem(QbKey.Create("num_tiers"), false) as QbItemInteger;
            int currTierCount = (int)qbNumTiers.Values[0];

            if (setTierCount != 0 && currTierCount != setTierCount)
            {
                setCareerTiers(careerSongsSec, currTierCount, setTierCount, unlockTiers);
                qbNumTiers.Values[0] = (uint)setTierCount;
            }

            if (setTierCount == 0)
                setTierCount = currTierCount; //no change

            #region career editing

            if (careerSongsSec != null)
            {
                QbKey qkEncore = QbKey.Create("encorep1");
                QbKey qkAeroEncore = QbKey.Create("aerosmith_encore_p1");
                QbKey qkBoss = QbKey.Create("boss");
                QbKey qkLevel = QbKey.Create("level");
                QbKey qkSongs = QbKey.Create("songs");
                QbKey qkUnlocked = QbKey.Create("defaultunlocked");
                QbKey qkNumTiers = QbKey.Create("num_tiers");

                int tierCount = 0;
                int tierNo = 0;

                //remove Through the fire and flames. It can only be unlocked with the cheat or by beating the devil
                //this.RemoveBonusSongQbItems(QbKey.Create("thrufireandflames"), storeQb);

                foreach (QbItemBase qib in careerSongsSec.Items)
                {
                    bool hasEncore = false;
                    bool hasBoss = false;
                    List<QbKey> sngs = null;

                    if (qib is QbItemInteger && qib.ItemQbKey != null && qib.ItemQbKey.Crc == qkNumTiers.Crc)
                        tierCount = (int)((QbItemInteger)qib).Values[0];

                    if (qib is QbItemStruct)
                    {
                        tierNo++; //assume they QB hold them in order

                        foreach (QbItemBase qib2 in qib.Items)
                        {
                            bool devilRemoved = false;
                            QbKey qiQk = null;
                            if (qib2.QbItemType == QbItemType.StructItemArray) //find songs to be removed
                            {
                                qiQk = qib2.ItemQbKey;
                                if (qiQk.Crc == qkSongs.Crc)
                                {
                                    if (removeBossBattles) //remove the battles if required
                                    {
                                        sngs = new List<QbKey>(((QbItemQbKey)qib2.Items[0]).Values);
                                        for (int si = sngs.Count - 1; si >= 0; si--)
                                        {
                                            foreach (QbKey k in bossSongs)
                                            {
                                                if (sngs[si].Crc == k.Crc)
                                                {
                                                    devilRemoved = k == qkDevil; //is it the devil?
                                                    removeSongFromSonglist(songlistQb, k);
                                                    sngs.RemoveAt(si--); //remove the boss song from the list
                                                }
                                            }
                                        }
                                    }

                                    //are we to modify the career tier song counts
                                    if (songCounts != null)
                                    {
                                        //set the career tier songs
                                        int tierSongs = songCounts[Math.Min(songCounts.Length - 1, tierNo - 1)];
                                        sngs.Clear();

                                        for (int i = 0; i < tierSongs; i++)
                                        {
                                            //last song of the career, use TTFAF or KQ (no credits)
                                            if (tierNo == tierCount && i == tierSongs - 1 && unlockSongExists)
                                            {
                                                careerSongs.Insert(usedSong, qkUnlockSong);
                                            }
                                            else if (usedSong >= careerSongs.Count)
                                            {
                                                //move song from bonus to career tier
                                                removeBonusSong(storeQb, bonusSongs[0]);
                                                careerSongs.Add(bonusSongs[0]);
                                                bonusSongs.RemoveAt(0);
                                            }

                                            sngs.Add(careerSongs[usedSong++]);
                                        }

                                    }
                                    else if (isGh3 && removeBossBattles && devilRemoved) //if tier songs are not to be edited then add ttfaf to the last tier (replace devil battle)
                                    {
                                        sngs.Add(qkUnlockSong);
                                    }

                                    if (sngs.Count < minTierSongCount)
                                        minTierSongCount = sngs.Count;

                                    ((QbItemQbKey)qib2.Items[0]).Values = sngs.ToArray();
                                }
                            }
                            else if (qib2.QbItemType == QbItemType.StructItemQbKey) //set the encore flag on all tiers, remove the boss
                            {
                                qiQk = ((QbItemQbKey)qib2).Values[0];
                                if (qiQk.Crc == qkEncore.Crc)
                                    hasEncore = true;
                                else if (qiQk.Crc == qkBoss.Crc || qiQk.Crc == qkAeroEncore.Crc)
                                {
                                    if (hasEncore) //just remove the boss or Aerosmith item
                                        qib.RemoveItem(qib2);
                                    else
                                        ((QbItemQbKey)qib2).Values[0] = QbKey.Create("encorep1");
                                    hasBoss = true;
                                    break;
                                }
                                else if (qiQk.Crc == qkLevel.Crc && !hasBoss && !hasEncore)
                                {
                                    QbItemQbKey enc = new QbItemQbKey(qib2.Root);
                                    enc.Create(QbItemType.StructItemQbKey);
                                    enc.Values = new QbKey[] { QbKey.Create("encorep1") };
                                    //insert new item
                                    qib.InsertItem(enc, qib2, true);
                                    break;
                                }
                            }
                            else if (qib2.QbItemType == QbItemType.StructItemInteger)
                            {
                                if (qib2.ItemQbKey != null && qib2.ItemQbKey.Crc == qkUnlocked.Crc && sngs != null && ((QbItemInteger)qib2).Values[0] < (uint)sngs.Count - 1)
                                    ((QbItemInteger)qib2).Values[0] = (uint)sngs.Count - 1;
                            }

                        }
                    }
                }

                if (songCounts == null)
                    usedSong = careerSongs.Count; //songs not touched

                //move the remaining Career Songs to the bonus section - ttfaf will not be the last song
                while (usedSong < careerSongs.Count)
                {
                    bonusSongs.Insert(0, careerSongs[careerSongs.Count - 1]);
                    this.AddBonusSongQbItems(careerSongs[careerSongs.Count - 1], storeQb, true);
                    careerSongs.RemoveAt(careerSongs.Count - 1);
                }

                while (bonusSongs.Count != 0 && bonusSongs.Count > bonusSongCount)
                {
                    this.BonusSongRemoveFromGame(storeQb, songlistQb, bonusSongs[bonusSongs.Count - 1]); //remove from set list also
                    //removeBonusSong(storeQb, bonusSongs[bonusSongs.Count - 1]);
                    bonusSongs.RemoveAt(bonusSongs.Count - 1);
                }

                //set the last bonus song to the creditsSongExists song
                if (!isGh3 && creditsSongExists)
                {
                    if (bonusSongs.Count != 0 && bonusSongs.Count == bonusSongCount) //remove last song
                    {
                        this.BonusSongRemoveFromGame(storeQb, songlistQb, bonusSongs[bonusSongs.Count - 1]); //remove from set list also
                        //removeBonusSong(storeQb, bonusSongs[bonusSongs.Count - 1]);
                        bonusSongs.RemoveAt(bonusSongs.Count - 1);
                    }
                    bonusSongs.Add(qkCreditsSong);
                    this.AddBonusSongQbItems(qkCreditsSong, storeQb, false);
                }

                //System.Diagnostics.Debug.WriteLine("\r\nCAREER\r\n");
                //foreach (QbKey q1 in careerSongs)
                //    System.Diagnostics.Debug.WriteLine(q1.Text);
                //System.Diagnostics.Debug.WriteLine("\r\nBONUS\r\n");
                //foreach (QbKey q1 in bonusSongs)
                //    System.Diagnostics.Debug.WriteLine(q1.Text);

                //set the songs to unlock section
                unlockXSongsToProgress(guitarProgressionQb,
                    Math.Max(1, (int)(minTierSongCount * 0.65)),
                    Math.Max(1, (int)(minTierSongCount * 0.75)),
                    Math.Max(1, (int)(minTierSongCount * 0.85)),
                    Math.Max(1, (int)(minTierSongCount * 0.95)),
                    Math.Max(1, bonusSongs.Count));
            }

            #endregion

            //modify the progression rules.
            QbItemArray careerProgSec = qb.FindItem(QbKey.Create("GH3_Career_Progression"), false) as QbItemArray;
            if (careerProgSec != null)
            {
                //use this temp
                progs[0] = findTierProgStruct(QbKey.Create("career_tier1_intro_songscomplete"), careerProgSec);
                if (progs[0] != null)
                    careerProgSec.Items[0].RemoveItem(progs[0]);

                progs[0] = findTierProgStruct(QbKey.Create("career_tier1_songscomplete"), careerProgSec);
                masks[0] = new string[] { "career_tier{0}_songscomplete", "career_tier{0}_complete" };
                progs[1] = findTierProgStruct(QbKey.Create("career_tier1_encoreunlock"), careerProgSec);
                masks[1] = new string[] { "career_tier{0}_encoreunlock", "career_tier{0}_songscomplete" };
                progs[2] = findTierProgStruct(QbKey.Create("career_tier1_encorecomplete"), careerProgSec);
                masks[2] = new string[] { "career_tier{0}_encorecomplete", "career_tier{0}_encoreunlock" };
                progs[3] = findTierProgStruct(QbKey.Create("career_tier1_complete"), careerProgSec);
                masks[3] = new string[] { "career_tier{0}_complete", "career_tier{0}_songscomplete", "career_tier{0}_encorecomplete" };
                progs[0] = (QbItemStruct)progs[0].Clone(); //we need to clone this before modifying it or the modified version will be saved.
                addDependencyToTier1SongsComplete(progs[0]);

                QbItemStruct copy = null;
                QbItemStruct last = progs[3]; //insert new items after this one
                QbItemBase rem = null;

                if (setTierCount == 1)
                    insertFinishGame(progs[3]);

                //set all prog items that trigger when completing the last tier
                QbKey qkCurr = QbKey.Create(string.Format("career_tier{0}_complete", currTierCount.ToString()));
                QbKey qkLast = QbKey.Create(string.Format("career_tier{0}_complete", setTierCount.ToString()));
                QbKey qkAtom = QbKey.Create("atom");
                careerProgSec.FindItem(true, delegate(QbItemBase qib)
                    {
                        if (qib.ItemQbKey != null && qib.ItemQbKey.Crc == qkAtom.Crc && ((QbItemQbKey)qib).Values[0].Crc == qkCurr.Crc)
                            ((QbItemQbKey)qib).Values[0] = qkLast.Clone(); //set to new last value
                        return false;
                    });

                //copy tier 1 to all tiers
                for (int t = 2; t <= Math.Max(setTierCount, currTierCount); t++)
                {
                    //remove the boss items
                    rem = findTierProgStruct(QbKey.Create(string.Format("career_tier{0}_bosscomplete", t.ToString())), careerProgSec);
                    if (rem != null)
                        careerProgSec.Items[0].RemoveItem(rem);
                    rem = findTierProgStruct(QbKey.Create(string.Format("career_tier{0}_bossunlock", t.ToString())), careerProgSec);
                    if (rem != null)
                        careerProgSec.Items[0].RemoveItem(rem);

                    rem = findTierProgStruct(QbKey.Create(string.Format("career_tier{0}_intro_songscomplete", t.ToString())), careerProgSec);
                    if (rem != null)
                        careerProgSec.Items[0].RemoveItem(rem);

                    for (int p = 0; p < progs.Length; p++)
                    {
                        //replace all 1s for our new number
                        copy = copyTierProg(progs[p], t, masks[p]);

                        //remove the existing item if present
                        rem = findTierProgStruct(((QbItemQbKey)copy.Items[0]).Values[0], careerProgSec);
                        careerProgSec.Items[0].RemoveItem(rem);

                        if (t <= setTierCount)
                        {
                            if (t == setTierCount && p == progs.Length - 1)
                                insertFinishGame(copy);
                            careerProgSec.Items[0].InsertItem(copy, last, false);
                        }
                        qb.AlignPointers();
                        qb.IsValid();

                        last = copy;
                    }
                }
            }

            QbItemStruct[] src = new QbItemStruct[] { (QbItemStruct)qb.FindItem(QbKey.Create("GH3_General_Songs"), false),
                                                      (QbItemStruct)qb.FindItem(QbKey.Create("GH3_GeneralP2_Songs"), false),
                                                      (QbItemStruct)qb.FindItem(QbKey.Create("GH3_GeneralP2_Songs_Coop"), false) };
            for (int i = 0; i < src.Length; i++)
            {
                if (src[i] != null)
                {
                    QbItemStruct dst = copyCareerTiers(careerSongsSec, src[i]);
                    qb.InsertItem(dst, src[i], true);
                    qb.RemoveItem(src[i]);
                    qb.AlignPointers();
                    qb.IsValid();
                }
            }

            if (coopQb != null)
            {
                copyCareerTiersToCoop(coopQb, guitarProgressionQb);
            }
        }
Example #5
0
        private void insertFinishGame(QbItemStruct prog)
        {
            prog.FindItem(true, delegate(QbItemBase qib)
            {
                if (qib is QbItemStruct && qib.ItemQbKey.Crc == QbKey.Create("atom_params").Crc)
                {
                    QbItemQbKey qk = new QbItemQbKey(prog.Root);
                    qk.Create(QbItemType.StructItemQbKey);
                    qk.Values = new QbKey[] { QbKey.Create("finished_game") };
                    ((QbItemStruct)qib).AddItem(qk);
                    return true; //stop after the first find
                }

                return false; //return false to continue search
            });
        }
Example #6
0
        private void setCareerTiers(QbItemStruct careerSongsSec, int existingTierCount, int newTierCount, bool setUnlockIfOneTier)
        {
            //if setUnlockIfOneTier is false and we only have only 1 tier then don't unlock the new tiers, if tier 2 exists the lock is clones from that

            int add = newTierCount - existingTierCount;

            int clone;
            QbKey qkTier;
            QbKey qkNewTier;
            QbKey qkLastTier = QbKey.Create(string.Format("tier{0}", newTierCount.ToString()));

            for (int t = existingTierCount + 1; t <= newTierCount; t++)
            {
                int origTiersCount = Math.Min(existingTierCount, (_project.GameInfo.Game == Game.GH3_Wii) ? 8 : 6); //6 for aerosmith
                clone = t % origTiersCount;
                if (clone == 0)
                    clone = origTiersCount;

                qkTier = QbKey.Create(string.Format("tier{0}", clone.ToString()));
                qkNewTier = QbKey.Create(string.Format("tier{0}", t.ToString()));

                QbItemStruct clonedTier = careerSongsSec.FindItem(qkTier, false).Clone() as QbItemStruct;
                clonedTier.ItemQbKey = qkNewTier.Clone();

                if (clone == 1) //if tier 1 is being cloned then check is tier 1 has the unlocked value and make this the same
                {
                    QbItemStruct tier2 = careerSongsSec.FindItem(QbKey.Create("tier2"), false) as QbItemStruct;
                    if (tier2 != null)
                    {
                        tier2 = tier2.Clone() as QbItemStruct;
                        QbItemInteger ul = tier2.FindItem(QbKey.Create("defaultunlocked"), false) as QbItemInteger;
                        if (ul == null) //remove the cloned item
                        {
                            if ((ul = clonedTier.FindItem(QbKey.Create("defaultunlocked"), false) as QbItemInteger) != null)
                                clonedTier.RemoveItem(ul);
                        }
                    }
                    else if (!setUnlockIfOneTier)
                    {
                        //clear lock
                        QbItemInteger ul = clonedTier.FindItem(QbKey.Create("defaultunlocked"), false) as QbItemInteger;
                        if (ul != null)
                            clonedTier.RemoveItem(ul);
                    }

                }

                careerSongsSec.AddItem(clonedTier);
            }

            while (careerSongsSec.Items.Count > 3 && careerSongsSec.Items[careerSongsSec.Items.Count - 1].ItemQbKey.Crc != qkLastTier.Crc)
                careerSongsSec.RemoveItem(careerSongsSec.Items[careerSongsSec.Items.Count - 1]); //remove last item

            careerSongsSec.Root.AlignPointers();
            careerSongsSec.Root.IsValid();
        }
Example #7
0
        private QbItemStruct copyCareerTiers(QbItemStruct careerSongsSec, QbItemStruct toTier)
        {
            //all other tier structs have encore2 in them so add it. and no completion movie item
            QbItemBase tmp;

            QbKey qkInitialMovie = QbKey.Create("initial_movie");
            QbKey qkCompletionMovie = QbKey.Create("completion_movie");
            QbKey qkEncoreP1 = QbKey.Create("encorep1");

            QbKey qkPrefix = QbKey.Create("prefix");
            string prefix = ((QbItemString)toTier.FindItem(qkPrefix, false)).Strings[0];

            QbItemStruct to = (QbItemStruct)careerSongsSec.Clone();

            if ((tmp = to.FindItem(qkInitialMovie, false)) != null)
                to.RemoveItem(tmp); //remove initial move if found

            to.ItemQbKey = toTier.ItemQbKey.Clone();
            ((QbItemString)to.FindItem(qkPrefix, false)).Strings[0] = prefix;

            QbItemQbKey encorep2 = new QbItemQbKey(to.Root);
            encorep2.Create(QbItemType.StructItemQbKey);
            encorep2.Values = new QbKey[] { QbKey.Create("encorep2") };

            foreach (QbItemBase qb in to.Items)
            {
                if (qb.QbItemType == QbItemType.StructItemStruct)
                {
                    if ((tmp = qb.FindItem(qkCompletionMovie, false)) != null)
                        qb.RemoveItem(tmp); //remove initial move if found

                    if ((tmp = qb.FindItem(false, delegate (QbItemBase q)
                        {
                            return (qb.QbItemType == QbItemType.StructItemQbKey && qb.ItemQbKey != null && qb.ItemQbKey.Crc == 0 && ((QbItemQbKey)qb).Values[0].Crc == qkEncoreP1.Crc);
                        })) != null)
                    {
                        qb.InsertItem(encorep2.Clone(), tmp, false);
                    }
                }
            }

            return to;
        }
Example #8
0
        private QbItemStruct copyTierProg(QbItemStruct prog, int toTierNo, params string[] qbKeyMask)
        {
            QbItemStruct copy = (QbItemStruct)prog.Clone();

            //replace all 1s for our new number
            copy.FindItem(true, delegate(QbItemBase qib)
                {
                    if (qib.ItemQbKey != null)
                    {
                        if (qib is QbItemInteger && qib.ItemQbKey.Crc == QbKey.Create("tier").Crc)
                            ((QbItemInteger)qib).Values[0] = (uint)toTierNo;
                        else if (qib is QbItemQbKey)
                        {
                            foreach (string s in qbKeyMask)
                            {
                                QbKey k = QbKey.Create(string.Format(s, "1"));
                                QbKey k2 = QbKey.Create(string.Format(s, "0"));

                                if (((QbItemQbKey)qib).Values[0].Crc == k.Crc)
                                    ((QbItemQbKey)qib).Values[0] = QbKey.Create(string.Format(s, toTierNo.ToString()));
                                else if (((QbItemQbKey)qib).Values[0].Crc == k2.Crc)
                                    ((QbItemQbKey)qib).Values[0] = QbKey.Create(string.Format(s, (toTierNo - 1).ToString()));
                            }
                        }
                    }
                    return false; //return false to continue search
                });
            return copy;
        }
Example #9
0
        public static QbItemStruct CreateSong(QbFile root, string songname)
        {
            QbItemStruct song = new QbItemStruct(root);
            song.Create(QbItemType.StructItemStruct);
            song.ItemQbKey = QbKey.Create(songname);

            QbItemQbKey checksum = new QbItemQbKey(root);
            checksum.Create(QbItemType.StructItemQbKey);
            checksum.ItemQbKey = QbKey.Create("checksum");
            checksum.Values = new QbKey[] { QbKey.Create(songname) };
            song.AddItem(checksum);

            QbItemString name = new QbItemString(root);
            name.Create(QbItemType.StructItemString);
            name.ItemQbKey = QbKey.Create("name");
            name.Strings = new string[] { songname };
            song.AddItem(name);

            QbItemString title = new QbItemString(root);
            title.Create(QbItemType.StructItemString);
            title.ItemQbKey = QbKey.Create("title");
            title.Strings = new string[] { songname };
            song.AddItem(title);

            QbItemString artist = new QbItemString(root);
            artist.Create(QbItemType.StructItemString);
            artist.ItemQbKey = QbKey.Create("artist");
            artist.Strings = new string[] { songname };
            song.AddItem(artist);

            QbItemString year = new QbItemString(root);
            year.Create(QbItemType.StructItemString);
            year.ItemQbKey = QbKey.Create("year");
            year.Strings = new string[] { string.Empty };
            song.AddItem(year);

            QbItemQbKey artistText = new QbItemQbKey(root);
            artistText.Create(QbItemType.StructItemQbKeyString);
            artistText.ItemQbKey = QbKey.Create("artist_text");
            artistText.Values = new QbKey[] { QbKey.Create("artist_text_by") };
            song.AddItem(artistText);

            QbItemInteger originalArtist = new QbItemInteger(root);
            originalArtist.Create(QbItemType.StructItemInteger);
            originalArtist.ItemQbKey = QbKey.Create("original_artist");
            originalArtist.Values = new uint[] { 1 };
            song.AddItem(originalArtist);

            QbItemQbKey version = new QbItemQbKey(root);
            version.Create(QbItemType.StructItemQbKey);
            version.ItemQbKey = QbKey.Create("version");
            version.Values = new QbKey[] { QbKey.Create("gh3") };
            song.AddItem(version);

            QbItemInteger leaderboard = new QbItemInteger(root);
            leaderboard.Create(QbItemType.StructItemInteger);
            leaderboard.ItemQbKey = QbKey.Create("leaderboard");
            leaderboard.Values = new uint[] { 1 };
            song.AddItem(leaderboard);

            QbItemInteger gemOffset = new QbItemInteger(root);
            gemOffset.Create(QbItemType.StructItemInteger);
            gemOffset.ItemQbKey = QbKey.Create("gem_offset");
            gemOffset.Values = new uint[] { 0 };
            song.AddItem(gemOffset);

            QbItemInteger inputOffset = new QbItemInteger(root);
            inputOffset.Create(QbItemType.StructItemInteger);
            inputOffset.ItemQbKey = QbKey.Create("input_offset");
            inputOffset.Values = new uint[] { 0 };
            song.AddItem(inputOffset);

            QbItemQbKey singer = new QbItemQbKey(root);
            singer.Create(QbItemType.StructItemQbKey);
            singer.ItemQbKey = QbKey.Create("singer");
            singer.Values = new QbKey[] { QbKey.Create("male") };
            song.AddItem(singer);

            QbItemQbKey keyboard = new QbItemQbKey(root);
            keyboard.Create(QbItemType.StructItemQbKey);
            keyboard.ItemQbKey = QbKey.Create("keyboard");
            keyboard.Values = new QbKey[] { QbKey.Create("false") };
            song.AddItem(keyboard);

            QbItemFloat bandPlaybackVolume = new QbItemFloat(root);
            bandPlaybackVolume.Create(QbItemType.StructItemFloat);
            bandPlaybackVolume.ItemQbKey = QbKey.Create("band_playback_volume");
            bandPlaybackVolume.Values = new float[] { 0F };
            song.AddItem(bandPlaybackVolume);

            QbItemFloat guitarPlaybackVolume = new QbItemFloat(root);
            guitarPlaybackVolume.Create(QbItemType.StructItemFloat);
            guitarPlaybackVolume.ItemQbKey = QbKey.Create("guitar_playback_volume");
            guitarPlaybackVolume.Values = new float[] { 0F };
            song.AddItem(guitarPlaybackVolume);

            QbItemString countOff = new QbItemString(root);
            countOff.Create(QbItemType.StructItemString);
            countOff.ItemQbKey = QbKey.Create("countoff");
            countOff.Strings = new string[] { "sticks_normal" };
            song.AddItem(countOff);

            QbItemInteger rhythmTrack = new QbItemInteger(root);
            rhythmTrack.Create(QbItemType.StructItemInteger);
            rhythmTrack.ItemQbKey = QbKey.Create("rhythm_track");
            rhythmTrack.Values = new uint[] { 0 };
            song.AddItem(rhythmTrack);

            return song;
        }
Example #10
0
        /// <summary>
        /// All but this tier 1 have a dependency on the previous tier being completed
        /// </summary>
        /// <param name="tier"></param>
        private void addDependencyToTier1SongsComplete(QbItemStruct prog)
        {
            //insert dependency on previous tier.  Obviously tier 0 does exist, it's just for replacement purposes
            QbItemBase qbs = prog.Items[prog.Items.Count - 1];
            if (qbs is QbItemArray)
            {
                QbItemStructArray qsa = (QbItemStructArray)qbs.Items[0];
                QbItemStruct qis = new QbItemStruct(prog.Root);
                qis.Create(QbItemType.StructHeader);

                QbItemQbKey qbQk = new QbItemQbKey(prog.Root);
                qbQk.Create(QbItemType.StructItemQbKey);
                qbQk.ItemQbKey = QbKey.Create("type");
                qbQk.Values = new QbKey[] { QbKey.Create("atom") };
                qis.AddItem(qbQk);

                qbQk = new QbItemQbKey(prog.Root);
                qbQk.Create(QbItemType.StructItemQbKey);
                qbQk.ItemQbKey = QbKey.Create("atom");
                qbQk.Values = new QbKey[] { QbKey.Create("career_tier0_complete") };
                qis.AddItem(qbQk);

                qsa.InsertItem(qis, qsa.Items[0], true);
            }
        }
Example #11
0
        private void calculateMarkers(int[] frets, QbItemArray arr, QbFile text)
        {
            int minNote = this.Notes.MinNoteOffsetSynced + _startPaddingMs + _fretPadding;
            int maxNote = this.Notes.MaxNoteOffsetSynced + _startPaddingMs + _fretPadding;

            int pos = minNote;

            int sectionSecs = 20000;
            int sections = (maxNote - minNote) / sectionSecs; //every x seconds

            for (int c = text.Items.Count - 1; c > 0; c--)
                text.RemoveItem(text.Items[c]);

            QbItemStructArray sa = new QbItemStructArray(arr.Root);
            sa.Create(QbItemType.ArrayStruct);

            arr.Items.Clear();
            arr.AddItem(sa);

            QbItemStruct s;
            QbItemInteger i;
            QbItemQbKey q;
            string sectionTitle;
            QbKey qbKey;
            QbItemString txt;

            for (int c = 0; c < sections; c++)
            {
                if (pos + 3000 > this.Length)
                    break; //don't create a section less than 3 seconds long

                sectionTitle = string.Format("Section {0}", (c + 1).ToString());
                qbKey = QbKey.Create(string.Format("{0}_markers_text_{1}", this.SongQb.Id, QbKey.Create(sectionTitle).Crc.ToString("x").ToLower()));

                txt = new QbItemString(text);
                txt.Create(QbItemType.SectionString);
                txt.ItemQbKey = qbKey;
                txt.Strings = new string[] { sectionTitle };
                text.AddItem(txt);

                s = new QbItemStruct(arr.Root);
                s.Create(QbItemType.StructHeader);
                sa.AddItem(s);

                i = new QbItemInteger(arr.Root);
                i.Create(QbItemType.StructItemInteger);
                i.ItemQbKey = QbKey.Create("time");
                i.Values = new uint[] { findNearestFret((uint)pos, frets) };
                s.AddItem(i);

                pos += sectionSecs;

                q = new QbItemQbKey(arr.Root);
                q.Create(QbItemType.StructItemQbKeyString);
                q.ItemQbKey = QbKey.Create("marker");
                q.Values = new QbKey[] { qbKey };
                s.AddItem(q);
            }

            text.AlignPointers();
            arr.Root.AlignPointers();
        }
Example #12
0
        private void setMarkers(int[] frets, QbItemArray arr, QbFile text, NotesMarker[] markers)
        {
            int minNote = this.Notes.MinNoteOffsetSynced + _startPaddingMs + _fretPadding;
            QbItemStruct s;
            QbItemInteger i;
            QbItemQbKey q;
            QbKey qbKey;
            QbItemString txt;

            for (int c = text.Items.Count - 1; c > 0; c--)
                text.RemoveItem(text.Items[c]);

            if (arr.Items[0] is QbItemFloats)
            {
                QbItemStructArray newArr = new QbItemStructArray(arr.Root);
                newArr.Create(QbItemType.ArrayStruct);
                arr.AddItem(newArr);
                arr.RemoveItem(arr.Items[0]);
            }

            QbItemStructArray sa = (QbItemStructArray)arr.Items[0];
            sa.Items.Clear();

            NotesMarker marker;

            List<NotesMarker> mrk = new List<NotesMarker>(markers);

            if (mrk.Count > 0 && mrk[0].Offset > minNote)  //some charts don't have sections at the start so you can't practice the start notes :-(
            {
                if (mrk[0].Offset > minNote + 5000) // if > 5secs then add new
                    mrk.Insert(0, new NotesMarker("Start", minNote));
                else //else move first marker back to start
                    mrk[0].Offset = minNote;
            }

            for (int c = 0; c < mrk.Count; c++)
            {
                marker = mrk[c];
                if (c < mrk.Count - 1 && mrk[c + 1].Offset < minNote)
                    continue; //don't add sections at the start that would have no notes (crashes song??)

                qbKey = QbKey.Create(string.Format("{0}_markers_text_{1}", this.SongQb.Id, QbKey.Create(marker.Title).Crc.ToString("x").ToLower()));

                txt = new QbItemString(text);
                txt.Create(QbItemType.SectionString);
                txt.ItemQbKey = qbKey;
                txt.Strings = new string[] { marker.Title };
                text.AddItem(txt);

                s = new QbItemStruct(arr.Root);
                s.Create(QbItemType.StructHeader);
                sa.AddItem(s);

                i = new QbItemInteger(arr.Root);
                i.Create(QbItemType.StructItemInteger);
                i.ItemQbKey = QbKey.Create("time");
                i.Values = new uint[] { findNearestFret((uint)marker.Offset, frets) };
                s.AddItem(i);

                q = new QbItemQbKey(arr.Root);
                q.Create(QbItemType.StructItemQbKeyString);
                q.ItemQbKey = QbKey.Create("marker");
                q.Values = new QbKey[] { qbKey };
                s.AddItem(q);
            }
            text.AlignPointers();
            arr.Root.AlignPointers();
        }
Example #13
0
        private void parse(Stream stream)
        {
            _streamStartPosition = stream.Position;

            _items = new List <QbItemBase>();

            //if (stream.Position != 0)
            //    throw new ApplicationException("The stream must start at position 0 as this parser uses the position to validate pointers.");

            using (BinaryEndianReader br = new BinaryEndianReader(stream))
            {
                _magic    = br.ReadUInt32(this.PakFormat.EndianType);
                _fileSize = br.ReadUInt32(this.PakFormat.EndianType);

                uint sectionValue;

                QbItemBase qib = new QbItemUnknown(20, this);
                qib.Construct(br, QbItemType.Unknown);
                AddItem(qib);

                while (this.StreamPos(br.BaseStream) < _fileSize)
                {
                    sectionValue = br.ReadUInt32(this.PakFormat.EndianType);
                    QbItemType sectionType = this.PakFormat.GetQbItemType(sectionValue);

                    switch (sectionType)
                    {
                    case QbItemType.SectionString:
                    case QbItemType.SectionStringW:
                        qib = new QbItemString(this);
                        break;

                    case QbItemType.SectionArray:
                        qib = new QbItemArray(this);
                        break;

                    case QbItemType.SectionStruct:
                        qib = new QbItemStruct(this);
                        break;

                    case QbItemType.SectionScript:
                        qib = new QbItemScript(this);
                        break;

                    case QbItemType.SectionFloat:
                        qib = new QbItemFloat(this);
                        break;

                    case QbItemType.SectionFloatsX2:
                    case QbItemType.SectionFloatsX3:
                        qib = new QbItemFloatsArray(this);
                        break;

                    case QbItemType.SectionInteger:
                    case QbItemType.SectionStringPointer:
                        qib = new QbItemInteger(this);
                        break;

                    case QbItemType.SectionQbKey:
                    case QbItemType.SectionQbKeyString:
                    case QbItemType.SectionQbKeyStringQs:     //GH:GH
                        qib = new QbItemQbKey(this);
                        break;

                    default:
                        throw new ApplicationException(string.Format("Location 0x{0}: Unknown section type 0x{1}", (this.StreamPos(br.BaseStream) - 4).ToString("X").PadLeft(8, '0'), sectionValue.ToString("X").PadLeft(8, '0')));
                    }
                    qib.Construct(br, sectionType);

                    AddItem(qib);
                }
            }

            uint f = this.FileId; //gettin this sets the file id
        }
Example #14
0
        private static QbItemBase createQbItemType(QbFile qbFile, QbItemType type, QbFormat qbFormat, bool hasQbFormat)
        {
            QbItemBase qib = null;

            if (qbFile.PakFormat.GetQbItemValue(type, qbFile) == 0xFFFFFFFF)
                throw new ApplicationException(string.Format("'{0}' data value not known for {1}", type.ToString(), qbFile.PakFormat.FriendlyName));

            switch (type)
            {
                //case QbItemType.Unknown:
                //    break;

                case QbItemType.SectionString:
                case QbItemType.SectionStringW:
                case QbItemType.ArrayString:
                case QbItemType.ArrayStringW:
                case QbItemType.StructItemString:
                case QbItemType.StructItemStringW:
                    qib = new QbItemString(qbFile);
                    break;
                case QbItemType.SectionArray:
                case QbItemType.ArrayArray:
                case QbItemType.StructItemArray:
                    qib = new QbItemArray(qbFile);
                    break;
                case QbItemType.SectionStruct:
                case QbItemType.StructItemStruct:
                case QbItemType.StructHeader:
                    qib = new QbItemStruct(qbFile);
                    break;
                case QbItemType.SectionScript:
                    qib = new QbItemScript(qbFile);
                    break;
                case QbItemType.SectionFloat:
                case QbItemType.ArrayFloat:
                case QbItemType.StructItemFloat:
                    qib = new QbItemFloat(qbFile);
                    break;
                case QbItemType.SectionFloatsX2:
                case QbItemType.SectionFloatsX3:
                case QbItemType.ArrayFloatsX2:
                case QbItemType.ArrayFloatsX3:
                case QbItemType.StructItemFloatsX2:
                case QbItemType.StructItemFloatsX3:
                    qib = new QbItemFloatsArray(qbFile);
                    break;
                case QbItemType.SectionInteger:
                case QbItemType.SectionStringPointer:
                case QbItemType.ArrayInteger:
                case QbItemType.ArrayStringPointer: //GH:GH
                case QbItemType.StructItemStringPointer:
                case QbItemType.StructItemInteger:
                    qib = new QbItemInteger(qbFile);
                    break;
                case QbItemType.SectionQbKey:
                case QbItemType.SectionQbKeyString:
                case QbItemType.SectionQbKeyStringQs: //GH:GH
                case QbItemType.ArrayQbKey:
                case QbItemType.ArrayQbKeyString:
                case QbItemType.ArrayQbKeyStringQs: //GH:GH
                case QbItemType.StructItemQbKey:
                case QbItemType.StructItemQbKeyString:
                case QbItemType.StructItemQbKeyStringQs:
                    qib = new QbItemQbKey(qbFile);
                    break;
                case QbItemType.Floats:
                    qib = new QbItemFloats(qbFile);
                    break;
                case QbItemType.ArrayStruct:
                    qib = new QbItemStructArray(qbFile);
                    break;

                default:
                    throw new ApplicationException(string.Format("'{0}' is not recognised by CreateQbItemType.", type.ToString()));
            }
            if (qib != null)
                qib.Create(type);

            return qib;
        }
Example #15
0
        private static QbItemBase createQbItemType(QbFile qbFile, QbItemType type, QbFormat qbFormat, bool hasQbFormat)
        {
            QbItemBase qib = null;

            if (qbFile.PakFormat.GetQbItemValue(type, qbFile) == 0xFFFFFFFF)
            {
                throw new ApplicationException(string.Format("'{0}' data value not known for {1}", type.ToString(), qbFile.PakFormat.FriendlyName));
            }

            switch (type)
            {
            //case QbItemType.Unknown:
            //    break;

            case QbItemType.SectionString:
            case QbItemType.SectionStringW:
            case QbItemType.ArrayString:
            case QbItemType.ArrayStringW:
            case QbItemType.StructItemString:
            case QbItemType.StructItemStringW:
                qib = new QbItemString(qbFile);
                break;

            case QbItemType.SectionArray:
            case QbItemType.ArrayArray:
            case QbItemType.StructItemArray:
                qib = new QbItemArray(qbFile);
                break;

            case QbItemType.SectionStruct:
            case QbItemType.StructItemStruct:
            case QbItemType.StructHeader:
                qib = new QbItemStruct(qbFile);
                break;

            case QbItemType.SectionScript:
                qib = new QbItemScript(qbFile);
                break;

            case QbItemType.SectionFloat:
            case QbItemType.ArrayFloat:
            case QbItemType.StructItemFloat:
                qib = new QbItemFloat(qbFile);
                break;

            case QbItemType.SectionFloatsX2:
            case QbItemType.SectionFloatsX3:
            case QbItemType.ArrayFloatsX2:
            case QbItemType.ArrayFloatsX3:
            case QbItemType.StructItemFloatsX2:
            case QbItemType.StructItemFloatsX3:
                qib = new QbItemFloatsArray(qbFile);
                break;

            case QbItemType.SectionInteger:
            case QbItemType.SectionStringPointer:
            case QbItemType.ArrayInteger:
            case QbItemType.ArrayStringPointer:     //GH:GH
            case QbItemType.StructItemStringPointer:
            case QbItemType.StructItemInteger:
                qib = new QbItemInteger(qbFile);
                break;

            case QbItemType.SectionQbKey:
            case QbItemType.SectionQbKeyString:
            case QbItemType.SectionQbKeyStringQs:     //GH:GH
            case QbItemType.ArrayQbKey:
            case QbItemType.ArrayQbKeyString:
            case QbItemType.ArrayQbKeyStringQs:     //GH:GH
            case QbItemType.StructItemQbKey:
            case QbItemType.StructItemQbKeyString:
            case QbItemType.StructItemQbKeyStringQs:
                qib = new QbItemQbKey(qbFile);
                break;

            case QbItemType.Floats:
                qib = new QbItemFloats(qbFile);
                break;

            case QbItemType.ArrayStruct:
                qib = new QbItemStructArray(qbFile);
                break;

            default:
                throw new ApplicationException(string.Format("'{0}' is not recognised by CreateQbItemType.", type.ToString()));
            }
            if (qib != null)
            {
                qib.Create(type);
            }

            return(qib);
        }
Example #16
0
        internal SongQb(Project project, QbItemStruct song)
        {
            _song = song;
            QbItemBase temp;

            _hopoMeasure = null;

            _checksum = (QbItemQbKey)song.FindItem(QbKey.Create("checksum"), false);
            //_key = song.ItemQbKey;
            _key = QbKey.Create(((QbItemString)song.FindItem(QbKey.Create("name"), false)).Strings[0]);

            _title = (QbItemString)song.FindItem(QbKey.Create("title"), false);
            _artist = (QbItemString)song.FindItem(QbKey.Create("artist"), false);

            _leaderboard = (QbItemInteger)song.FindItem(QbKey.Create("leaderboard"), false);
            _year = (QbItemString)song.FindItem(QbKey.Create("year"), false);

            _boss = song.FindItem(QbKey.Create("boss"), false) as QbItemQbKey;  //is this a boss

            temp = song.FindItem(QbKey.Create("band_playback_volume"), false);  //sometimes integer instead of float
            if (temp == null)
            {
                _songVolume = new QbItemFloat(song.Root);
                _songVolume.Create(QbItemType.StructItemFloat);
                _songVolume.ItemQbKey = QbKey.Create("band_playback_volume");
                _songVolume.Values = new float[1];
                _songVolume.Values[0] = 0;
                song.AddItem(_songVolume);
                song.Root.AlignPointers();
            }
            else if (temp is QbItemInteger)
                _songVolume = replaceItemIntForFloat(song, (QbItemInteger)temp);
            else
                _songVolume = (QbItemFloat)temp;

            temp = song.FindItem(QbKey.Create("guitar_playback_volume"), false);  //sometimes integer instead of float
            if (temp == null)
            {
                _guitarVolume = new QbItemFloat(song.Root);
                _guitarVolume.Create(QbItemType.StructItemFloat);
                _guitarVolume.ItemQbKey = QbKey.Create("guitar_playback_volume");
                _guitarVolume.Values = new float[1];
                _guitarVolume.Values[0] = 0;
                song.AddItem(_guitarVolume);
                song.Root.AlignPointers();
            }
            else if (temp is QbItemInteger)
                _guitarVolume = replaceItemIntForFloat(song, (QbItemInteger)temp);
            else
                _guitarVolume = (QbItemFloat)temp;

            _rhythmTrack = (QbItemInteger)song.FindItem(QbKey.Create("rhythm_track"), false);

            temp = song.FindItem(QbKey.Create("artist_text"), false);
            if (temp is QbItemString)
            {
                _artistTextString = (QbItemString)temp;
                _artistText = null;
            }
            else
            {
                _artistText = song.FindItem(QbKey.Create("artist_text"), false) as QbItemQbKey;
                _artistTextString = null;
            }

            _originalArtist = (QbItemInteger)song.FindItem(QbKey.Create("original_artist"), false);

            temp = song.FindItem(QbKey.Create("singer"), false);
            if (temp == null) //GH3 wii Cream sunshine for your love has no singer item
            {
                _singer = new QbItemQbKey(song.Root);
                _singer.Create(QbItemType.StructItemQbKey);
                _singer.ItemQbKey = QbKey.Create("singer");
                _singer.Values = new QbKey[1];
                _singer.Values[0] = QbKey.Create("male");
                song.AddItem(_singer);
                song.Root.AlignPointers();
            }
            else
                _singer = (QbItemQbKey)temp;

            _fretbarOffset = song.FindItem(QbKey.Create("fretbar_offset"), false) as QbItemInteger;
            _gemOffset = song.FindItem(QbKey.Create("gem_offset"), false) as QbItemInteger;
            _inputOffset = song.FindItem(QbKey.Create("input_offset"), false) as QbItemInteger;

            //this fixes an issue with GH3(cult of personality) and GHA (talk talking)
            if (this.key.Crc != this.checksum.Crc)
                _id = (project.GameInfo.Game == Game.GH3_Wii) ? this.checksum : this.key;
            else
                _id = this.checksum.HasText ? this.checksum : this.key;
        }
Example #17
0
        /// <summary>
        /// Some items are not the correct type, replace them.
        /// </summary>
        /// <param name="song"></param>
        /// <param name="item"></param>
        /// <returns></returns>
        private QbItemFloat replaceItemIntForFloat(QbItemStruct song, QbItemInteger item)
        {
            QbItemFloat f = new QbItemFloat(song.Root);
            f.Create(QbItemType.StructItemFloat);

            f.ItemQbKey = item.ItemQbKey;
            f.Values[0] = item.Values[0];
            song.InsertItem(f, item, true);
            song.RemoveItem(item);
            song.Root.AlignPointers();
            return f;
        }
Example #18
0
        /// <summary>
        /// Add song to bonus list and shop
        /// </summary>
        /// <param name="songQk"></param>
        public void AddBonusSongQbItems(QbKey songQk, QbFile qbStore, bool insertAdd)
        {
            QbKey qkCreditsSong = _project.GameInfo.Game == Game.GH3_Wii ? QbKey.Create("thrufireandflames") : QbKey.Create("kingsandqueenscredits");

            //find bonus song list
            QbItemArray bonusSongs = qbStore.FindItem(QbKey.Create("songs"), true) as QbItemArray;

            //find bonus song price list
            QbItemStruct songData = qbStore.FindItem(QbKey.Create("store_song_data"), true) as QbItemStruct;

            //find bonus song info
            QbItemArray bonusInfo = qbStore.FindItem(QbKey.Create("Bonus_Songs_Info"), true) as QbItemArray;

            //add bonus song to list
            if (bonusSongs != null)
            {
                List<QbKey> songs = new List<QbKey>((bonusSongs.Items[0] as QbItemQbKey).Values);
                if (!songs.Contains(songQk))
                {
                    if (insertAdd)
                        songs.Insert(0, songQk.Clone());
                    else
                    {
                        //insert second from the end (before TTFAF / kingandqueenscredits)
                        if (songs.Count == 0 || songs[songs.Count - 1].Crc != qkCreditsSong.Crc)
                            songs.Add(songQk.Clone()); //clone qbkey
                        else
                            songs.Insert(songs.Count - 1, songQk.Clone()); //clone qbkey
                    }
                    (bonusSongs.Items[0] as QbItemQbKey).Values = songs.ToArray();
                }
            }

            if (songData != null)
            {
                //add bonus song price
                if (null == songData.FindItem(false, delegate(QbItemBase qib)
                    {
                        return (qib.ItemQbKey.Crc == songQk.Crc);
                    }))
                {
                    QbItemStruct songDataItem = new QbItemStruct(qbStore);
                    songDataItem.Create(QbItemType.StructItemStruct);
                    songDataItem.ItemQbKey = songQk.Clone();
                    QbItemInteger songDataItemPrice = new QbItemInteger(qbStore);
                    songDataItemPrice.Create(QbItemType.StructItemInteger);
                    songDataItemPrice.ItemQbKey = QbKey.Create("price");
                    songDataItemPrice.Values = new uint[] { 0 };
                    songDataItem.AddItem(songDataItemPrice);
                    if (!insertAdd || songData.Items.Count == 0)
                        songData.AddItem(songDataItem);
                    else
                        songData.InsertItem(songDataItem, songData.Items[0], true);
                }
            }

            if (bonusInfo != null)
            {
                //add bonus info
                QbKey itemQk = QbKey.Create("item");
                QbItemStructArray infoArray = (bonusInfo.Items[0] as QbItemStructArray);
                if (null == infoArray.FindItem(false, delegate(QbItemBase qib)
                    {
                        QbItemQbKey iqk = (QbItemQbKey)(qib.Items[0]);
                        return iqk.ItemQbKey.Crc == itemQk.Crc && iqk.Values[0] == songQk.Crc;
                    }))
                {
                    QbItemStruct infoStruct = new QbItemStruct(qbStore);
                    infoStruct.Create(QbItemType.StructHeader);
                    if (!insertAdd || infoArray.Items.Count == 0)
                        infoArray.AddItem(infoStruct);
                    else
                        infoArray.InsertItem(infoStruct, infoArray.Items[0], true);
                    qbStore.AlignPointers();
                    qbStore.IsValid();
                    QbItemQbKey infoItem = new QbItemQbKey(qbStore);
                    infoItem.Create(QbItemType.StructItemQbKey);
                    infoItem.ItemQbKey = itemQk; //"item"
                    infoItem.Values = new QbKey[] { songQk.Clone() };
                    infoStruct.AddItem(infoItem);
                    qbStore.AlignPointers();
                    qbStore.IsValid();
                    QbItemString infoText = new QbItemString(qbStore);
                    infoText.Create(QbItemType.StructItemString);
                    infoText.ItemQbKey = QbKey.Create("text");
                    infoText.Strings = new string[] { "Bonus song added with TheGHOST" };
                    infoStruct.AddItem(infoText);
                    qbStore.AlignPointers();
                    qbStore.IsValid();
                    QbItemQbKey infoCover = new QbItemQbKey(qbStore);
                    infoCover.Create(QbItemType.StructItemQbKey);
                    infoCover.ItemQbKey = QbKey.Create("album_cover");
                    infoCover.Values = new QbKey[] { QbKey.Create("store_song_default") };
                    infoStruct.AddItem(infoCover);
                    qbStore.AlignPointers();
                    qbStore.IsValid();
                }
            }
        }
Example #19
0
        public override void Construct(BinaryEndianReader br, QbItemType type)
        {
            //System.Diagnostics.Debug.WriteLine(string.Format("{0} - 0x{1}", type.ToString(), (base.StreamPos(br) - 4).ToString("X").PadLeft(8, '0')));

            base.Construct(br, type);

            uint pointer;

            if (type != QbItemType.StructHeader)
            {
                _headerValue = br.ReadUInt32(base.Root.PakFormat.EndianType);
            }
            else
            {
                _headerValue = base.Root.PakFormat.GetQbItemValue(type, this.Root);
            }

            _headerType = base.Root.PakFormat.GetQbItemType(_headerValue);

            QbItemBase qib = null;
            QbItemType structType;
            uint       structValue;

            if (_headerType == QbItemType.StructHeader)
            {
                pointer = br.ReadUInt32(base.Root.PakFormat.EndianType); //Should be the current stream position after reading

                _iniNextItemPointer = pointer;

                if (pointer != 0 && base.StreamPos(br) != pointer) //pointer test
                {
                    throw new ApplicationException(QbFile.FormatBadPointerExceptionMessage(this, base.StreamPos(br), pointer));
                }

                while (pointer != 0)
                {
                    structValue = br.ReadUInt32(this.Root.PakFormat.EndianType);
                    structType  = this.Root.PakFormat.GetQbItemType(structValue);

                    switch (structType)
                    {
                    case QbItemType.StructItemStruct:
                        this.Root.PakFormat.StructItemChildrenType = StructItemChildrenType.StructItems;
                        qib = new QbItemStruct(this.Root);
                        break;

                    case QbItemType.StructItemStringPointer:
                    case QbItemType.StructItemInteger:
                        this.Root.PakFormat.StructItemChildrenType = StructItemChildrenType.StructItems;
                        qib = new QbItemInteger(this.Root);
                        break;

                    case QbItemType.StructItemQbKeyString:
                    case QbItemType.StructItemQbKeyStringQs:
                    case QbItemType.StructItemQbKey:
                        this.Root.PakFormat.StructItemChildrenType = StructItemChildrenType.StructItems;
                        qib = new QbItemQbKey(this.Root);
                        break;

                    case QbItemType.StructItemString:
                    case QbItemType.StructItemStringW:
                        this.Root.PakFormat.StructItemChildrenType = StructItemChildrenType.StructItems;
                        qib = new QbItemString(this.Root);
                        break;

                    case QbItemType.StructItemFloat:
                        this.Root.PakFormat.StructItemChildrenType = StructItemChildrenType.StructItems;
                        qib = new QbItemFloat(this.Root);
                        break;

                    case QbItemType.StructItemFloatsX2:
                    case QbItemType.StructItemFloatsX3:
                        this.Root.PakFormat.StructItemChildrenType = StructItemChildrenType.StructItems;
                        qib = new QbItemFloatsArray(this.Root);
                        break;

                    case QbItemType.StructItemArray:
                        this.Root.PakFormat.StructItemChildrenType = StructItemChildrenType.StructItems;
                        qib = new QbItemArray(this.Root);
                        break;

                    //Convert array types to structitems to fit in with this parser (if QbFile.HasStructItems is false then internal type will be swapped back to array)
                    case QbItemType.ArrayStruct:
                        structType = QbItemType.StructItemStruct;
                        qib        = new QbItemArray(this.Root);
                        break;

                    case QbItemType.ArrayInteger:
                        structType = QbItemType.StructItemInteger;
                        qib        = new QbItemInteger(this.Root);
                        break;

                    case QbItemType.ArrayQbKeyString:
                        structType = QbItemType.StructItemQbKeyString;
                        qib        = new QbItemQbKey(this.Root);
                        break;

                    case QbItemType.ArrayStringPointer:
                        structType = QbItemType.StructItemStringPointer;
                        qib        = new QbItemInteger(this.Root);
                        break;

                    case QbItemType.ArrayQbKeyStringQs:
                        structType = QbItemType.StructItemQbKeyStringQs;
                        qib        = new QbItemQbKey(this.Root);
                        break;

                    case QbItemType.ArrayQbKey:
                        structType = QbItemType.StructItemQbKey;
                        qib        = new QbItemQbKey(this.Root);
                        break;

                    case QbItemType.ArrayString:
                        structType = QbItemType.StructItemString;
                        qib        = new QbItemString(this.Root);
                        break;

                    case QbItemType.ArrayStringW:
                        structType = QbItemType.StructItemStringW;
                        qib        = new QbItemString(this.Root);
                        break;

                    case QbItemType.ArrayFloat:
                        structType = QbItemType.StructItemFloat;
                        qib        = new QbItemFloat(this.Root);
                        break;

                    case QbItemType.ArrayFloatsX2:
                        structType = QbItemType.StructItemFloatsX2;
                        qib        = new QbItemFloatsArray(this.Root);
                        break;

                    case QbItemType.ArrayFloatsX3:
                        structType = QbItemType.StructItemFloatsX3;
                        qib        = new QbItemFloatsArray(this.Root);
                        break;

                    case QbItemType.ArrayArray:
                        structType = QbItemType.StructItemArray;
                        qib        = new QbItemArray(this.Root);
                        break;

                    default:
                        qib = null;
                        break;
                    }

                    if (qib != null)
                    {
                        if (this.Root.PakFormat.StructItemChildrenType == StructItemChildrenType.NotSet) //will have been set to structItem if qib is not null)
                        {
                            this.Root.PakFormat.StructItemChildrenType = StructItemChildrenType.ArrayItems;
                        }

                        qib.Construct(br, structType);
                        AddItem(qib);
                        pointer = qib.NextItemPointer;
                    }
                    else
                    {
                        throw new ApplicationException(string.Format("Location 0x{0}: Unknown item type 0x{1} in struct ", (base.StreamPos(br) - 4).ToString("X").PadLeft(8, '0'), structValue.ToString("X").PadLeft(8, '0')));
                    }
                }
            }
            else
            {
                throw new ApplicationException(string.Format("Location 0x{0}: Struct without header type", (base.StreamPos(br) - 4).ToString("X").PadLeft(8, '0')));
            }

            base.ConstructEnd(br);
        }
Example #20
0
        private void parse(Stream stream)
        {
            _streamStartPosition = stream.Position;

            _items = new List<QbItemBase>();

            //if (stream.Position != 0)
            //    throw new ApplicationException("The stream must start at position 0 as this parser uses the position to validate pointers.");

            using (BinaryEndianReader br = new BinaryEndianReader(stream))
            {
                _magic = br.ReadUInt32(this.PakFormat.EndianType);
                _fileSize = br.ReadUInt32(this.PakFormat.EndianType);

                uint sectionValue;

                QbItemBase qib = new QbItemUnknown(20, this);
                qib.Construct(br, QbItemType.Unknown);
                AddItem(qib);

                while (this.StreamPos(br.BaseStream) < _fileSize)
                {
                    sectionValue = br.ReadUInt32(this.PakFormat.EndianType);
                    QbItemType sectionType = this.PakFormat.GetQbItemType(sectionValue);

                    switch (sectionType)
                    {
                        case QbItemType.SectionString:
                        case QbItemType.SectionStringW:
                            qib = new QbItemString(this);
                            break;
                        case QbItemType.SectionArray:
                            qib = new QbItemArray(this);
                            break;
                        case QbItemType.SectionStruct:
                            qib = new QbItemStruct(this);
                            break;
                        case QbItemType.SectionScript:
                            qib = new QbItemScript(this);
                            break;
                        case QbItemType.SectionFloat:
                            qib = new QbItemFloat(this);
                            break;
                        case QbItemType.SectionFloatsX2:
                        case QbItemType.SectionFloatsX3:
                            qib = new QbItemFloatsArray(this);
                            break;
                        case QbItemType.SectionInteger:
                        case QbItemType.SectionStringPointer:
                            qib = new QbItemInteger(this);
                            break;
                        case QbItemType.SectionQbKey:
                        case QbItemType.SectionQbKeyString:
                        case QbItemType.SectionQbKeyStringQs: //GH:GH
                            qib = new QbItemQbKey(this);
                            break;
                        default:
                            throw new ApplicationException(string.Format("Location 0x{0}: Unknown section type 0x{1}", (this.StreamPos(br.BaseStream) - 4).ToString("X").PadLeft(8, '0'), sectionValue.ToString("X").PadLeft(8, '0')));
                    }
                    qib.Construct(br, sectionType);

                    AddItem(qib);
                }
            }

            uint f = this.FileId; //gettin this sets the file id
        }
Example #21
0
        public override void Construct(BinaryEndianReader br, QbItemType type)
        {
            //System.Diagnostics.Debug.WriteLine(string.Format("{0} - 0x{1}", type.ToString(), (base.StreamPos(br) - 4).ToString("X").PadLeft(8, '0')));

            base.Construct(br, type);

            QbItemBase qib = null;
            QbItemType arrayType;
            uint arrayValue;

            for (int i = 0; i < base.ItemCount; i++)
            {
                arrayValue = br.ReadUInt32(this.Root.PakFormat.EndianType);
                arrayType = this.Root.PakFormat.GetQbItemType(arrayValue);

                switch (arrayType)
                {
                    case QbItemType.Floats:
                        qib = new QbItemFloats(this.Root);
                        break;
                    case QbItemType.ArrayStruct:
                        qib = new QbItemStructArray(this.Root);
                        break;
                    case QbItemType.ArrayFloat:
                        qib = new QbItemFloat(this.Root);
                        break;
                    case QbItemType.ArrayString:
                    case QbItemType.ArrayStringW:
                        qib = new QbItemString(this.Root);
                        break;
                    case QbItemType.ArrayFloatsX2:
                    case QbItemType.ArrayFloatsX3:
                        qib = new QbItemFloatsArray(this.Root);
                        break;
                    case QbItemType.ArrayStringPointer:
                    case QbItemType.ArrayInteger:
                        qib = new QbItemInteger(this.Root);
                        break;
                    case QbItemType.ArrayArray:
                        qib = new QbItemArray(this.Root);
                        break;
                    case QbItemType.ArrayQbKey:
                    case QbItemType.ArrayQbKeyString:
                    case QbItemType.ArrayQbKeyStringQs: //GH:GH
                        qib = new QbItemQbKey(this.Root);
                        break;
                    case QbItemType.StructHeader:
                        qib = new QbItemStruct(this.Root);
                        break;
                    default:
                        throw new ApplicationException(string.Format("Location 0x{0}: Unknown array type 0x{1}", (base.StreamPos(br) - 4).ToString("X").PadLeft(8, '0'), arrayValue.ToString("X").PadLeft(8, '0')));
                }
                qib.Construct(br, arrayType);
                AddItem(qib);

            }
            base.ConstructEnd(br);
        }
Example #22
0
        public override void Construct(BinaryEndianReader br, QbItemType type)
        {
            //System.Diagnostics.Debug.WriteLine(string.Format("{0} - 0x{1}", type.ToString(), (base.StreamPos(br) - 4).ToString("X").PadLeft(8, '0')));

            base.Construct(br, type);

            uint pointer;

            if (type != QbItemType.StructHeader)
                _headerValue = br.ReadUInt32(base.Root.PakFormat.EndianType);
            else
                _headerValue = base.Root.PakFormat.GetQbItemValue(type, this.Root);

             _headerType = base.Root.PakFormat.GetQbItemType(_headerValue);

            QbItemBase qib = null;
            QbItemType structType;
            uint structValue;

            if (_headerType == QbItemType.StructHeader)
            {
                pointer = br.ReadUInt32(base.Root.PakFormat.EndianType); //Should be the current stream position after reading

                _iniNextItemPointer = pointer;

                if (pointer != 0 && base.StreamPos(br) != pointer) //pointer test
                    throw new ApplicationException(QbFile.FormatBadPointerExceptionMessage(this, base.StreamPos(br), pointer));

                while (pointer != 0)
                {
                    structValue = br.ReadUInt32(this.Root.PakFormat.EndianType);
                    structType = this.Root.PakFormat.GetQbItemType(structValue);

                    switch (structType)
                    {
                        case QbItemType.StructItemStruct:
                            this.Root.PakFormat.StructItemChildrenType = StructItemChildrenType.StructItems;
                            qib = new QbItemStruct(this.Root);
                            break;
                        case QbItemType.StructItemStringPointer:
                        case QbItemType.StructItemInteger:
                            this.Root.PakFormat.StructItemChildrenType = StructItemChildrenType.StructItems;
                            qib = new QbItemInteger(this.Root);
                            break;
                        case QbItemType.StructItemQbKeyString:
                        case QbItemType.StructItemQbKeyStringQs:
                        case QbItemType.StructItemQbKey:
                            this.Root.PakFormat.StructItemChildrenType = StructItemChildrenType.StructItems;
                            qib = new QbItemQbKey(this.Root);
                            break;
                        case QbItemType.StructItemString:
                        case QbItemType.StructItemStringW:
                            this.Root.PakFormat.StructItemChildrenType = StructItemChildrenType.StructItems;
                            qib = new QbItemString(this.Root);
                            break;
                        case QbItemType.StructItemFloat:
                            this.Root.PakFormat.StructItemChildrenType = StructItemChildrenType.StructItems;
                            qib = new QbItemFloat(this.Root);
                            break;
                        case QbItemType.StructItemFloatsX2:
                        case QbItemType.StructItemFloatsX3:
                            this.Root.PakFormat.StructItemChildrenType = StructItemChildrenType.StructItems;
                            qib = new QbItemFloatsArray(this.Root);
                            break;
                        case QbItemType.StructItemArray:
                            this.Root.PakFormat.StructItemChildrenType = StructItemChildrenType.StructItems;
                            qib = new QbItemArray(this.Root);
                            break;

                        //Convert array types to structitems to fit in with this parser (if QbFile.HasStructItems is false then internal type will be swapped back to array)
                        case QbItemType.ArrayStruct:
                            structType = QbItemType.StructItemStruct;
                            qib = new QbItemArray(this.Root);
                            break;
                        case QbItemType.ArrayInteger:
                            structType = QbItemType.StructItemInteger;
                            qib = new QbItemInteger(this.Root);
                            break;
                        case QbItemType.ArrayQbKeyString:
                            structType = QbItemType.StructItemQbKeyString;
                            qib = new QbItemQbKey(this.Root);
                            break;
                        case QbItemType.ArrayStringPointer:
                            structType = QbItemType.StructItemStringPointer;
                            qib = new QbItemInteger(this.Root);
                            break;
                        case QbItemType.ArrayQbKeyStringQs:
                            structType = QbItemType.StructItemQbKeyStringQs;
                            qib = new QbItemQbKey(this.Root);
                            break;
                        case QbItemType.ArrayQbKey:
                            structType = QbItemType.StructItemQbKey;
                            qib = new QbItemQbKey(this.Root);
                            break;
                        case QbItemType.ArrayString:
                            structType = QbItemType.StructItemString;
                            qib = new QbItemString(this.Root);
                            break;
                        case QbItemType.ArrayStringW:
                            structType = QbItemType.StructItemStringW;
                            qib = new QbItemString(this.Root);
                            break;
                        case QbItemType.ArrayFloat:
                            structType = QbItemType.StructItemFloat;
                            qib = new QbItemFloat(this.Root);
                            break;
                        case QbItemType.ArrayFloatsX2:
                            structType = QbItemType.StructItemFloatsX2;
                            qib = new QbItemFloatsArray(this.Root);
                            break;
                        case QbItemType.ArrayFloatsX3:
                            structType = QbItemType.StructItemFloatsX3;
                            qib = new QbItemFloatsArray(this.Root);
                            break;
                        case QbItemType.ArrayArray:
                            structType = QbItemType.StructItemArray;
                            qib = new QbItemArray(this.Root);
                            break;
                        default:
                            qib = null;
                            break;
                    }

                    if (qib != null)
                    {
                        if (this.Root.PakFormat.StructItemChildrenType == StructItemChildrenType.NotSet) //will have been set to structItem if qib is not null)
                            this.Root.PakFormat.StructItemChildrenType = StructItemChildrenType.ArrayItems;

                        qib.Construct(br, structType);
                        AddItem(qib);
                        pointer = qib.NextItemPointer;
                    }
                    else
                        throw new ApplicationException(string.Format("Location 0x{0}: Unknown item type 0x{1} in struct ", (base.StreamPos(br) - 4).ToString("X").PadLeft(8, '0'), structValue.ToString("X").PadLeft(8, '0')));

                }
            }
            else
                throw new ApplicationException(string.Format("Location 0x{0}: Struct without header type", (base.StreamPos(br) - 4).ToString("X").PadLeft(8, '0')));

            base.ConstructEnd(br);
        }
Example #23
0
        public override void Construct(BinaryEndianReader br, QbItemType type)
        {
            //System.Diagnostics.Debug.WriteLine(string.Format("{0} - 0x{1}", type.ToString(), (base.StreamPos(br) - 4).ToString("X").PadLeft(8, '0')));

            base.Construct(br, type);

            QbItemBase qib = null;
            QbItemType arrayType;
            uint       arrayValue;

            for (int i = 0; i < base.ItemCount; i++)
            {
                arrayValue = br.ReadUInt32(this.Root.PakFormat.EndianType);
                arrayType  = this.Root.PakFormat.GetQbItemType(arrayValue);

                switch (arrayType)
                {
                case QbItemType.Floats:
                    qib = new QbItemFloats(this.Root);
                    break;

                case QbItemType.ArrayStruct:
                    qib = new QbItemStructArray(this.Root);
                    break;

                case QbItemType.ArrayFloat:
                    qib = new QbItemFloat(this.Root);
                    break;

                case QbItemType.ArrayString:
                case QbItemType.ArrayStringW:
                    qib = new QbItemString(this.Root);
                    break;

                case QbItemType.ArrayFloatsX2:
                case QbItemType.ArrayFloatsX3:
                    qib = new QbItemFloatsArray(this.Root);
                    break;

                case QbItemType.ArrayStringPointer:
                case QbItemType.ArrayInteger:
                    qib = new QbItemInteger(this.Root);
                    break;

                case QbItemType.ArrayArray:
                    qib = new QbItemArray(this.Root);
                    break;

                case QbItemType.ArrayQbKey:
                case QbItemType.ArrayQbKeyString:
                case QbItemType.ArrayQbKeyStringQs:     //GH:GH
                    qib = new QbItemQbKey(this.Root);
                    break;

                case QbItemType.StructHeader:
                    qib = new QbItemStruct(this.Root);
                    break;

                default:
                    throw new ApplicationException(string.Format("Location 0x{0}: Unknown array type 0x{1}", (base.StreamPos(br) - 4).ToString("X").PadLeft(8, '0'), arrayValue.ToString("X").PadLeft(8, '0')));
                }
                qib.Construct(br, arrayType);
                AddItem(qib);
            }
            base.ConstructEnd(br);
        }