示例#1
0
        private const uint DBCFmtSig = 0x43424457; // WDBC

        public DBC(string filename)
        {
            if (!CASC.Initialized)
            {
                return;
            }
            if (!CASC.FileExists(filename))
            {
                return;
            }

            #region Read DBC
            using (var br = new BinaryReader(CASC.OpenFile(filename)))
            {
                // Make sure we've got a valid DBC
                if (br.BaseStream.Length < DBCHeader.Size)
                {
                    return;
                }
                if (DBCFmtSig != br.ReadUInt32())
                {
                    return;
                }

                // Read DBC header
                Header = new DBCHeader();
                Header.Read(br);

                // Read strings to a table
                var readPos        = br.BaseStream.Position;
                var strTableOffset = br.BaseStream.Position + (Header.RecordCount * Header.RecordSize);
                br.BaseStream.Position = strTableOffset;
                var strTable = new Dictionary <int, string>();
                while (br.BaseStream.Position < br.BaseStream.Length)
                {
                    var idx = (int)(br.BaseStream.Position - strTableOffset);
                    strTable[idx] = br.ReadCString();
                }

                // Move back to where we were
                br.BaseStream.Position = readPos;
                Rows = new T[Header.RecordCount];
                var tProperties = typeof(T).GetProperties();
                for (int i = 0; i < Header.RecordCount; i++)
                {
                    var row      = new T();
                    var startPos = br.BaseStream.Position;

                    // Can't we use a foreach here?
                    for (int j = 0; j < tProperties.Length; j++)
                    {
                        switch (Type.GetTypeCode(tProperties[j].PropertyType))
                        {
                        case TypeCode.Int32:
                            tProperties[j].SetValue(row, br.ReadInt32());
                            break;

                        case TypeCode.UInt32:
                            tProperties[j].SetValue(row, br.ReadUInt32());
                            break;

                        case TypeCode.Single:
                            tProperties[j].SetValue(row, br.ReadSingle());
                            break;

                        case TypeCode.String:
                            tProperties[j].SetValue(row, strTable[br.ReadInt32()]);
                            break;

                        default:
                            Console.WriteLine("wat?? {0}", Type.GetTypeCode(tProperties[j].PropertyType));
                            break;
                        }
                    }

                    var diffSize = (br.BaseStream.Position - startPos);
                    if (diffSize > Header.RecordSize)
                    {
                        return;                               // We read too much! Struct is wrong
                    }
                    if (diffSize < Header.RecordSize)
                    {
                        br.ReadBytes((int)(Header.RecordSize - diffSize));                               // We read too little! Let's pad!
                    }
                    Rows[i] = row;
                }
            }
            #endregion
        }
示例#2
0
        private const uint DBCFmtSig = 0x43424457; // WDBC

        public DBC(string filename, BackgroundWorker worker = null)
        {
            if (!CASC.Initialized)
            {
                return;
            }
            if (!CASC.FileExists(filename))
            {
                return;
            }

            #region Read DBC
            using (var br = new BinaryReader(CASC.OpenFile(filename)))
            {
                // Make sure we've got a valid DBC
                if (br.BaseStream.Length < DBCHeader.Size)
                {
                    return;
                }
                if (DBCFmtSig != br.ReadUInt32())
                {
                    return;
                }

                // Read DBC header
                Header = new DBCHeader();
                Header.Read(br);

                // Read strings to a table
                var readPos        = br.BaseStream.Position;
                var strTableOffset = br.BaseStream.Position + (Header.RecordCount * Header.RecordSize);
                br.BaseStream.Position = strTableOffset;
                var strTable = new Dictionary <int, string>();
                while (br.BaseStream.Position < br.BaseStream.Length)
                {
                    var idx = (int)(br.BaseStream.Position - strTableOffset);
                    strTable[idx] = br.ReadCString();
                }

                // Move back to where we were
                br.BaseStream.Position = readPos;

                Debug.Assert(Marshal.SizeOf(typeof(T)) == Header.RecordSize,
                             $"Invalid record size, got {Marshal.SizeOf(typeof(T))}, expected {Header.RecordSize}.");

                Rows = new T[Header.RecordCount];
                var tProperties = typeof(T).GetProperties();
                for (var i = 0; i < Header.RecordCount; i++)
                {
                    var row      = new T();
                    var startPos = br.BaseStream.Position;

                    foreach (var prop in tProperties)
                    {
                        switch (Type.GetTypeCode(prop.PropertyType))
                        {
                        case TypeCode.Int32:
                            prop.SetValue(row, br.ReadInt32());
                            break;

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

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

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

                        default:
                            Console.WriteLine("wat?? {0}", Type.GetTypeCode(prop.PropertyType));
                            break;
                        }
                    }

                    if (worker != null)
                    {
                        worker.ReportProgress(i * 100 / Header.RecordCount, row);
                    }

                    var diffSize = (br.BaseStream.Position - startPos);
                    if (diffSize > Header.RecordSize)
                    {
                        return;                               // We read too much! Struct is wrong
                    }
                    if (diffSize < Header.RecordSize)
                    {
                        br.ReadBytes((int)(Header.RecordSize - diffSize));                               // We read too little! Let's pad!
                    }
                    Rows[i] = row;
                }
            }
            #endregion
        }