Пример #1
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);

            _values = new QbKey[base.ItemCount];

            uint   crc;
            string debug;

            for (int i = 0; i < base.ItemCount; i++)
            {
                crc   = br.ReadUInt32(base.Root.PakFormat.EndianType);
                debug = this.Root.LookupDebugName(crc);
                if (debug.Length != 0)
                {
                    _values[i] = QbKey.Create(crc, debug);
                }
                else
                {
                    _values[i] = QbKey.Create(crc);
                }
            }

            base.ConstructEnd(br);
        }
Пример #2
0
 public QbItemBase FindItem(QbKey key, bool recursive)
 {
     return(SearchItems(this, _items, recursive, delegate(QbItemBase item)
     {
         return (item.ItemQbKey != null && item.ItemQbKey.Crc == key.Crc);
     }));
 }
Пример #3
0
        public void NewFile(string newQbFilename, QbKey itemType, bool filenameInHeader, uint magic, byte[] unknownData)
        {
            createBlankFile(newQbFilename, itemType, filenameInHeader);
            QbFile blank = new QbFile(newQbFilename, _pakFormat, magic, unknownData);

            this.ReplaceFile(newQbFilename, blank);
        }
Пример #4
0
        /// <summary>
        /// Add the non debug item to the user defined list if it's not already there
        /// </summary>
        /// <param name="qbKey"></param>
        /// <param name="qbFilename"></param>
        /// <param name="qbfile"></param>
        /// <returns>True if crc already exists with different text.</returns>
        public string AddNonDebugQbKey(QbKey qbKey, string qbFilename, QbFile qbfile)
        {
            //check that it's not already in the real debug file
            if (qbKey.HasText)
            {
                string t = string.Empty;
                if (qbfile != null)
                {
                    t = qbfile.LookupDebugName(qbKey.Crc, false);
                }

                //it's in the debug file
                if (t.Length != 0)
                {
                    if (t != qbKey.Text)
                    {
                        return(t);
                    }
                }
                else
                {
                    //check that it's not in the user debug file
                    if (GetNonDebugQbKey(qbKey.Crc, qbFilename) == null)
                    {
                        if (_qbKeys == null)
                        {
                            _qbKeys = new List <NonDebugQbKey>();
                        }
                        _qbKeys.Add(new NonDebugQbKey(qbKey, qbFilename));
                    }
                }
            }
            return(string.Empty);
        }
Пример #5
0
 /// <summary>
 /// Converts the qbkey to the enum
 /// </summary>
 /// <param name="fileType"></param>
 /// <returns>The enum item or Other if not in enum</returns>
 public static PakItemType FileTypeToPakItemType(QbKey fileType)
 {
     if (fileType == _itemTypes[0].Crc) //.qb
     {
         return(PakItemType.Qb);
     }
     else if (fileType == _itemTypes[1].Crc) //.sqb
     {
         return(PakItemType.Sqb);
     }
     else if (fileType == _itemTypes[2].Crc) //.dbg
     {
         return(PakItemType.Debug);
     }
     else if (fileType == _itemTypes[3].Crc) //.img
     {
         return(PakItemType.Image);
     }
     else if (fileType == _itemTypes[4].Crc) //.mqb
     {
         return(PakItemType.Midi);
     }
     else if (fileType == _itemTypes[5].Crc) //.tex
     {
         return(PakItemType.Texture);
     }
     else if (fileType == _itemTypes[6].Crc) //.skin
     {
         return(PakItemType.Skin);
     }
     else
     {
         return(PakItemType.Other);
     }
 }
Пример #6
0
        /// <summary>
        /// Rename the filename, this does not set the fileid for all the qb types
        /// </summary>
        /// <param name="qbFilename">Source full filename.</param>
        /// <param name="newFullQbFilename">Full QB filename</param>
        /// <param name="fileType">.qb or .sqb=QB, .mqb=mid, .img=img .dbg=dbg  etc</param>
        /// <param name="extension">.qb.ngc for Wii for example</param>
        public void RenameFile(string qbFilename, string newQbFilename, QbKey itemType)
        {
            PakHeaderItem phi = _pakHeaders[qbFilename.ToLower()];

            phi.SetFilename(newQbFilename, itemType, _pakFormat.FileExtension, phi);

            using (BinaryEndianWriter bw = new BinaryEndianWriter(File.OpenWrite(_pakFormat.FullPakFilename)))
            {
                bw.BaseStream.Seek(phi.HeaderStart, SeekOrigin.Begin);
                writeHeaderItem(bw, phi);
            }

            //update the filename in the collection
            Dictionary <string, PakHeaderItem> p = new Dictionary <string, PakHeaderItem>(_pakHeaders.Count);

            foreach (PakHeaderItem ph in _pakHeaders.Values)
            {
                p.Add(ph.Filename.ToLower(), ph);
            }

            _pakHeaders = p;

            if (phi.PakFileType == PakItemType.Qb || phi.PakFileType == PakItemType.Sqb || phi.PakFileType == PakItemType.Midi)
            {
                try
                {
                    QbFile qbf = ReadQbFile(newQbFilename);
                    qbf.SetNewFileId();
                    ReplaceFile(newQbFilename, qbf);
                }
                catch
                {
                }
            }
        }
Пример #7
0
 internal DatItem(QbKey itemQbKey, uint fileOffset, uint fileSize, byte[] reserved)
 {
     _itemQkey = itemQbKey;
     _fileOffset = fileOffset;
     _fileSize = fileSize;
     _reserved = reserved;
 }
Пример #8
0
        /// <summary>
        /// Rename the filename and set the data types
        /// </summary>
        /// <param name="newFullQbFilename">Full QB filename</param>
        /// <param name="fileType">.qb or .sqb=QB, .mqb=mid, .img=img .dbg=dbg  etc</param>
        /// <param name="extension">.ngc for Wii for example</param>
        /// <param name="baseOn">base the qbKeys that are present on the passed item</param>
        public void SetFilename(string newFullQbFilename, QbKey itemType, string extension, PakHeaderItem baseOn)
        {
            if (newFullQbFilename.Length > PakHeaderItem.FileNameMaxLength)
            {
                throw new ApplicationException("newQbFilename is too long");
            }

            if (!itemType.HasText || itemType.Text.Length == 0)
            {
                throw new ApplicationException("fileType is not recognised");
            }

            //filename is stored in the header
            if ((this.Flags & PakHeaderFlags.Filename) == PakHeaderFlags.Filename)
            {
                this.Filename          = newFullQbFilename;
                this.FullFilenameQbKey = 0;
            }
            else
            {
                this.Filename = QbKey.Create(newFullQbFilename).Crc.ToString("X").PadLeft(8, '0').ToLower();

                if (baseOn == null || baseOn.FullFilenameQbKey != 0)
                {
                    this.FullFilenameQbKey = QbKey.Create(newFullQbFilename).Crc;
                }
                else
                {
                    this.FullFilenameQbKey = 0;
                }
            }

            string[] pts = newFullQbFilename.Split('.');

            string nameOnly = pts[0];

            if (baseOn == null || baseOn.FullFilenameQbKey != 0)
            {
                this.NameOnlyCrc = QbKey.Create(nameOnly).Crc;
            }
            else
            {
                this.NameOnlyCrc = 0;
            }


            this.FileType = itemType;

            if (baseOn == null || baseOn.PakFullFileNameQbKey != 0)
            {
                this.PakFullFileNameQbKey = QbKey.Create(newFullQbFilename).Crc;
            }
            else
            {
                this.PakFullFileNameQbKey = 0;
            }
        }
Пример #9
0
        public QbKey ToQbKey()
        {
            Type t = typeof(QbKey);

            if (t != _type)
            {
                throw new ApplicationException(getToError(_type, t));
            }
            return(QbKey.Create(_value));
        }
Пример #10
0
        public GenericQbItem(string name, QbKey value, Type editType, bool readOnly, bool useQbItemType, QbItemType qbType, string sourceProperty)
            : this(name, editType, readOnly, useQbItemType, qbType, sourceProperty)
        {
            _value = value.ToString();
            _type  = value.GetType();

            _typeNumeric = true;
            _qbKey       = value;
            this.ConvertTo(editType);
        }
Пример #11
0
        public GenericQbItem(string name, QbKey value, Type editType, bool readOnly, bool useQbItemType, QbItemType qbType, string sourceProperty)
            : this(name, editType, readOnly, useQbItemType, qbType, sourceProperty)
        {
            _value = value.ToString();
            _type = value.GetType();

            _typeNumeric = true;
            _qbKey = value;
            this.ConvertTo(editType);
        }
Пример #12
0
        /// <summary>
        /// Create a QbKey that has an already known CRC and Text
        /// </summary>
        /// <param name="crc">QBKey crc</param>
        /// <param name="text">Text from debug file etc</param>
        /// <returns></returns>
        public static QbKey Create(uint crc, string text)
        {
            QbKey qb = Create(text);

            if (crc != qb.Crc)
            {
                throw new ArgumentException(string.Format("The Crc 0x{0} does not match the Text '{1}'", crc.ToString("X").PadLeft(8, '0'), text));
            }

            return(qb);
        }
Пример #13
0
 public QbKey Clone()
 {
     if (this.HasText)
     {
         return(QbKey.Create(this.Text));
     }
     else
     {
         return(QbKey.Create(this.Crc));
     }
 }
