Beispiel #1
0
        public STLReader(string fileName)
        {
            reader = BinaryReaderExtensions.FromFile(fileName);

            MPQHeader mHdr = reader.ReadStruct <MPQHeader>();
            StlHeader sHdr = reader.ReadStruct <StlHeader>();

            //StlEntry sEntry = reader.ReadStruct<StlEntry>();

            RecordsCount = sHdr.entriesSize / 0x50;

            m_rows = new byte[RecordsCount][];

            for (int i = 0; i < RecordsCount; ++i)
            {
                m_rows[i] = reader.ReadBytes(0x50);
            }

            //StringTable = new Dictionary<int, string>();

            //if (reader.BaseStream.Position != reader.BaseStream.Length)
            //{
            //    while (reader.BaseStream.Position != reader.BaseStream.Length)
            //    {
            //        if (reader.PeekChar() == 0)
            //        {
            //            reader.BaseStream.Position++;
            //            continue;
            //        }

            //        int offset = (int)reader.BaseStream.Position;
            //        StringTable[offset] = reader.ReadStringNull();
            //    }
            //}
        }
Beispiel #2
0
        public DB5SparseReader(string fileName)
        {
            using (var reader = BinaryReaderExtensions.FromFile(fileName))
            {
                if (reader.BaseStream.Length < HeaderSize)
                {
                    throw new InvalidDataException(String.Format("File {0} is corrupted!", fileName));
                }

                if (reader.ReadUInt32() != DB5FmtSig)
                {
                    throw new InvalidDataException(String.Format("File {0} isn't valid DB5 sparse file!", fileName));
                }

                RecordsCount = reader.ReadInt32();
                FieldsCount  = reader.ReadInt32();
                RecordSize   = reader.ReadInt32();
                int offsetsPos = reader.ReadInt32();

                uint tableHash = reader.ReadUInt32();
                uint build     = reader.ReadUInt32();

                int MinId         = reader.ReadInt32();
                int MaxId         = reader.ReadInt32();
                int locale        = reader.ReadInt32();
                int CopyTableSize = reader.ReadInt32();
                int metaFlags     = reader.ReadInt32();

                FieldOffsets  = new short[FieldsCount];
                FieldBitSizes = new short[FieldsCount];

                for (var i = 0; i < FieldsCount; ++i)
                {
                    FieldBitSizes[i] = reader.ReadInt16();
                    FieldOffsets[i]  = reader.ReadInt16();
                }

                reader.BaseStream.Position = offsetsPos;

                var numOffsets = MaxId - MinId + 1;
                for (var i = 0; i < numOffsets; ++i)
                {
                    var offset = reader.ReadInt32();
                    var length = reader.ReadUInt16();
                    if (offset != 0 && length != 0)
                    {
                        var rowData       = reader.ReadBytesAt(offset, length);
                        var rowDataWithId = new byte[length + 4];

                        Array.Copy(BitConverter.GetBytes(MinId + i), rowDataWithId, 4);
                        Array.Copy(rowData, 0, rowDataWithId, 4, rowData.Length);

                        RowData.Add(MinId + i, rowDataWithId);
                    }
                }

                RecordsCount = RowData.Count;
            }
        }