Пример #14
0
 /// <summary>
 /// Attempts to take a qbkey key without any text and lookup a named file type
 /// </summary>
 /// <returns></returns>
 public static QbKey LookupFileType(QbKey fileType)
 {
     foreach (QbKey k in _itemTypes)
     {
         if (fileType.Crc == k.Crc)
         {
             return(k);
         }
     }
     return(fileType);
 }
Пример #15
0
 private void loadNonDebugQbKey()
 {
     if (File.Exists(FullNonDebugQbKeyFilename))
     {
         string[] f;
         foreach (string s in File.ReadAllLines(FullNonDebugQbKeyFilename))
         {
             f = s.Split('|');
             AddNonDebugQbKey(QbKey.Create(uint.Parse(f[0].Substring(2), System.Globalization.NumberStyles.HexNumber), f[1]), f[2], null);
         }
     }
 }
Пример #16
0
        /// <summary>
        /// The FileId is based on the filename, this will recalculate it, GH3 has a bug where the first character is missing from the path.
        /// The FileId doesn't appear to affect the game, it may just need to be unique
        /// </summary>
        public void SetNewFileId()
        {
            uint fileId = QbKey.Create(this.Filename).Crc;

            foreach (QbItemBase qbi in this.Items)
            {
                if (qbi.QbItemType != QbItemType.Unknown)
                {
                    qbi.FileId = fileId;
                }
            }
        }
Пример #17
0
        public override void Create(QbItemType type)
        {
            if (type != QbItemType.SectionQbKey && type != QbItemType.SectionQbKeyString && type != QbItemType.SectionQbKeyStringQs &&
                type != QbItemType.ArrayQbKey && type != QbItemType.ArrayQbKeyString && type != QbItemType.ArrayQbKeyStringQs &&
                type != QbItemType.StructItemQbKey && type != QbItemType.StructItemQbKeyString && type != QbItemType.StructItemQbKeyStringQs)
            {
                throw new ApplicationException(string.Format("type '{0}' is not a QB key item type", type.ToString()));
            }

            base.Create(type);

            this.Values = new QbKey[1]; //sets item count
            _values[0]  = QbKey.Create(0);
        }
Пример #18
0
        static PakHeaderItem()
        {                             // qb,     qb,    debug,   image,  midi
            string[] s = new string[] { ".qb", ".sqb", ".dbg", ".img", ".mqb", ".tex", ".skin", ".cam", ".col", ".fam", ".fnc", ".fnt", ".fnv", ".gap",
                                        ".hkc", ".imv", ".last", ".mcol", ".mdl", ".mdv", ".nav", ".nqb", ".oba", ".pfx", ".pimg", ".png", ".rag", ".rnb",
                                        ".rnb_lvl", ".rnb_mdl", ".scn", ".scv", ".shd", ".ska", ".ske", ".skiv", ".stex", ".table", ".tvx", ".wav", ".empty",
                                        ".clt", ".jam", ".note", ".nqb", ".perf", ".pimv", ".qs", ".qs.br", ".qs.de", ".qs.en", ".qs.es", ".qs.fr", ".qs.it",
                                        ".raw", ".rgn", ".trkobj", ".xml" };

            _itemTypes = new QbKey[s.Length];
            for (int i = 0; i < s.Length; i++)
            {
                _itemTypes[i] = QbKey.Create(s[i]);
            }
        }
Пример #19
0
        public static void CreateDatWad(QbKey songQk, EndianType endianType, string datFilename, string wadFilename, string songFilename, string guitarFilename, string rhythmFilename, string previewFilename)
        {
            QbKey[] keys = new QbKey[4];
            int[] offsets = new int[5];
            int[] sizes = new int[4];

            FileHelper.Delete(wadFilename);
            FileHelper.Delete(datFilename);

            using (FileStream fsWad = File.OpenWrite(wadFilename))
            {
                offsets[0] = (int)fsWad.Position;
                keys[0] = QbKey.Create(string.Format("{0}_guitar", songQk.Text));
                sizes[0] = (int)writeFsbToStream(fsWad, guitarFilename, string.Concat(keys[0].Text, ".wav"));
                offsets[1] = (int)fsWad.Position;
                keys[1] = QbKey.Create(string.Format("{0}_preview", songQk.Text));
                sizes[1] = (int)writeFsbToStream(fsWad, previewFilename, string.Concat(keys[1].Text, ".wav"));
                offsets[2] = (int)fsWad.Position;
                keys[2] = QbKey.Create(string.Format("{0}_rhythm", songQk.Text));
                sizes[2] = (int)writeFsbToStream(fsWad, rhythmFilename, string.Concat(keys[2].Text, ".wav"));
                offsets[3] = (int)fsWad.Position;
                keys[3] = QbKey.Create(string.Format("{0}_song", songQk.Text));
                sizes[3] = (int)writeFsbToStream(fsWad, songFilename, string.Concat(keys[3].Text, ".wav"));
                offsets[4] = (int)fsWad.Position;
                fsWad.Flush();
            }

            using (FileStream fsDat = File.OpenWrite(datFilename))
            {
                using (BinaryEndianWriter bw = new BinaryEndianWriter(fsDat))
                {
                    int l = offsets[3] + sizes[3];
                    if (l % 16 != 0)
                        l += 16 - (l % 16);

                    bw.Write((uint)keys.Length, endianType);
                    bw.Write((uint)l, endianType);

                    for (int i = 0; i < offsets.Length - 1; i++)
                    {
                        bw.Write(keys[i].Crc, endianType);
                        bw.Write(offsets[i], endianType);
                        bw.Write(sizes[i], endianType);
                        bw.Write(new byte[] { 0,0,0,0,0,0,0,0 });
                    }
                    fsDat.Flush();
                }
            }
        }
Пример #20
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()
        {
            QbItemQbKey qk = new QbItemQbKey(this.Root);
            qk.Create(this.QbItemType);

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

            QbKey[] q = new QbKey[this.Values.Length];
            for (int i = 0; i < q.Length; i++ )
                q[i] = this.Values[i].Clone();

            qk.Values = q;
            qk.ItemCount = this.ItemCount;
            return qk;
        }
Пример #21
0
        internal string LookupDebugName(uint debugCrc, bool allowUserQbkeyLookup)
        {
            if (_debugNames != null && _debugNames.ContainsKey(debugCrc))
            {
                return(_debugNames[debugCrc]);
            }

            if (allowUserQbkeyLookup)
            {
                QbKey qbKey = _pakFormat.GetNonDebugQbKey(debugCrc, _filename);
                if (qbKey != null)
                {
                    return(qbKey.Text);
                }
            }

            return(string.Empty);
        }
Пример #22
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()
        {
            QbItemQbKey qk = new QbItemQbKey(this.Root);

            qk.Create(this.QbItemType);

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

            QbKey[] q = new QbKey[this.Values.Length];
            for (int i = 0; i < q.Length; i++)
            {
                q[i] = this.Values[i].Clone();
            }

            qk.Values    = q;
            qk.ItemCount = this.ItemCount;
            return(qk);
        }
Пример #23
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();
                }
            }
        }
Пример #24
0
        /// <summary>
        /// Remove song to bonus list and shop
        /// </summary>
        /// <param name="songQk"></param>
        public void RemoveBonusSongQbItems(QbKey songQk, QbFile qbStore)
        {
            QbItemBase item;

            //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;

            //remove bonus song from list
            if (bonusSongs != null)
            {
                List<QbKey> songs = new List<QbKey>((bonusSongs.Items[0] as QbItemQbKey).Values);
                songs.Remove(songQk);
                (bonusSongs.Items[0] as QbItemQbKey).Values = songs.ToArray();
            }

            //remove bonus song price
            if (songData != null)
            {
                item = songData.FindItem(false, delegate(QbItemBase qib)
                    {
                        return (qib.ItemQbKey.Crc == songQk.Crc);
                    });
                if (item != null)
                    songData.RemoveItem(item);
            }

            //remove bonus info
            if (bonusInfo != null && bonusInfo.Items.Count > 0)
            {
                QbKey itemQk = QbKey.Create("item");
                QbItemStructArray infoArray = (bonusInfo.Items[0] as QbItemStructArray);
                item = infoArray.FindItem(false, delegate(QbItemBase qib)
                    {
                        QbItemQbKey iqk = (QbItemQbKey)(qib.Items[0]);
                        return iqk.ItemQbKey.Crc == itemQk.Crc && iqk.Values[0] == songQk.Crc;
                    });
                if (item != null)
                    infoArray.RemoveItem(item);
            }

            qbStore.AlignPointers();
            qbStore.IsValid();
        }
Пример #25
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);
            }
        }
Пример #26
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);
            }
        }
Пример #27
0
        internal List<TierQb> BuildTierList(QbFile fileQb, QbKey tiersQk)
        {
            List<TierQb> tierList = new List<TierQb>();

            QbItemBase tiersQi = fileQb.FindItem(tiersQk, false);

            if (tiersQi != null)
            {
                tiersQi.FindItem(false, delegate(QbItemBase item)
                {
                    if (item.QbItemType == QbItemType.StructItemStruct)
                        tierList.Add(new TierQb((QbItemStruct)item));
                    return false; //if we return false then the search continues
                });
            }

            foreach (TierQb t in tierList)
            {
                for (int i = 0; i < t.Songs.Length; i++)
                {
                    if (this.Songs.ContainsKey(t.Songs[i].Crc))
                        t.Songs[i] = this.Songs[t.Songs[i].Crc].SongQb.Id; //get the key from the songlist (it has the text)
                }
            }

            return tierList;
        }
Пример #28
0
        /// <summary>
        /// Remove song from bonus list and shop
        /// </summary>
        public void BonusSongRemoveFromGame(QbFile qbStore, QbFile qbSongList, QbKey qkSong)
        {
            //is this song (this) in the bonus tiers?
            bool found = getAllBonusSongs(qbStore).Contains(qkSong);

            removeSongFromSonglist(qbSongList, qkSong);

            this.RemoveBonusSongQbItems(qkSong, qbStore);
        }
Пример #29
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
            }
        }
Пример #30
0
 public NonDebugQbKey(QbKey qbKey, string qbFilename)
 {
     this.QbKey = qbKey;
     this.QbFilename = qbFilename;
 }
Пример #31
0
        /// <summary>
        /// Load type data from binary reader
        /// </summary>
        public virtual void Construct(BinaryEndianReader br, QbItemType type)
        {
            setQbFormat(type);
            _qbItemType = type;
            _qbItemValue = this.Root.PakFormat.GetQbItemValue(type, this.Root);
            _position = this.StreamPos(br) - (1 * 4); //subtract the already read header
            uint itemQbKeyCrc = 0;

            #region switch
            switch (_qbFormat)
            {
                case QbFormat.SectionPointer:
                    //Complex section type:
                    //  ItemId, FileId, Pointer, Reserved
                    _hasQbKey = true;

                    itemQbKeyCrc = br.ReadUInt32(this.Root.PakFormat.EndianType);
                    _fileId = br.ReadUInt32(this.Root.PakFormat.EndianType);
                    _pointer = br.ReadUInt32(this.Root.PakFormat.EndianType);
                    _reserved = br.ReadUInt32(this.Root.PakFormat.EndianType);

                    _length = (5*4);

                    if (type == QbItemType.SectionScript)
                        _itemCount = 0;
                    else
                        _itemCount = 1;
                    _pointers = new uint[1];
                    _pointers[0] = _pointer;

                    if (this.StreamPos(br) != _pointer) //pointer test
                        throw new ApplicationException(QbFile.FormatBadPointerExceptionMessage(this, this.StreamPos(br), _pointer));
                    break;

                case QbFormat.SectionValue:
                    //Simple section type:
                    //  ItemId, FileId, Value, Reserved
                    _hasQbKey = true;

                    itemQbKeyCrc = br.ReadUInt32(this.Root.PakFormat.EndianType);
                    _fileId = br.ReadUInt32(this.Root.PakFormat.EndianType);

                    _itemCount = 1;

                    _length = (3*4);
                    break;

                case QbFormat.StructItemPointer:
                    //Complex struct type:
                    //  ItemId, Pointer, NextItemPointer
                    _hasQbKey = true;

                    itemQbKeyCrc = br.ReadUInt32(this.Root.PakFormat.EndianType);
                    _pointer = br.ReadUInt32(this.Root.PakFormat.EndianType);
                    _nextItemPointer = br.ReadUInt32(this.Root.PakFormat.EndianType);

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

                    _itemCount = 1;
                    _pointers = new uint[1];
                    _pointers[0] = _pointer;

                    _length = (4*4);
                    break;

                case QbFormat.StructItemValue:
                    //Simple struct type:
                    //  ItemId, Value (4 byte), NextItemPointer
                    _hasQbKey = true;

                    itemQbKeyCrc = br.ReadUInt32(this.Root.PakFormat.EndianType);

                    //always null?
                    if (_itemQbKey == 0 && _qbItemType == QbItemType.StructItemQbKeyString)
                        _itemQbKey = null;

                    _itemCount = 1;

                    _length = (2*4);
                    break;

                case QbFormat.ArrayPointer:
                    //Complex array type:
                    //  ItemCount, Pointer, Pointers -  (if length is 1 then pointer points to first item and Pointers are abscent)
                    _hasQbKey = false;

                    _itemCount = br.ReadUInt32(this.Root.PakFormat.EndianType);
                    _pointer = br.ReadUInt32(this.Root.PakFormat.EndianType);
                    itemQbKeyCrc = 0;

                    _length = (3 * 4);

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

                    _pointers = new uint[_itemCount];

                    if (_itemCount == 1)
                        _pointers[0] = _pointer;
                    else if (_itemCount > 1)
                    {
                        for (int i = 0; i < _itemCount; i++)
                            _pointers[i] = br.ReadUInt32(this.Root.PakFormat.EndianType);

                        _length += (_itemCount * 4);
                    }
                    break;

                case QbFormat.ArrayValue:
                    //Simple array type:
                    //  ItemCount, Pointer, Pointers -  (if length is 1 then pointer points to first item and Pointers are abscent)
                    _hasQbKey = false;

                    itemQbKeyCrc = 0;
                    _itemCount = br.ReadUInt32(this.Root.PakFormat.EndianType);
                    _length = (2*4);
                    if (_itemCount > 1)
                    {
                        _pointer = br.ReadUInt32(this.Root.PakFormat.EndianType);
                        if (this.StreamPos(br) != _pointer) //pointer test
                            throw new ApplicationException(QbFile.FormatBadPointerExceptionMessage(this, this.StreamPos(br), _pointer));
                        _length += (1 * 4);
                    }
                    break;

                case QbFormat.StructHeader: //when struct array item
                    _hasQbKey = false;
                    _length = (1 * 4);
                    break;

                case QbFormat.Floats:
                    _hasQbKey = false;
                    _length = (1 * 4);
                    break;

                case QbFormat.Unknown:
                    _hasQbKey = false;
                    _position += 4; //there is no header so re add the previously removed 4
                    _length = (0*4);
                    break;

                default:
                    break;
            }
            #endregion

            if (!_hasQbKey)
                _itemQbKey = null;
            else
            {
                string debugName = Root.LookupDebugName(itemQbKeyCrc);
                if (debugName.Length != 0)
                    _itemQbKey = QbKey.Create(itemQbKeyCrc, debugName);
                else
                    _itemQbKey = QbKey.Create(itemQbKeyCrc);
            }
        }
Пример #32
0
 public QbItemBase FindItem(QbKey key, bool recursive)
 {
     return this.Root.SearchItems(this.Root, _items, recursive, delegate(QbItemBase item)
     {
         return (item.ItemQbKey != 0 && item.ItemQbKey.Crc == key.Crc);
     });
 }
Пример #33
0
 public string GetNotesTextQbFilename(QbKey song)
 {
     if (this.Game == Game.GH3_Wii || this.Game == Game.GHA_Wii)
     {
         if (!song.HasText)
         {
             song = findMissingText(song);
             if (!song.HasText)
                 throw new ApplicationException(string.Format("Missing text in Song QbKey '{0}'", song.Crc));
         }
         if (this.Game == Game.GHA_Wii)
             return string.Format(@"songs\{0}.mid_text.qb.{1}", song.Text, FileExtension);
         else //GH3
             return string.Format(@"data/songs/{0}.mid_text.qb.{1}", song.Text, FileExtension);
     }
     else if (this.Game == Game.GH3_PS2)
     {
         return null;
     }
     else
         throw new ApplicationException(string.Format("'{0}' is not a supported Game type", this.Game.ToString()));
 }
Пример #34
0
        private static void addSongToSonglist(QbFile qbSongList, QbKey qkSong)
        {
            QbItemStruct songs = qbSongList.FindItem(QbKey.Create("permanent_songlist_props"), false) as QbItemStruct;
            QbItemArray songsList = qbSongList.FindItem(QbKey.Create("gh3_songlist"), false) as QbItemArray;
            if (songsList != null)
            {
                List<QbKey> songlistQk = new List<QbKey>(((QbItemQbKey)songsList.Items[0]).Values);

                if (!songlistQk.Contains(qkSong))
                {
                    songs.AddItem((QbItemBase)SongQb.CreateSong(songs.Root, qkSong.Text));
                    songlistQk.Add(qkSong);
                }

                //update gh3_songlist
                ((QbItemQbKey)songsList.Items[0]).Values = songlistQk.ToArray();

                qbSongList.AlignPointers();
                qbSongList.IsValid();
            }
        }