Beispiel #3
0
        public DB2Reader(string fileName)
        {
            using (var reader = BinaryReaderExtensions.FromFile(fileName))
            {
                if (reader.BaseStream.Length < HeaderSize)
                {
                    throw new InvalidDataException(String.Format("File {0} is corrupted!", fileName));
                }

                if (reader.ReadUInt32() != DB2FmtSig)
                {
                    throw new InvalidDataException(String.Format("File {0} isn't valid DBC file!", fileName));
                }

                RecordsCount    = reader.ReadInt32();
                FieldsCount     = reader.ReadInt32();
                RecordSize      = reader.ReadInt32();
                StringTableSize = reader.ReadInt32();

                // WDB2 specific fields
                uint tableHash = reader.ReadUInt32(); // new field in WDB2
                uint build     = reader.ReadUInt32(); // new field in WDB2
                uint unk1      = reader.ReadUInt32(); // new field in WDB2

                if (build > 12880)                    // new extended header
                {
                    int MinId  = reader.ReadInt32();  // new field in WDB2
                    int MaxId  = reader.ReadInt32();  // new field in WDB2
                    int locale = reader.ReadInt32();  // new field in WDB2
                    int unk5   = reader.ReadInt32();  // new field in WDB2

                    if (MaxId != 0)
                    {
                        var diff = MaxId - MinId + 1;   // blizzard is weird people...
                        reader.ReadBytes(diff * 4);     // an index for rows
                        reader.ReadBytes(diff * 2);     // a memory allocation bank
                    }
                }

                m_rows = new byte[RecordsCount][];

                for (int i = 0; i < RecordsCount; i++)
                {
                    m_rows[i] = reader.ReadBytes(RecordSize);
                }

                int stringTableStart = (int)reader.BaseStream.Position;

                StringTable = new Dictionary <int, string>();

                while (reader.BaseStream.Position != reader.BaseStream.Length)
                {
                    int index = (int)reader.BaseStream.Position - stringTableStart;
                    StringTable[index] = reader.ReadStringNull();
                }
            }
        }
Beispiel #4
0
        public ADBReader(string fileName)
        {
            using (var reader = BinaryReaderExtensions.FromFile(fileName))
            {
                if (reader.BaseStream.Length < HeaderSize)
                {
                    throw new InvalidDataException(String.Format("File {0} is corrupted!", fileName));
                }

                var signature = reader.ReadUInt32();

                if (signature != ADBFmtSig)
                {
                    throw new InvalidDataException(String.Format("File {0} isn't valid DBC file!", fileName));
                }

                RecordsCount    = reader.ReadInt32();
                FieldsCount     = reader.ReadInt32(); // not fields count in WCH2
                RecordSize      = reader.ReadInt32();
                StringTableSize = reader.ReadInt32();

                index = new List <int>();

                // WCH2 specific fields
                uint tableHash = reader.ReadUInt32(); // new field in WCH2
                Build = reader.ReadUInt32();          // new field in WCH2

                int unk1   = reader.ReadInt32();      // Unix time in WCH2
                int unk2   = reader.ReadInt32();      // new field in WCH2
                int unk3   = reader.ReadInt32();      // new field in WCH2 (index table?)
                int locale = reader.ReadInt32();      // new field in WCH2
                int unk5   = reader.ReadInt32();      // new field in WCH2

                if (unk3 != 0)
                {
                    reader.ReadBytes(unk3 * 4 - HeaderSize);     // an index for rows
                    reader.ReadBytes(unk3 * 2 - HeaderSize * 2); // a memory allocation bank
                }

                m_rows = new byte[RecordsCount][];

                for (int i = 0; i < RecordsCount; i++)
                {
                    m_rows[i] = reader.ReadBytes(RecordSize);
                }

                int stringTableStart = (int)reader.BaseStream.Position;

                StringTable = new Dictionary <int, string>();

                while (reader.BaseStream.Position != reader.BaseStream.Length)
                {
                    int index = (int)reader.BaseStream.Position - stringTableStart;
                    StringTable[index] = reader.ReadStringNull();
                }
            }
        }