Пример #35
0
        public static void SetGenericItems(QbItemBase item, List<GenericQbItem> gItems)
        {
            MemberInfo[] ms = item.GetType().FindMembers(MemberTypes.Property,
                /*BindingFlags.DeclaredOnly |*/ BindingFlags.Instance | BindingFlags.Public,
                Type.FilterName, "*");

            int i = 0;
            GenericQbItem gi;
            List<GenericQbItem> list = null;

            if (gItems.Count == 0)
            {
                //test if this is an array item
                GenericQbItem gqi = QbFile.CreateGenericArrayItem(item);

                //null if not an array type
                if (gqi != null)
                {
                    //use this item to identify the array to set to 0 items
                    MemberInfo m = Array.Find(ms, delegate(MemberInfo mi)
                    {
                        return (mi.Name == gqi.SourceProperty);
                    });
                    if (m != null)
                    {
                        Type t = ((PropertyInfo)m).GetValue(item, null).GetType();
                        if (t == typeof(QbKey[]))
                            ((PropertyInfo)m).SetValue(item, new QbKey[0], null);
                        else if (t == typeof(float[]))
                            ((PropertyInfo)m).SetValue(item, new float[0], null);
                        else if (t == typeof(uint[]))
                            ((PropertyInfo)m).SetValue(item, new uint[0], null);
                        else if (t == typeof(int[]))
                            ((PropertyInfo)m).SetValue(item, new int[0], null);
                        else if (t == typeof(string[]))
                            ((PropertyInfo)m).SetValue(item, new string[0], null);
                    }
                }
            }

            while (i < gItems.Count)
            {
                gi = gItems[i++];

                if (gi.ReadOnly)
                    continue;

                //list = null;

                list = new List<GenericQbItem>();
                list.Add(gi);
                while (i < gItems.Count && gi.SourceProperty == gItems[i].SourceProperty)
                    list.Add(gItems[i++]);

                MemberInfo m = Array.Find(ms, delegate(MemberInfo mi)
                {
                    return (mi.Name == gi.SourceProperty);
                });

                if (m != null)
                {
                    Type t = ((PropertyInfo)m).GetValue(item, null).GetType();
                    if (t == typeof(QbKey[]))
                    {
                        QbKey[] qb = new QbKey[list.Count];
                        QbKey q;
                        string qS;

                        for (int c = 0; c < list.Count; c++)
                        {
                            q = list[c].ToQbKey();
                            qS = item.Root.LookupDebugName(q.Crc);
                            if (qS.Length != 0)
                                q = QbKey.Create(q.Crc, qS);
                            qb[c] = q;
                        }
                        ((PropertyInfo)m).SetValue(item, qb, null);
                    }
                    else if (t == typeof(float[]))
                    {
                        float[] f = new float[list.Count];
                        for (int c = 0; c < list.Count; c++)
                            f[c] = list[c].ToSingle();
                        ((PropertyInfo)m).SetValue(item, f, null);
                    }
                    else if (t == typeof(uint[]))
                    {
                        uint[] ui = new uint[list.Count];
                        for (int c = 0; c < list.Count; c++)
                            ui[c] = list[c].ToUInt32();
                        ((PropertyInfo)m).SetValue(item, ui, null);
                    }
                    else if (t == typeof(int[]))
                    {
                        int[] si = new int[list.Count];
                        for (int c = 0; c < list.Count; c++)
                            si[c] = list[c].ToInt32();
                        ((PropertyInfo)m).SetValue(item, si, null);
                    }
                    else if (t == typeof(string[]))
                    {
                        string[] s = new string[list.Count];
                        for (int c = 0; c < list.Count; c++)
                            s[c] = list[c].ToString();
                        ((PropertyInfo)m).SetValue(item, s, null);
                    }
                    else if (t == typeof(QbKey))
                    {
                        QbKey q = gi.ToQbKey();
                        string qS = item.Root.LookupDebugName(q.Crc);
                        if (qS.Length != 0)
                            q = QbKey.Create(q.Crc, qS);
                        ((PropertyInfo)m).SetValue(item, q, null);
                    }
                    else if (t == typeof(float))
                        ((PropertyInfo)m).SetValue(item, gi.ToSingle(), null);
                    else if (t == typeof(uint))
                        ((PropertyInfo)m).SetValue(item, gi.ToUInt32(), null);
                    else if (t == typeof(int))
                        ((PropertyInfo)m).SetValue(item, gi.ToInt32(), null);
                    else if (t == typeof(string))
                        ((PropertyInfo)m).SetValue(item, gi.ToString(), null);
                    else if (t == typeof(byte[]))
                        ((PropertyInfo)m).SetValue(item, gi.ToByteArray(), null);
                    else
                    {
                        throw new ApplicationException(string.Format("DataType {0} not supported.", t.Name));
                    }
                }
            }
        }
Пример #36
0
        protected void AddQbKeyToUserDebugFile(QbKey qbKey)
        {
            string qbKeyText = string.Empty;

            if (qbKey == null)
                return;

            if ((qbKeyText = _qbItemBase.Root.PakFormat.AddNonDebugQbKey(qbKey, _qbItemBase.Root.Filename, _qbItemBase.Root)).Length != 0)
                this.ShowError("QB Key Error", string.Format("QB Key '{0}' has the same crc as item '{1}' from the debug file.{2}{2}The QbKey text '{0}' will not be saved to the User Debug file.", qbKey.Text, qbKeyText, Environment.NewLine));
        }
Пример #37
0
        /// <summary>
        /// Add the non debug item to the user defined list if it's not already there
        /// </summary>
        /// <param name="qbKey"></param>
        /// <param name="qbFilename"></param>
        /// <param name="qbfile"></param>
        /// <returns>True if crc already exists with different text.</returns>
        public string AddNonDebugQbKey(QbKey qbKey, string qbFilename, QbFile qbfile)
        {
            //check that it's not already in the real debug file
            if (qbKey.HasText)
            {
                string t = string.Empty;
                if (qbfile != null)
                    t = qbfile.LookupDebugName(qbKey.Crc, false);

                //it's in the debug file
                if (t.Length != 0)
                {
                    if (t != qbKey.Text)
                        return t;
                }
                else
                {
                    //check that it's not in the user debug file
                    if ( GetNonDebugQbKey(qbKey.Crc, qbFilename) == null)
                    {
                        if (_qbKeys == null)
                            _qbKeys = new List<NonDebugQbKey>();
                        _qbKeys.Add(new NonDebugQbKey(qbKey, qbFilename));
                    }
                }
            }
            return string.Empty;
        }
Пример #38
0
 public NonDebugQbKey(QbKey qbKey, string qbFilename)
 {
     this.QbKey      = qbKey;
     this.QbFilename = qbFilename;
 }
Пример #39
0
        public static void SetGenericItems(QbItemBase item, List <GenericQbItem> gItems)
        {
            MemberInfo[] ms = item.GetType().FindMembers(MemberTypes.Property,
                                                         /*BindingFlags.DeclaredOnly |*/ BindingFlags.Instance | BindingFlags.Public,
                                                         Type.FilterName, "*");

            int                  i = 0;
            GenericQbItem        gi;
            List <GenericQbItem> list = null;

            if (gItems.Count == 0)
            {
                //test if this is an array item
                GenericQbItem gqi = QbFile.CreateGenericArrayItem(item);

                //null if not an array type
                if (gqi != null)
                {
                    //use this item to identify the array to set to 0 items
                    MemberInfo m = Array.Find(ms, delegate(MemberInfo mi)
                    {
                        return(mi.Name == gqi.SourceProperty);
                    });
                    if (m != null)
                    {
                        Type t = ((PropertyInfo)m).GetValue(item, null).GetType();
                        if (t == typeof(QbKey[]))
                        {
                            ((PropertyInfo)m).SetValue(item, new QbKey[0], null);
                        }
                        else if (t == typeof(float[]))
                        {
                            ((PropertyInfo)m).SetValue(item, new float[0], null);
                        }
                        else if (t == typeof(uint[]))
                        {
                            ((PropertyInfo)m).SetValue(item, new uint[0], null);
                        }
                        else if (t == typeof(int[]))
                        {
                            ((PropertyInfo)m).SetValue(item, new int[0], null);
                        }
                        else if (t == typeof(string[]))
                        {
                            ((PropertyInfo)m).SetValue(item, new string[0], null);
                        }
                    }
                }
            }


            while (i < gItems.Count)
            {
                gi = gItems[i++];

                if (gi.ReadOnly)
                {
                    continue;
                }

                //list = null;

                list = new List <GenericQbItem>();
                list.Add(gi);
                while (i < gItems.Count && gi.SourceProperty == gItems[i].SourceProperty)
                {
                    list.Add(gItems[i++]);
                }

                MemberInfo m = Array.Find(ms, delegate(MemberInfo mi)
                {
                    return(mi.Name == gi.SourceProperty);
                });

                if (m != null)
                {
                    Type t = ((PropertyInfo)m).GetValue(item, null).GetType();
                    if (t == typeof(QbKey[]))
                    {
                        QbKey[] qb = new QbKey[list.Count];
                        QbKey   q;
                        string  qS;

                        for (int c = 0; c < list.Count; c++)
                        {
                            q  = list[c].ToQbKey();
                            qS = item.Root.LookupDebugName(q.Crc);
                            if (qS.Length != 0)
                            {
                                q = QbKey.Create(q.Crc, qS);
                            }
                            qb[c] = q;
                        }
                        ((PropertyInfo)m).SetValue(item, qb, null);
                    }
                    else if (t == typeof(float[]))
                    {
                        float[] f = new float[list.Count];
                        for (int c = 0; c < list.Count; c++)
                        {
                            f[c] = list[c].ToSingle();
                        }
                        ((PropertyInfo)m).SetValue(item, f, null);
                    }
                    else if (t == typeof(uint[]))
                    {
                        uint[] ui = new uint[list.Count];
                        for (int c = 0; c < list.Count; c++)
                        {
                            ui[c] = list[c].ToUInt32();
                        }
                        ((PropertyInfo)m).SetValue(item, ui, null);
                    }
                    else if (t == typeof(int[]))
                    {
                        int[] si = new int[list.Count];
                        for (int c = 0; c < list.Count; c++)
                        {
                            si[c] = list[c].ToInt32();
                        }
                        ((PropertyInfo)m).SetValue(item, si, null);
                    }
                    else if (t == typeof(string[]))
                    {
                        string[] s = new string[list.Count];
                        for (int c = 0; c < list.Count; c++)
                        {
                            s[c] = list[c].ToString();
                        }
                        ((PropertyInfo)m).SetValue(item, s, null);
                    }
                    else if (t == typeof(QbKey))
                    {
                        QbKey  q  = gi.ToQbKey();
                        string qS = item.Root.LookupDebugName(q.Crc);
                        if (qS.Length != 0)
                        {
                            q = QbKey.Create(q.Crc, qS);
                        }
                        ((PropertyInfo)m).SetValue(item, q, null);
                    }
                    else if (t == typeof(float))
                    {
                        ((PropertyInfo)m).SetValue(item, gi.ToSingle(), null);
                    }
                    else if (t == typeof(uint))
                    {
                        ((PropertyInfo)m).SetValue(item, gi.ToUInt32(), null);
                    }
                    else if (t == typeof(int))
                    {
                        ((PropertyInfo)m).SetValue(item, gi.ToInt32(), null);
                    }
                    else if (t == typeof(string))
                    {
                        ((PropertyInfo)m).SetValue(item, gi.ToString(), null);
                    }
                    else if (t == typeof(byte[]))
                    {
                        ((PropertyInfo)m).SetValue(item, gi.ToByteArray(), null);
                    }
                    else
                    {
                        throw new ApplicationException(string.Format("DataType {0} not supported.", t.Name));
                    }
                }
            }
        }
Пример #40
0
 private QbKey findMissingText(QbKey song)
 {
     for (int i = 1; i < 100; i++)
     {
         if (song.Crc == QbKey.Create(string.Format("theghost{0}", i.ToString().PadLeft(3, '0'))).Crc)
             song = QbKey.Create(string.Format("theghost{0}", i.ToString().PadLeft(3, '0')));
     }
     return song;
 }
Пример #41
0
        private PakHeaderItem createBlankFile(string newQbFilename, QbKey itemType, bool filenameInHeader)
        {
            //update the filename in the collection
            List <PakHeaderItem> hd = new List <PakHeaderItem>(_pakHeaders.Values);

            PakHeaderItem newHdr = new PakHeaderItem();

            newHdr.FileLength    = 0; // (uint)(new FileInfo(localFilename)).Length;
            newHdr.FileOffset    = hd[0].FileOffset + (uint)(filenameInHeader ? PakHeaderItem.FullHeaderLength : 0x20);
            newHdr.Flags         = (PakHeaderFlags)(filenameInHeader ? PakHeaderFlags.Filename : 0);
            newHdr.HeaderStart   = 0;
            newHdr.IsStoredInPak = true;
            newHdr.Filename      = newQbFilename;
            newHdr.FileType      = itemType;
            hd.Insert(0, newHdr);

            //update the filename in the collection
            bool pastNew = false;
            Dictionary <string, PakHeaderItem> p = new Dictionary <string, PakHeaderItem>(_pakHeaders.Count);

            bool hasFoundMatch = filenameInHeader;

            foreach (PakHeaderItem ph in hd)
            {
                //small hack to determine which items need to be filled - Find another header with
                if (!hasFoundMatch && ((ph.Flags & PakHeaderFlags.Filename) != PakHeaderFlags.Filename) && ph != newHdr)
                {
                    newHdr.SetFilename(newQbFilename, itemType, _pakFormat.FileExtension, ph);
                    hasFoundMatch = true;
                }

                if (pastNew)
                {
                    ph.HeaderStart += (uint)(filenameInHeader ? PakHeaderItem.FullHeaderLength : 0x20);
                }
                else if (ph != newHdr)
                {
                    ph.FileOffset += (uint)(filenameInHeader ? PakHeaderItem.FullHeaderLength : 0x20);
                }
                else // (ph == newHdr)
                {
                    pastNew = true;
                }

                p.Add(ph.Filename.ToLower(), ph);
            }

            if (!hasFoundMatch)
            {
                newHdr.SetFilename(newQbFilename, itemType, _pakFormat.FileExtension, null);
            }

            _pakFileLength += (uint)(filenameInHeader ? PakHeaderItem.FullHeaderLength : PakHeaderItem.FullHeaderLength - PakHeaderItem.FileNameMaxLength);

            _pakHeaders = p;

            string newPakFilename = string.Format("{0}_{1}", _pakFilename, Guid.NewGuid().ToString("N"));

            using (FileStream fsO = File.Open(newPakFilename, FileMode.CreateNew))
            {
                using (BinaryEndianWriter bw = new BinaryEndianWriter(fsO))
                {
                    writeHeaderItem(bw, newHdr);
                    using (FileStream fsI = File.OpenRead(_pakFilename))
                        copyData(fsI, fsO, new FileInfo(_pakFilename).Length);
                }
            }

            File.Delete(_pakFilename);
            File.Move(newPakFilename, _pakFilename);

            return(newHdr);
        }
Пример #42
0
 /// <summary>
 /// Converts the qbkey to the enum
 /// </summary>
 /// <param name="fileType"></param>
 /// <returns>The enum item or Other if not in enum</returns>
 public static PakItemType FileTypeToPakItemType(QbKey fileType)
 {
     if (fileType == _itemTypes[0].Crc) //.qb
         return PakItemType.Qb;
     else if (fileType == _itemTypes[1].Crc) //.sqb
         return PakItemType.Sqb;
     else if (fileType == _itemTypes[2].Crc) //.dbg
         return PakItemType.Debug;
     else if (fileType == _itemTypes[3].Crc) //.img
         return PakItemType.Image;
     else if (fileType == _itemTypes[4].Crc) //.mqb
         return PakItemType.Midi;
     else if (fileType == _itemTypes[5].Crc) //.tex
         return PakItemType.Texture;
     else if (fileType == _itemTypes[6].Crc) //.skin
         return PakItemType.Skin;
     else
         return PakItemType.Other;
 }