Beispiel #5
0
        public WDBReader(string fileName)
        {
            using (var reader = BinaryReaderExtensions.FromFile(fileName))
            {
                if (reader.BaseStream.Length < HeaderSize)
                {
                    throw new InvalidDataException(String.Format("File {0} is corrupted!", fileName));
                }

                var signature = reader.ReadUInt32();

                if (!WDBSigs.Contains(signature))
                {
                    throw new InvalidDataException(String.Format("File {0} isn't valid WDB file!", fileName));
                }

                uint build   = reader.ReadUInt32();
                uint locale  = reader.ReadUInt32();
                var  unk1    = reader.ReadInt32();
                var  unk2    = reader.ReadInt32();
                var  version = reader.ReadInt32();

                m_rows = new Dictionary <int, byte[]>();

                while (reader.BaseStream.Position != reader.BaseStream.Length)
                {
                    var entry = reader.ReadInt32();
                    var size  = reader.ReadInt32();
                    if (entry == 0 && size == 0 && reader.BaseStream.Position == reader.BaseStream.Length)
                    {
                        break;
                    }
                    var row = new byte[0]
                              .Concat(BitConverter.GetBytes(entry))
                              .Concat(reader.ReadBytes(size))
                              .ToArray();
                    m_rows.Add(entry, row);
                }

                RecordsCount = m_rows.Count;
            }
        }
Beispiel #6
0
        public DBCReader(string fileName)
        {
            using (var reader = BinaryReaderExtensions.FromFile(fileName))
            {
                if (reader.BaseStream.Length < HeaderSize)
                {
                    throw new InvalidDataException(String.Format("File {0} is corrupted!", fileName));
                }

                if (reader.ReadUInt32() != DBCFmtSig)
                {
                    throw new InvalidDataException(String.Format("File {0} isn't valid DBC file!", fileName));
                }

                RecordsCount    = reader.ReadInt32();
                FieldsCount     = reader.ReadInt32();
                RecordSize      = reader.ReadInt32();
                StringTableSize = reader.ReadInt32();
                index           = new List <int>();
                Build           = 0;

                m_rows = new byte[RecordsCount][];

                for (int i = 0; i < RecordsCount; i++)
                {
                    m_rows[i] = reader.ReadBytes(RecordSize);
                }

                int stringTableStart = (int)reader.BaseStream.Position;

                StringTable = new Dictionary <int, string>();

                while (reader.BaseStream.Position != reader.BaseStream.Length)
                {
                    int index = (int)reader.BaseStream.Position - stringTableStart;
                    StringTable[index] = reader.ReadStringNull();
                }

                reader.BaseStream.Position = stringTableStart;
                Strings = reader.ReadBytes(StringTableSize);
            }
        }