Пример #43
0
        private void replaceFile(string qbFilename, long newLength, bool remove, WriteDataToStream callback)
        {
            int filePad = _pakFormat.FilePadSize;

            PakHeaderItem phi = null;

            if (_pakHeaders.ContainsKey(qbFilename.ToLower()))
            {
                phi = _pakHeaders[qbFilename.ToLower()];
            }
            else
            {
                string fqk = QbKey.Create(qbFilename).Crc.ToString("X").PadLeft(8, '0').ToLower();

                if (_pakHeaders.ContainsKey(fqk))
                {
                    phi = _pakHeaders[fqk];
                }
            }

            if (phi != null)
            {
                long pad = filePad - (newLength % filePad);
                if (pad == filePad)
                {
                    pad = 0;
                }

                string newPakFilename = string.Format("{0}_{1}", _pakFormat.FullPakFilename, Guid.NewGuid().ToString("N"));
                string newPabFilename = string.Format("{0}_{1}", _pakFormat.FullPabFilename, Guid.NewGuid().ToString("N"));

                uint minOffset  = uint.MaxValue;
                bool itemFound  = false;
                uint nextOffset = 0;

                foreach (PakHeaderItem ph in _pakHeaders.Values)
                {
                    if (itemFound)
                    {
                        nextOffset = ph.FileOffset + ph.HeaderStart;
                        itemFound  = false; //don't enter this if again
                    }

                    if (object.ReferenceEquals(phi, ph))
                    {
                        itemFound = true;
                    }

                    if (ph.HeaderStart + ph.FileOffset < minOffset)
                    {
                        minOffset = ph.HeaderStart + ph.FileOffset;
                    }
                }

                uint lastItemPad = 0;
                int  repPad      = filePad - ((int)phi.FileLength % filePad);
                if (repPad == filePad)
                {
                    repPad = 0;
                }

                //previously badly padded or last file
                if (nextOffset != 0 && (nextOffset - (phi.FileOffset + phi.HeaderStart)) % filePad != 0)
                {
                    repPad = (int)((nextOffset - (phi.FileOffset + phi.HeaderStart)) - phi.FileLength);
                }


                //position of the LAST header item
                long lastHeaderPos = 0;
                //the length of all the headers (like pak when there's a pab) with padding
                long allHeadersLen = minOffset;
                //position in the input file where our file is to be replaced (not including header pos)
                long fileReplacePos = (phi.HeaderStart + phi.FileOffset) - allHeadersLen;
                //position in the input file after the file that is to be replaced
                long fileAfterReplacePos = fileReplacePos + phi.FileLength + repPad; //item size before modifying header

                //open input pak
                using (FileStream fsPakI = File.Open(_pakFilename, FileMode.Open, FileAccess.Read))
                {
                    using (BinaryEndianReader brPakI = new BinaryEndianReader(fsPakI))
                    {
                        //open output pak temp file
                        using (FileStream fsPakO = File.Create(newPakFilename))
                        {
                            using (BinaryEndianWriter bwPakO = new BinaryEndianWriter(fsPakO))
                            {
                                long diffLen = 0;

                                //do not compensate for missing header when using zlib compression as the header is padded
                                if (remove && _pakFormat.CompressionType != CompressionType.ZLibChunk) //we need to cater for the header being removed on all items before it.
                                {
                                    diffLen = PakHeaderItem.FullHeaderLength;
                                    if ((phi.Flags & PakHeaderFlags.Filename) != PakHeaderFlags.Filename)
                                    {
                                        diffLen -= PakHeaderItem.FileNameMaxLength;
                                    }
                                }


                                //write out the headers
                                foreach (PakHeaderItem ph in _pakHeaders.Values)
                                {
                                    //apply offset change before finding file to be replaced
                                    //this will prevents the offset of the replaced file being changed
                                    ph.FileOffset = (uint)(ph.FileOffset - (long)diffLen);
                                    if (object.ReferenceEquals(phi, ph))
                                    {
                                        if (remove)
                                        {
                                            long remPad = filePad - (phi.FileLength % filePad);
                                            if (remPad == filePad)
                                            {
                                                remPad = 0;
                                            }

                                            diffLen = phi.FileLength + remPad; //now cater for the difference in file size
                                        }
                                        else
                                        {
                                            diffLen       = (long)((ph.FileLength + repPad) - (newLength + pad));
                                            ph.FileLength = (uint)newLength; //0 for remove
                                        }
                                    }

                                    lastHeaderPos += PakHeaderItem.FullHeaderLength;

                                    if (!(remove && object.ReferenceEquals(phi, ph)))
                                    {
                                        writeHeaderItem(bwPakO, ph);
                                    }


                                    if ((ph.Flags & PakHeaderFlags.Filename) != PakHeaderFlags.Filename)
                                    {
                                        lastHeaderPos -= PakHeaderItem.FileNameMaxLength;
                                    }
                                }

                                //Move to the "last" header
                                fsPakI.Seek(lastHeaderPos, SeekOrigin.Begin);

                                //write out "last" HeaderType
                                bwPakO.Write(brPakI.ReadBytes(4));

                                //Modify and write the offset of the "last" header's data
                                uint lastOffset = brPakI.ReadUInt32(_pakFormat.EndianType);
                                lastOffset = (uint)(lastOffset - (long)diffLen);

                                //fix bad padding on last file
                                if (nextOffset == 0 && ((lastOffset - (phi.FileOffset + phi.HeaderStart) % filePad) % filePad) != 0)
                                {
                                    lastItemPad = (uint)filePad - (uint)(lastOffset % filePad);
                                    lastOffset += lastItemPad;
                                }

                                bwPakO.Write(lastOffset, _pakFormat.EndianType);

                                //write out the end of the last header
                                copyData(fsPakI, fsPakO, allHeadersLen - fsPakI.Position);
                            }
                        }
                    }
                }

                //open input pak
                using (FileStream fsPakI = File.Open(_requiresPab ? _pakFormat.FullPabFilename : _pakFilename, FileMode.Open, FileAccess.Read))
                {
                    using (BinaryEndianReader brPakI = new BinaryEndianReader(fsPakI))
                    {
                        //open output pak temp file
                        using (FileStream fsPakO = _requiresPab ? File.Open(newPabFilename, FileMode.Create) : File.Open(newPakFilename, FileMode.Append))
                        {
                            using (BinaryEndianWriter bwPakO = new BinaryEndianWriter(fsPakO))
                            {
                                if (!_requiresPab)
                                {
                                    fsPakI.Seek(allHeadersLen, SeekOrigin.Begin);
                                }

                                //Write out the data starting from the last header to the start of the file to be replaced (minus the length of the type and offset)
                                copyData(fsPakI, fsPakO, fileReplacePos);

                                //Write the new file into the pak file
                                int pos = (int)fsPakO.Position;
                                callback(fsPakO);
                                if (pad != 0)
                                {
                                    fsPakO.Write(new byte[pad], 0, (int)pad);
                                }

                                if (!_requiresPab)
                                {
                                    fileAfterReplacePos += allHeadersLen;
                                }

                                if (lastItemPad != 0)
                                {
                                    fileAfterReplacePos -= lastItemPad; // a bit of a hack as this was not applied when this var was set as we didn't know the values
                                }
                                //write the remainder of source the pak file
                                fsPakI.Seek(fileAfterReplacePos, SeekOrigin.Begin);
                                copyData(fsPakI, fsPakO, fsPakI.Length - fileAfterReplacePos);

                                fsPakO.Flush();
                            }
                        }
                    }
                }

                fixUncompressedFileLengths(newPakFilename, newPabFilename);


                File.Delete(_pakFilename);
                File.Move(newPakFilename, _pakFilename);
                if (_requiresPab)
                {
                    File.Delete(_pakFormat.FullPabFilename);
                    File.Move(newPabFilename, _pakFormat.FullPabFilename);
                }


                _pakFormat.Compress();
            }
            else
            {
                throw new ApplicationException(string.Format("'{0}' does not exist in '{1}'", qbFilename, _pakFilename));
            }
        }
Пример #44
0
        /// <summary>
        /// Rename the filename and set the data types
        /// </summary>
        /// <param name="newFullQbFilename">Full QB filename</param>
        /// <param name="fileType">.qb or .sqb=QB, .mqb=mid, .img=img .dbg=dbg  etc</param>
        /// <param name="extension">.ngc for Wii for example</param>
        /// <param name="baseOn">base the qbKeys that are present on the passed item</param>
        public void SetFilename(string newFullQbFilename, QbKey itemType, string extension, PakHeaderItem baseOn)
        {
            if (newFullQbFilename.Length > PakHeaderItem.FileNameMaxLength)
                throw new ApplicationException("newQbFilename is too long");

            if (!itemType.HasText || itemType.Text.Length == 0)
                throw new ApplicationException("fileType is not recognised");

            //filename is stored in the header
            if ((this.Flags & PakHeaderFlags.Filename) == PakHeaderFlags.Filename)
            {
                this.Filename = newFullQbFilename;
                this.FullFilenameQbKey = 0;
            }
            else
            {
                this.Filename = QbKey.Create(newFullQbFilename).Crc.ToString("X").PadLeft(8, '0').ToLower();

                if (baseOn == null || baseOn.FullFilenameQbKey != 0)
                    this.FullFilenameQbKey = QbKey.Create(newFullQbFilename).Crc;
                else
                    this.FullFilenameQbKey = 0;
            }

            string[] pts = newFullQbFilename.Split('.');

            string nameOnly = pts[0];

            if (baseOn == null || baseOn.FullFilenameQbKey != 0)
                this.NameOnlyCrc = QbKey.Create(nameOnly).Crc;
            else
                this.NameOnlyCrc = 0;

            this.FileType = itemType;

            if (baseOn == null || baseOn.PakFullFileNameQbKey != 0)
                this.PakFullFileNameQbKey = QbKey.Create(newFullQbFilename).Crc;
            else
                this.PakFullFileNameQbKey = 0;
        }
Пример #45
0
        /// <summary>
        /// Load type data from binary reader
        /// </summary>
        public virtual void Create(QbItemType type)
        {
            setQbFormat(type);

            _qbItemType  = type;
            _qbItemValue = this.Root.PakFormat.GetQbItemValue(type, this.Root);
            _position    = 0; //unknown

            #region switch
            switch (_qbFormat)
            {
            case QbFormat.SectionPointer:
                //Complex section type:
                //  ItemId, FileId, Pointer, Reserved

                _itemQbKey = QbKey.Create(0);
                _fileId    = this.Root.FileId;
                _pointer   = 0;
                _reserved  = 0;

                _length = (5 * 4);

                _itemCount = 1;

                _pointers    = new uint[1];
                _pointers[0] = 0;
                break;

            case QbFormat.SectionValue:
                //Simple section type:
                //  ItemId, FileId, Value, Reserved

                _itemQbKey = QbKey.Create(0);
                _fileId    = this.Root.FileId;

                _itemCount = 1;

                _length = (4 * 4);
                break;

            case QbFormat.StructItemPointer:
                //Complex struct type:
                //  ItemId, Pointer, NextItemPointer

                _itemQbKey       = QbKey.Create(0);
                _pointer         = 0;
                _nextItemPointer = 0;

                _itemCount   = 1;
                _pointers    = new uint[1];
                _pointers[0] = _pointer;

                _length = (4 * 4);
                break;

            case QbFormat.StructItemValue:
                //Simple struct type:
                //  ItemId, Value (4 byte), NextItemPointer

                _itemQbKey = QbKey.Create(0);      //always null?
                _itemCount = 1;

                _length = (3 * 4);
                break;

            case QbFormat.ArrayPointer:
                //Complex array type:
                //  ItemCount, Pointer, Pointers -  (if length is 1 then pointer points to first item and Pointers are abscent)

                _itemCount = 0;
                _pointer   = 0;
                _itemQbKey = null;

                _length = (3 * 4);

                _pointers = new uint[_itemCount];
                break;

            case QbFormat.ArrayValue:
                //Simple array type:
                //  ItemCount, Pointer, Pointers -  (if length is 1 then pointer points to first item and Pointers are abscent)

                _itemQbKey = null;
                _itemCount = 0;
                _length    = (2 * 4);
                break;

            case QbFormat.StructHeader:     //when struct array item
                _length = (1 * 4);
                break;

            case QbFormat.Floats:
                _itemCount = 2;
                _length    = (1 * 4);
                break;

            case QbFormat.Unknown:
                _position += 4;     //there is no header so re add the previously removed 4
                _length    = (0 * 4);
                break;

            default:
                break;
            }
            #endregion

            setChildMode();
            _itemCount = (uint)this.CalcItemCount();
        }