Beispiel #7
0
        public DB3Reader(string fileName)
        {
            using (var reader = BinaryReaderExtensions.FromFile(fileName))
            {
                if (reader.BaseStream.Length < HeaderSize)
                {
                    throw new InvalidDataException(String.Format("File {0} is corrupted!", fileName));
                }

                uint signature = reader.ReadUInt32();

                if (signature != DB3FmtSig)
                {
                    throw new InvalidDataException(String.Format("File {0} isn't valid DBC file!", fileName));
                }

                RecordsCount    = reader.ReadInt32();
                FieldsCount     = reader.ReadInt32();
                RecordSize      = reader.ReadInt32();
                StringTableSize = reader.ReadInt32();

                // WDB2 specific fields
                uint tableHash = reader.ReadUInt32();   // new field in WDB2
                Build = reader.ReadUInt32();            // new field in WDB2
                uint unk1 = reader.ReadUInt32();        // new field in WDB2

                int MinId         = reader.ReadInt32(); // new field in WDB2
                int MaxId         = reader.ReadInt32(); // new field in WDB2
                int locale        = reader.ReadInt32(); // new field in WDB2
                int CopyTableSize = reader.ReadInt32();

                index       = new List <int>();
                StringTable = new Dictionary <int, string>();

                List <byte[]> rows = new List <byte[]>();

                //  m_rows = new byte[RecordsCount + CopyTableSize/8][];

                List <int[]> pairlist = new List <int[]>();

                List <string> strlist = new List <string>();
                List <string> strl    = new List <string>();

                Console.WriteLine(reader.BaseStream.Length);



                if (RecordsCount <= 0)
                {
                    return;
                }

                Console.WriteLine("rsize:" + RecordSize);
                Console.WriteLine("rcount:" + RecordsCount);
                Console.WriteLine("csize:" + (6 * (MaxId - MinId + 1) + HeaderSize));
                Console.WriteLine("minID:" + MinId);
                Console.WriteLine("maxID:" + MaxId);
                Console.WriteLine("CPSize:" + CopyTableSize);


                int foffset1 = reader.ReadInt32();

                Console.WriteLine("foffset1:" + foffset1);
                //   reader.BaseStream.Position = reader.BaseStream.Position - 4;

                int rlength1 = reader.ReadUInt16();

                Console.WriteLine("rlength1:" + rlength1);

                reader.BaseStream.Position = reader.BaseStream.Position - 6;


                bool isRawData = (foffset1 == (6 * (MaxId - MinId + 1) + HeaderSize));

                int stringTableStart = HeaderSize + RecordsCount * RecordSize;
                int stringTableEnd   = stringTableStart + StringTableSize;


                Console.WriteLine("stStart:" + stringTableStart);
                Console.WriteLine("stEnd:" + stringTableEnd);

                bool hasIndex = stringTableEnd + CopyTableSize < reader.BaseStream.Length;

                Console.WriteLine(hasIndex);



                if (isRawData)
                {
                    while (reader.BaseStream.Position != foffset1)
                    {
                        int[] pairs = new int[2];

                        pairs[0] = reader.ReadInt32();
                        pairs[1] = reader.ReadInt16();

                        //  Console.WriteLine(pairs[0]);
                        //  Console.WriteLine(pairs[1]);
                        pairlist.Add(pairs);
                        //  strl.Add(pairs[0].ToString()+","+pairs[1].ToString());
                    }

                    //  File.WriteAllLines("offsettable.txt",strl);


                    foreach (var p in pairlist)
                    {
                        if (p[0] > 0)
                        {
                            reader.BaseStream.Position = p[0];

                            rows.Add(reader.ReadBytes(p[1]));
                        }
                    }



                    m_rows = rows.ToArray();


                    int countc = 0;



                    // reader.BaseStream.Position = stringTableEnd;

                    reader.ReadUInt16();

                    while (reader.BaseStream.Position != reader.BaseStream.Length && hasIndex)
                    {
                        int id = reader.ReadInt32();

                        index.Add(id);

                        // lookup.Add(id,count);

                        countc++;
                        if (countc >= RecordsCount)
                        {
                            break;
                        }
                    }


                    return;
                }

                for (int i = 0; i < RecordsCount; i++)
                {
                    rows.Add(reader.ReadBytes(RecordSize));
                    // m_rows[i] = reader.ReadBytes(RecordSize);
                }

                m_rows = rows.ToArray();

                // int stringTableStart = (int)reader.BaseStream.Position;

                // int stringTableEnd = (stringTableStart + StringTableSize);

                // Console.WriteLine("stableStart:"+stringTableStart);

                //  Console.WriteLine("stableEnd:" + (stringTableStart+StringTableSize).ToString());

                //  StringTable = new Dictionary<int, string>();

                while (reader.BaseStream.Position != stringTableEnd)
                {
                    int index = (int)reader.BaseStream.Position - stringTableStart;
                    StringTable[index] = reader.ReadStringNull();
                }

                //   index = new List<int>();

                Console.WriteLine(stringTableEnd);

                int count = 0;


                while (reader.BaseStream.Position != reader.BaseStream.Length && hasIndex)
                {
                    int id = reader.ReadInt32();

                    index.Add(id);

                    // lookup.Add(id,count);

                    count++;
                    if (count >= RecordsCount)
                    {
                        break;
                    }
                }

                long copyTablePos = stringTableEnd + (hasIndex ? 4 * RecordsCount : 0);

                Console.WriteLine("cpPos:" + copyTablePos);



                if (copyTablePos != reader.BaseStream.Length && CopyTableSize != 0)
                {
                    reader.BaseStream.Position = copyTablePos;

                    while (reader.BaseStream.Position != reader.BaseStream.Length)
                    {
                        int id     = reader.ReadInt32();
                        int idcopy = reader.ReadInt32();

                        strlist.Add(id.ToString() + "," + idcopy.ToString());

                        //  Console.WriteLine("ID:"+id);
                        //  Console.WriteLine("IDcopy:"+idcopy);

                        //  Console.WriteLine(index.IndexOf(idcopy));

                        if (index.IndexOf(idcopy) > 0)
                        {
                            // m_rows[count] = m_rows[index.IndexOf(idcopy)];

                            rows.Add(rows[index.IndexOf(idcopy)]);

                            index.Add(id);

                            count++;

                            RecordsCount++;
                        }

                        /*else
                         * {
                         *  m_rows[count] = new byte[RecordSize];
                         *
                         *  Array.Copy(BitConverter.GetBytes(id), m_rows[count], 4);
                         *
                         *  index.Add(id);
                         *
                         *  count++;
                         *
                         *  RecordsCount++;
                         * }
                         */



                        /*  byte[] copyRow = Lookup[idcopy];
                         * byte[] newRow = new byte[copyRow.Length];
                         * Array.Copy(copyRow, newRow, newRow.Length);
                         * Array.Copy(BitConverter.GetBytes(id), newRow, 4);
                         *
                         * Lookup.Add(id, newRow);*/
                    }

                    m_rows = rows.ToArray();
                }
            }
        }
Beispiel #8
0
        public DB4Reader(string fileName)
        {
            using (var reader = BinaryReaderExtensions.FromFile(fileName))
            {
                if (reader.BaseStream.Length < HeaderSize)
                {
                    throw new InvalidDataException(String.Format("File {0} is corrupted!", fileName));
                }

                if (reader.ReadUInt32() != DB4FmtSig)
                {
                    throw new InvalidDataException(String.Format("File {0} isn't valid DB4 file!", fileName));
                }

                RecordsCount    = reader.ReadInt32();
                FieldsCount     = reader.ReadInt32();
                RecordSize      = reader.ReadInt32();
                StringTableSize = reader.ReadInt32();

                uint tableHash = reader.ReadUInt32();
                uint build     = reader.ReadUInt32();
                uint unk1      = reader.ReadUInt32();

                int MinId         = reader.ReadInt32();
                int MaxId         = reader.ReadInt32();
                int locale        = reader.ReadInt32();
                int CopyTableSize = reader.ReadInt32();
                int metaFlags     = reader.ReadInt32();

                int stringTableStart = HeaderSize + RecordsCount * RecordSize;
                int stringTableEnd   = stringTableStart + StringTableSize;

                // Index table
                int[] m_indexes = null;
                HasSeparateIndexColumn = stringTableEnd + CopyTableSize < reader.BaseStream.Length;

                if (HasSeparateIndexColumn)
                {
                    reader.BaseStream.Position = stringTableEnd;

                    m_indexes = new int[RecordsCount];

                    for (int i = 0; i < RecordsCount; i++)
                    {
                        m_indexes[i] = reader.ReadInt32();
                    }
                }

                // Records table
                reader.BaseStream.Position = HeaderSize;

                for (int i = 0; i < RecordsCount; i++)
                {
                    byte[] recordBytes = reader.ReadBytes(RecordSize);

                    if (HasSeparateIndexColumn)
                    {
                        byte[] newRecordBytes = new byte[RecordSize + 4];

                        Array.Copy(BitConverter.GetBytes(m_indexes[i]), newRecordBytes, 4);
                        Array.Copy(recordBytes, 0, newRecordBytes, 4, recordBytes.Length);

                        Lookup.Add(m_indexes[i], newRecordBytes);
                    }
                    else
                    {
                        Lookup.Add(BitConverter.ToInt32(recordBytes, 0), recordBytes);
                    }
                }

                // Strings table
                reader.BaseStream.Position = stringTableStart;

                StringTable = new Dictionary <int, string>();

                while (reader.BaseStream.Position != stringTableEnd)
                {
                    int index = (int)reader.BaseStream.Position - stringTableStart;
                    StringTable[index] = reader.ReadStringNull();
                }

                // Copy index table
                long copyTablePos = stringTableEnd + (HasSeparateIndexColumn ? 4 * RecordsCount : 0);

                if (copyTablePos != reader.BaseStream.Length && CopyTableSize != 0)
                {
                    reader.BaseStream.Position = copyTablePos;

                    while (reader.BaseStream.Position < reader.BaseStream.Length)
                    {
                        try
                        {
                            int id     = reader.ReadInt32();
                            int idcopy = reader.ReadInt32();

                            byte[] copyRow = Lookup[idcopy];
                            byte[] newRow  = new byte[copyRow.Length];
                            Array.Copy(copyRow, newRow, newRow.Length);
                            Array.Copy(BitConverter.GetBytes(id), newRow, 4);

                            Lookup.Add(id, newRow);
                            RecordsCount++;
                        }
                        catch (KeyNotFoundException)
                        {
                        }
                    }
                }
            }
        }