Пример #46
0
        /// <summary>
        /// Load type data from binary reader
        /// </summary>
        public virtual void Create(QbItemType type)
        {
            setQbFormat(type);

            _qbItemType = type;
            _qbItemValue = this.Root.PakFormat.GetQbItemValue(type, this.Root);
            _position = 0; //unknown

            #region switch
            switch (_qbFormat)
            {
                case QbFormat.SectionPointer:
                    //Complex section type:
                    //  ItemId, FileId, Pointer, Reserved

                    _itemQbKey = QbKey.Create(0);
                    _fileId = this.Root.FileId;
                    _pointer = 0;
                    _reserved = 0;

                    _length = (5 * 4);

                    _itemCount = 1;

                    _pointers = new uint[1];
                    _pointers[0] = 0;
                    break;

                case QbFormat.SectionValue:
                    //Simple section type:
                    //  ItemId, FileId, Value, Reserved

                    _itemQbKey = QbKey.Create(0);
                    _fileId = this.Root.FileId;

                    _itemCount = 1;

                    _length = (4 * 4);
                    break;

                case QbFormat.StructItemPointer:
                    //Complex struct type:
                    //  ItemId, Pointer, NextItemPointer

                    _itemQbKey = QbKey.Create(0);
                    _pointer = 0;
                    _nextItemPointer = 0;

                    _itemCount = 1;
                    _pointers = new uint[1];
                    _pointers[0] = _pointer;

                    _length = (4 * 4);
                    break;

                case QbFormat.StructItemValue:
                    //Simple struct type:
                    //  ItemId, Value (4 byte), NextItemPointer

                    _itemQbKey = QbKey.Create(0);  //always null?
                    _itemCount = 1;

                    _length = (3 * 4);
                    break;

                case QbFormat.ArrayPointer:
                    //Complex array type:
                    //  ItemCount, Pointer, Pointers -  (if length is 1 then pointer points to first item and Pointers are abscent)

                    _itemCount = 0;
                    _pointer = 0;
                    _itemQbKey = null;

                    _length = (3 * 4);

                    _pointers = new uint[_itemCount];
                    break;

                case QbFormat.ArrayValue:
                    //Simple array type:
                    //  ItemCount, Pointer, Pointers -  (if length is 1 then pointer points to first item and Pointers are abscent)

                    _itemQbKey = null;
                    _itemCount = 0;
                    _length = (2 * 4);
                    break;

                case QbFormat.StructHeader: //when struct array item
                    _length = (1 * 4);
                    break;

                case QbFormat.Floats:
                    _itemCount = 2;
                    _length = (1 * 4);
                    break;

                case QbFormat.Unknown:
                    _position += 4; //there is no header so re add the previously removed 4
                    _length = (0 * 4);
                    break;

                default:
                    break;
            }
            #endregion

            setChildMode();
            _itemCount = (uint)this.CalcItemCount();
        }
Пример #47
0
        private bool removeBonusSong(QbFile storeQb, QbKey songId)
        {
            //find bonus song list
            QbItemArray bonusSongs = storeQb.FindItem(true, delegate(QbItemBase qib)
            {
                return (qib.QbItemType == QbItemType.StructItemArray && qib.ItemQbKey == QbKey.Create("songs"));
            }) as QbItemArray;

            //remove bonus song from list
            List<QbKey> songs = new List<QbKey>((bonusSongs.Items[0] as QbItemQbKey).Values);

            if (songs.Exists(delegate(QbKey qk)
                {
                    return qk.Crc == songId.Crc;
                }))
            {
                this.RemoveBonusSongQbItems(songId, storeQb);
                return true;
            }
            else
                return false;
        }
Пример #48
0
        /// <summary>
        /// Convert text representations
        /// </summary>
        /// <param name="text"></param>
        /// <param name="toType">Type to convert to</param>
        /// <returns></returns>
        private string convert(Type toType)
        {
            byte[] b = null;
            float f;
            uint u;
            int i;
            string result = _value;

            if (_currType == null)
                _currType = _type;

            if (_currType == toType)
                return _value;

            if (!this.CanConvertTo(toType))
                return _value;

            //if QBKey then swap between Hex and String
            if (_type == typeof(QbKey))
            {
                QbKey qb = QbKey.Create(_value);
                if (_currType == typeof(byte[]) && toType == typeof(string))
                {
                    if (_qbKey == qb)
                        return _qbKey.ToString();
                    else
                        return qb.ToString();
                }
                else if (_currType == typeof(string) && toType == typeof(byte[]))
                {
                    if (_value.Trim().Length != 0)
                        _qbKey = QbKey.Create(_value);
                    return _qbKey.Crc.ToString("X").PadLeft(8, '0');
                }
                else
                    return _value;
            }

            //get the data into a byte array
            if (_currType == typeof(float))
            {
                if (float.TryParse(_value, out f))
                    b = BitConverter.GetBytes(f);
            }
            else if (_currType == typeof(uint))
            {
                if (uint.TryParse(_value, out u))
                    b = BitConverter.GetBytes(u);
            }
            else if (_currType == typeof(int))
            {
                if (int.TryParse(_value, out i))
                    b = BitConverter.GetBytes(i);
            }
            else if (_currType == typeof(byte[]))
            {
                if (_value.Length > 2)
                {
                    b = new byte[_value.Length / 2];
                    for (int c = 0; c < _value.Length; c += 2)
                        b[c / 2] = byte.Parse(_value.Substring(c, 2), System.Globalization.NumberStyles.HexNumber);
                    if (_typeNumeric && BitConverter.IsLittleEndian)
                        Array.Reverse(b);
                }
            }
            else if (_currType == typeof(string))
            {
                b = Encoding.Default.GetBytes(_value);
            }

            //else
            //    throw new ArgumentOutOfRangeException(string.Format("{0} is not supported", _currType.FullName));

            if (b != null)
            {
                //convert the data to the new type
                if (toType == typeof(float))
                {
                    f = BitConverter.ToSingle(b, 0);
                    result = f.ToString();
                }
                else if (toType == typeof(uint))
                {
                    u = BitConverter.ToUInt32(b, 0);
                    result = u.ToString();
                }
                else if (toType == typeof(int))
                {
                    i = BitConverter.ToInt32(b, 0);
                    result = i.ToString();
                }
                else if (toType == typeof(byte[]))
                {
                    StringBuilder sb = new StringBuilder();
                    if (_typeNumeric && BitConverter.IsLittleEndian)
                        Array.Reverse(b);
                    foreach (byte x in b)
                        sb.Append(x.ToString("X").PadLeft(2, '0'));
                    result = sb.ToString();
                }
                else if (toType == typeof(string))
                {
                    result = Encoding.Default.GetString(b);
                }

                //else
                //    throw new ArgumentOutOfRangeException(string.Format("{0} is not supported", toType.FullName));
            }
            return result;
        }
Пример #49
0
        private void removeSongFromSonglist(QbFile qbSongList, QbKey qkSong)
        {
            QbItemArray songsList = qbSongList.FindItem(QbKey.Create("gh3_songlist"), false) as QbItemArray;
            if (songsList != null)
            {
                List<QbKey> songlistQk = new List<QbKey>(((QbItemQbKey)songsList.Items[0]).Values);

                if (songlistQk.Contains(qkSong))
                    songlistQk.Remove(qkSong);

                //update gh3_songlist
                ((QbItemQbKey)songsList.Items[0]).Values = songlistQk.ToArray();

                qbSongList.AlignPointers();
                qbSongList.IsValid();
            }
        }
Пример #50
0
        /// <summary>
        /// Convert text representations
        /// </summary>
        /// <param name="text"></param>
        /// <param name="toType">Type to convert to</param>
        /// <returns></returns>
        private string convert(Type toType)
        {
            byte[] b = null;
            float  f;
            uint   u;
            int    i;
            string result = _value;

            if (_currType == null)
            {
                _currType = _type;
            }

            if (_currType == toType)
            {
                return(_value);
            }

            if (!this.CanConvertTo(toType))
            {
                return(_value);
            }

            //if QBKey then swap between Hex and String
            if (_type == typeof(QbKey))
            {
                QbKey qb = QbKey.Create(_value);
                if (_currType == typeof(byte[]) && toType == typeof(string))
                {
                    if (_qbKey == qb)
                    {
                        return(_qbKey.ToString());
                    }
                    else
                    {
                        return(qb.ToString());
                    }
                }
                else if (_currType == typeof(string) && toType == typeof(byte[]))
                {
                    if (_value.Trim().Length != 0)
                    {
                        _qbKey = QbKey.Create(_value);
                    }
                    return(_qbKey.Crc.ToString("X").PadLeft(8, '0'));
                }
                else
                {
                    return(_value);
                }
            }


            //get the data into a byte array
            if (_currType == typeof(float))
            {
                if (float.TryParse(_value, out f))
                {
                    b = BitConverter.GetBytes(f);
                }
            }
            else if (_currType == typeof(uint))
            {
                if (uint.TryParse(_value, out u))
                {
                    b = BitConverter.GetBytes(u);
                }
            }
            else if (_currType == typeof(int))
            {
                if (int.TryParse(_value, out i))
                {
                    b = BitConverter.GetBytes(i);
                }
            }
            else if (_currType == typeof(byte[]))
            {
                if (_value.Length > 2)
                {
                    b = new byte[_value.Length / 2];
                    for (int c = 0; c < _value.Length; c += 2)
                    {
                        b[c / 2] = byte.Parse(_value.Substring(c, 2), System.Globalization.NumberStyles.HexNumber);
                    }
                    if (_typeNumeric && BitConverter.IsLittleEndian)
                    {
                        Array.Reverse(b);
                    }
                }
            }
            else if (_currType == typeof(string))
            {
                b = Encoding.Default.GetBytes(_value);
            }


            //else
            //    throw new ArgumentOutOfRangeException(string.Format("{0} is not supported", _currType.FullName));

            if (b != null)
            {
                //convert the data to the new type
                if (toType == typeof(float))
                {
                    f      = BitConverter.ToSingle(b, 0);
                    result = f.ToString();
                }
                else if (toType == typeof(uint))
                {
                    u      = BitConverter.ToUInt32(b, 0);
                    result = u.ToString();
                }
                else if (toType == typeof(int))
                {
                    i      = BitConverter.ToInt32(b, 0);
                    result = i.ToString();
                }
                else if (toType == typeof(byte[]))
                {
                    StringBuilder sb = new StringBuilder();
                    if (_typeNumeric && BitConverter.IsLittleEndian)
                    {
                        Array.Reverse(b);
                    }
                    foreach (byte x in b)
                    {
                        sb.Append(x.ToString("X").PadLeft(2, '0'));
                    }
                    result = sb.ToString();
                }
                else if (toType == typeof(string))
                {
                    result = Encoding.Default.GetString(b);
                }

                //else
                //    throw new ArgumentOutOfRangeException(string.Format("{0} is not supported", toType.FullName));
            }
            return(result);
        }
Пример #51
0
 /// <summary>
 /// Add song to bonus list and shop
 /// </summary>
 /// <param name="songQk"></param>
 public void BonusSongAddToGame(QbFile qbStore, QbFile qbSongList, QbKey qkSong, bool insertAdd)
 {
     //is this song (this) in the bonus tiers already?
     bool found = getAllBonusSongs(qbStore).Contains(qkSong);
     addSongToSonglist(qbSongList, qkSong);
     this.AddBonusSongQbItems(qkSong, qbStore, insertAdd);
 }
Пример #52
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);
                    }

                }
            }
        }
Пример #53
0
        /// <summary>
        /// Add a new file in to the PAK, currently just inserts it at the start.
        /// </summary>
        /// <param name="newFullQbFilename">Full QB filename</param>
        /// <param name="fileType">.qb or .sqb=QB, .mqb=mid, .img=img .dbg=dbg  etc</param>
        /// <param name="extension">.qb.ngc for Wii for example</param>
        public void AddFile(QbFile newQbFile, string newQbFilename, QbKey itemType, bool filenameInHeader)
        {
            createBlankFile(newQbFilename, itemType, filenameInHeader);

            this.ReplaceFile(newQbFilename, newQbFile);
        }
Пример #54
0
 /// <summary>
 /// Attempts to take a qbkey key without any text and lookup a named file type
 /// </summary>
 /// <returns></returns>
 public static QbKey LookupFileType(QbKey fileType)
 {
     foreach (QbKey k in _itemTypes)
     {
         if (fileType.Crc == k.Crc)
             return k;
     }
     return fileType;
 }
Пример #55
0
        private void createBonusSongAudio(DirectoryInfo rootPath, string xboxWav, QbKey dest)
        {
            string dat = string.Format(@"{0}\music\{1}.dat.ngc", rootPath.FullName.TrimEnd('\\'), dest.Text);
            string wad = string.Format(@"{0}\music\{1}.wad.ngc", rootPath.FullName.TrimEnd('\\'), dest.Text);

            if (!File.Exists(dat) || !File.Exists(wad))
                DatWad.CreateDatWad(dest, _project.FileManager.PakFormat.EndianType, dat, wad, xboxWav, xboxWav, xboxWav, xboxWav);
        }
Пример #56
0
        private QbItemStruct findTierProgStruct(QbKey firstChild, QbItemArray careerProgressionStruct)
        {
            QbKey tname = QbKey.Create("name");

            return careerProgressionStruct.FindItem(true, delegate(QbItemBase qib)
            {
                QbItemStruct qs = (qib as QbItemStruct);
                if (qs != null && qs.Items.Count != 0 && qs.Items[0] is QbItemQbKey)
                {
                    QbItemQbKey qk = (QbItemQbKey)qs.Items[0];
                    if (qk.ItemQbKey.Crc == tname.Crc && qk.Values[0].Crc == firstChild.Crc)
                        return true;
                }
                return false;
            }) as QbItemStruct;
        }
Пример #57
0
        /// <summary>
        /// Load type data from binary reader
        /// </summary>
        public virtual void Construct(BinaryEndianReader br, QbItemType type)
        {
            setQbFormat(type);
            _qbItemType  = type;
            _qbItemValue = this.Root.PakFormat.GetQbItemValue(type, this.Root);
            _position    = this.StreamPos(br) - (1 * 4); //subtract the already read header
            uint itemQbKeyCrc = 0;

            #region switch
            switch (_qbFormat)
            {
            case QbFormat.SectionPointer:
                //Complex section type:
                //  ItemId, FileId, Pointer, Reserved
                _hasQbKey = true;

                itemQbKeyCrc = br.ReadUInt32(this.Root.PakFormat.EndianType);
                _fileId      = br.ReadUInt32(this.Root.PakFormat.EndianType);
                _pointer     = br.ReadUInt32(this.Root.PakFormat.EndianType);
                _reserved    = br.ReadUInt32(this.Root.PakFormat.EndianType);

                _length = (5 * 4);

                if (type == QbItemType.SectionScript)
                {
                    _itemCount = 0;
                }
                else
                {
                    _itemCount = 1;
                }
                _pointers    = new uint[1];
                _pointers[0] = _pointer;

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

            case QbFormat.SectionValue:
                //Simple section type:
                //  ItemId, FileId, Value, Reserved
                _hasQbKey = true;

                itemQbKeyCrc = br.ReadUInt32(this.Root.PakFormat.EndianType);
                _fileId      = br.ReadUInt32(this.Root.PakFormat.EndianType);

                _itemCount = 1;

                _length = (3 * 4);
                break;

            case QbFormat.StructItemPointer:
                //Complex struct type:
                //  ItemId, Pointer, NextItemPointer
                _hasQbKey = true;

                itemQbKeyCrc     = br.ReadUInt32(this.Root.PakFormat.EndianType);
                _pointer         = br.ReadUInt32(this.Root.PakFormat.EndianType);
                _nextItemPointer = br.ReadUInt32(this.Root.PakFormat.EndianType);

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

                _itemCount   = 1;
                _pointers    = new uint[1];
                _pointers[0] = _pointer;

                _length = (4 * 4);
                break;

            case QbFormat.StructItemValue:
                //Simple struct type:
                //  ItemId, Value (4 byte), NextItemPointer
                _hasQbKey = true;

                itemQbKeyCrc = br.ReadUInt32(this.Root.PakFormat.EndianType);

                //always null?
                if (_itemQbKey == 0 && _qbItemType == QbItemType.StructItemQbKeyString)
                {
                    _itemQbKey = null;
                }

                _itemCount = 1;

                _length = (2 * 4);
                break;

            case QbFormat.ArrayPointer:
                //Complex array type:
                //  ItemCount, Pointer, Pointers -  (if length is 1 then pointer points to first item and Pointers are abscent)
                _hasQbKey = false;

                _itemCount   = br.ReadUInt32(this.Root.PakFormat.EndianType);
                _pointer     = br.ReadUInt32(this.Root.PakFormat.EndianType);
                itemQbKeyCrc = 0;

                _length = (3 * 4);

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

                _pointers = new uint[_itemCount];

                if (_itemCount == 1)
                {
                    _pointers[0] = _pointer;
                }
                else if (_itemCount > 1)
                {
                    for (int i = 0; i < _itemCount; i++)
                    {
                        _pointers[i] = br.ReadUInt32(this.Root.PakFormat.EndianType);
                    }

                    _length += (_itemCount * 4);
                }
                break;

            case QbFormat.ArrayValue:
                //Simple array type:
                //  ItemCount, Pointer, Pointers -  (if length is 1 then pointer points to first item and Pointers are abscent)
                _hasQbKey = false;

                itemQbKeyCrc = 0;
                _itemCount   = br.ReadUInt32(this.Root.PakFormat.EndianType);
                _length      = (2 * 4);
                if (_itemCount > 1)
                {
                    _pointer = br.ReadUInt32(this.Root.PakFormat.EndianType);
                    if (this.StreamPos(br) != _pointer)     //pointer test
                    {
                        throw new ApplicationException(QbFile.FormatBadPointerExceptionMessage(this, this.StreamPos(br), _pointer));
                    }
                    _length += (1 * 4);
                }
                break;

            case QbFormat.StructHeader:     //when struct array item
                _hasQbKey = false;
                _length   = (1 * 4);
                break;

            case QbFormat.Floats:
                _hasQbKey = false;
                _length   = (1 * 4);
                break;

            case QbFormat.Unknown:
                _hasQbKey  = false;
                _position += 4;     //there is no header so re add the previously removed 4
                _length    = (0 * 4);
                break;

            default:
                break;
            }
            #endregion

            if (!_hasQbKey)
            {
                _itemQbKey = null;
            }
            else
            {
                string debugName = Root.LookupDebugName(itemQbKeyCrc);
                if (debugName.Length != 0)
                {
                    _itemQbKey = QbKey.Create(itemQbKeyCrc, debugName);
                }
                else
                {
                    _itemQbKey = QbKey.Create(itemQbKeyCrc);
                }
            }
        }