Beispiel #9
0
        public static IWowClientDBReader GetReader(string file, XmlElement definition)
        {
            IWowClientDBReader reader;

            var ext = Path.GetExtension(file).ToUpperInvariant();

            if (ext == ".DBC")
            {
                reader = new DBCReader(file);
            }
            else if (ext == ".DB2")
            {
                using (var binaryReader = BinaryReaderExtensions.FromFile(file))
                {
                    switch (binaryReader.ReadUInt32())
                    {
                    case DB2Reader.DB2FmtSig:
                    {
                        reader = new DB2Reader(file);
                        break;
                    }

                    case DB3Reader.DB3FmtSig:
                    {
                        reader = new DB2Reader(file);
                        break;
                    }

                    case DB4Reader.DB4FmtSig:
                    {
                        try
                        {
                            reader = new DB4Reader(file);
                        }
                        catch
                        {
                            reader = new DB4SparseReader(file);
                        }
                        break;
                    }

                    case DB5Reader.DB5FmtSig:
                    {
                        try
                        {
                            reader = new DB5Reader(file, definition);
                        }
                        catch
                        {
                            reader = new DB5SparseReader(file);
                        }
                        break;
                    }

                    default:
                        throw new InvalidDataException(string.Format("Unknown file type {0}", ext));
                    }
                }
            }
            else if (ext == ".ADB")
            {
                reader = new ADBReader(file);
            }
            else if (ext == ".WDB")
            {
                reader = new WDBReader(file);
            }
            else if (ext == ".STL")
            {
                reader = new STLReader(file);
            }
            else
            {
                throw new InvalidDataException(String.Format("Unknown file type {0}", ext));
            }

            return(reader);
        }
Beispiel #10
0
        public DBCReaderGeneric(string fileName)
        {
            using (var reader = BinaryReaderExtensions.FromFile(fileName))
            {
                if (reader.BaseStream.Length < HeaderSize)
                {
                    throw new InvalidDataException(String.Format("File {0} is corrupted!", fileName));
                }

                if (reader.ReadUInt32() != DBCFmtSig)
                {
                    throw new InvalidDataException(String.Format("File {0} isn't valid DBC file!", fileName));
                }

                RecordsCount    = reader.ReadInt32();
                FieldsCount     = reader.ReadInt32();
                RecordSize      = reader.ReadInt32();
                StringTableSize = reader.ReadInt32();

                long pos = reader.BaseStream.Position;
                long stringTableStart = reader.BaseStream.Position + RecordsCount * RecordSize;
                reader.BaseStream.Position = stringTableStart;

                Dictionary <int, string> StringTable = new Dictionary <int, string>();

                while (reader.BaseStream.Position != reader.BaseStream.Length)
                {
                    int index = (int)(reader.BaseStream.Position - stringTableStart);
                    StringTable[index] = reader.ReadStringNull();
                }

                reader.BaseStream.Position = pos;

                m_rows = new T[RecordsCount];

                var props = typeof(T).GetProperties();

                for (int i = 0; i < RecordsCount; i++)
                {
                    T row = new T();

                    long rowStart = reader.BaseStream.Position;

                    for (int j = 0; j < props.Length; j++)
                    {
                        var prop = props[j];

                        switch (Type.GetTypeCode(prop.PropertyType))
                        {
                        case TypeCode.Int32:
                            prop.SetValue(row, reader.ReadInt32());
                            break;

                        case TypeCode.UInt32:
                            prop.SetValue(row, reader.ReadUInt32());
                            break;

                        case TypeCode.Single:
                            prop.SetValue(row, reader.ReadSingle());
                            break;

                        case TypeCode.String:
                            prop.SetValue(row, StringTable[reader.ReadInt32()]);
                            break;

                        default:
                            throw new Exception("Unsupported field type " + Type.GetTypeCode(prop.PropertyType));
                        }
                    }

                    if (reader.BaseStream.Position - rowStart != RecordSize)
                    {
                        // struct bigger than record size
                        if (reader.BaseStream.Position - rowStart > RecordSize)
                        {
                            throw new Exception("Incorrect DBC struct!");
                        }

                        // struct smaller than record size (incomplete)
                        reader.BaseStream.Position += RecordSize - (reader.BaseStream.Position - rowStart);
                    }

                    m_rows[i] = row;
                }
            }
        }
Beispiel #11
0
        public DB5Reader(string fileName, XmlElement definition)
        {
            var fields = definition.GetElementsByTagName("field");

            var         db5index = 0;
            XmlNodeList indexes  = definition.GetElementsByTagName("index");

            if (indexes.Count == 1)
            {
                for (var j = 0; j < fields.Count; ++j)
                {
                    if (fields[j].Attributes["name"].Value == indexes[0]["primary"].InnerText)
                    {
                        db5index = j;
                        break;
                    }
                }
            }

            using (var reader = BinaryReaderExtensions.FromFile(fileName))
            {
                if (reader.BaseStream.Length < HeaderSize)
                {
                    throw new InvalidDataException(string.Format("File {0} is corrupted!", fileName));
                }

                if (reader.ReadUInt32() != DB5FmtSig)
                {
                    throw new InvalidDataException(string.Format("File {0} isn't valid DB5 file!", fileName));
                }

                RecordsCount    = reader.ReadInt32();
                FieldsCount     = reader.ReadInt32();
                RecordSize      = reader.ReadInt32();
                StringTableSize = reader.ReadInt32();

                uint tableHash = reader.ReadUInt32();
                uint build     = reader.ReadUInt32();

                int MinId         = reader.ReadInt32();
                int MaxId         = reader.ReadInt32();
                int locale        = reader.ReadInt32();
                int CopyTableSize = reader.ReadInt32();
                int metaFlags     = reader.ReadInt32();

                FieldOffsets  = new short[FieldsCount];
                FieldBitSizes = new short[FieldsCount];

                for (var i = 0; i < FieldsCount; ++i)
                {
                    FieldBitSizes[i] = reader.ReadInt16();
                    FieldOffsets[i]  = reader.ReadInt16();
                }

                var headerEnd = reader.BaseStream.Position;

                var stringTableStart = headerEnd + RecordsCount * RecordSize;
                var stringTableEnd   = stringTableStart + StringTableSize;

                // Index table
                int[] m_indexes = null;
                HasSeparateIndexColumn = stringTableEnd + CopyTableSize < reader.BaseStream.Length;

                if (HasSeparateIndexColumn)
                {
                    reader.BaseStream.Position = stringTableEnd;

                    m_indexes = new int[RecordsCount];

                    for (int i = 0; i < RecordsCount; i++)
                    {
                        m_indexes[i] = reader.ReadInt32();
                    }
                }

                // Records table
                reader.BaseStream.Position = headerEnd;

                for (int i = 0; i < RecordsCount; i++)
                {
                    byte[] recordBytes = reader.ReadBytes(RecordSize);

                    if (HasSeparateIndexColumn)
                    {
                        byte[] newRecordBytes = new byte[RecordSize + 4];

                        Array.Copy(BitConverter.GetBytes(m_indexes[i]), newRecordBytes, 4);
                        Array.Copy(recordBytes, 0, newRecordBytes, 4, recordBytes.Length);

                        Lookup.Add(m_indexes[i], newRecordBytes);
                    }
                    else
                    {
                        var idBytes = new byte[4];
                        Array.Copy(recordBytes, FieldOffsets[db5index], idBytes, 0, 4 - FieldBitSizes[db5index] / 8);
                        Lookup.Add(BitConverter.ToInt32(idBytes, 0), recordBytes);
                    }
                }

                // Strings table
                reader.BaseStream.Position = stringTableStart;

                StringTable = new Dictionary <int, string>();

                while (reader.BaseStream.Position != stringTableEnd)
                {
                    int index = (int)(reader.BaseStream.Position - stringTableStart);
                    StringTable[index] = reader.ReadStringNull();
                }

                // Copy index table
                long copyTablePos = stringTableEnd + (HasSeparateIndexColumn ? 4 * RecordsCount : 0);

                if (copyTablePos != reader.BaseStream.Length && CopyTableSize != 0)
                {
                    reader.BaseStream.Position = copyTablePos;

                    while (reader.BaseStream.Position < reader.BaseStream.Length)
                    {
                        try
                        {
                            int id     = reader.ReadInt32();
                            int idcopy = reader.ReadInt32();

                            byte[] copyRow = Lookup[idcopy];
                            byte[] newRow  = new byte[copyRow.Length];
                            Array.Copy(copyRow, newRow, newRow.Length);
                            Array.Copy(BitConverter.GetBytes(id), newRow, 4);

                            Lookup.Add(id, newRow);
                            RecordsCount++;
                        }
                        catch (KeyNotFoundException)
                        {
                        }
                    }
                }
            }
        }
Beispiel #12
0
        public WDBReader(string fileName)
        {
            using (var reader = BinaryReaderExtensions.FromFile(fileName))
            {
                if (reader.BaseStream.Length < HeaderSize)
                {
                    throw new InvalidDataException(String.Format("File {0} is corrupted!", fileName));
                }

                var signature = reader.ReadUInt32();

                if (!WDBSigs.Contains(signature))
                {
                    throw new InvalidDataException(String.Format("File {0} isn't valid WDB file!", fileName));
                }

                Build = reader.ReadUInt32();
                uint locale = reader.ReadUInt32();
                var  unk1   = reader.ReadInt32();

                //   Console.WriteLine(unk1);

                var unk2 = reader.ReadInt32();

                //    Console.WriteLine(unk2);

                // Console.WriteLine("-----------------");

                var version = reader.ReadInt32();
                index = new List <int>();
                //m_rows = new Dictionary<int, byte[]>();
                m_rows = new List <byte[]>();

                StringTable = new Dictionary <int, string>();
                while (reader.BaseStream.Position != reader.BaseStream.Length)
                {
                    var entry = reader.ReadInt32();
                    var size  = reader.ReadInt32();
                    if (entry == 0 && size == 0 && reader.BaseStream.Position == reader.BaseStream.Length)
                    {
                        break;
                    }
                    var row = new byte[0]
                              .Concat(BitConverter.GetBytes(entry))
                              .Concat(reader.ReadBytes(size))
                              .ToArray();
                    //  m_rows.Add(entry, row);
                    m_rows.Add(row);
                }

                RecordsCount = m_rows.Count;


                /* foreach (var r in m_rows)
                 * {
                 *
                 *   Console.WriteLine(r.Value.Length);
                 * }
                 *
                 */
                /* RecordSize = 0;
                 * FieldsCount = 0;
                 * StringTableSize = 0;*/
            }
        }