public void ReloadContents() { Body = new DBCBody(); Reader = new DBCReader(_filePath); var name = Path.GetFileNameWithoutExtension(_filePath); var binding = BindingManager.GetInstance().FindBinding(name); if (binding == null) { throw new Exception($"Binding not found: {name}.txt"); } Header = Reader.ReadDBCHeader(); Reader.ReadDBCRecords(Body, name); Reader.ReadStringBlock(); }
/** * Reads the DBC Header, saving it to the class and returning it */ public DBCHeader ReadDBCHeader() { DBCHeader header; using (FileStream fileStream = new FileStream(_filePath, FileMode.Open)) { _fileSize = fileStream.Length; int count = Marshal.SizeOf(typeof(DBCHeader)); byte[] readBuffer = new byte[count]; using (BinaryReader reader = new BinaryReader(fileStream)) { readBuffer = reader.ReadBytes(count); _filePosition = reader.BaseStream.Position; header = ReadStruct <DBCHeader>(reader, readBuffer); } } _header = header; return(header); }
public void ItemsToDBC() { DBCReader reader = new DBCReader("data/itemheader.dbc"); BinaryWriter writer = new BinaryWriter(File.OpenWrite("Item.dbc")); DBCHeader header = new DBCHeader { DBCmagic = DBCReader.DBCFmtSig, RecordsCount = (uint)items.Count, FieldsCount = (uint)reader.FieldsCount, RecordSize = (uint)reader.RecordSize, StringTableSize = (uint)reader.StringTableSize }; //Write header content writer.Write(DBCReader.DBCFmtSig); writer.Write(header.RecordsCount); writer.Write(header.FieldsCount); writer.Write(header.RecordSize); writer.Write(header.StringTableSize); //Write item struct foreach (var pair in items) { Item item = pair.Value; byte[] buffer = new byte[Marshal.SizeOf(typeof(Item))]; GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned); Marshal.StructureToPtr(item, handle.AddrOfPinnedObject(), true); writer.Write(buffer, 0, buffer.Length); handle.Free(); } //Write string table foreach (var pair in reader.StringTable) { writer.Write(Encoding.UTF8.GetBytes(pair.Value + "\0")); } writer.Close(); MessageBox.Show("Conversion to DBC complete, please check main folder new Item.dbc file!"); }
public Task ExportToDbc(IDatabaseAdapter adapter, MainWindow.UpdateProgressFunc updateProgress, string IdKey, string bindingName) { return(Task.Run(() => { var binding = BindingManager.GetInstance().FindBinding(bindingName); if (binding == null) { throw new Exception("Binding not found: " + bindingName); } var body = new DBCBodyToSerialize(); var orderClause = ""; if (binding.OrderOutput) { orderClause = binding.Fields.FirstOrDefault(f => f.Name.Equals(IdKey)) != null ? $" ORDER BY `{IdKey}`" : ""; } body.Records = LoadRecords(adapter, bindingName, orderClause, updateProgress); var numRows = body.Records.Count(); if (numRows == 0) { throw new Exception("No rows to export"); } Header = new DBCHeader { FieldCount = (uint)binding.Fields.Count(), // Magic is always 'WDBC' https://wowdev.wiki/DBC Magic = 1128416343, RecordCount = (uint)numRows, RecordSize = (uint)binding.CalcRecordSize(), StringBlockSize = body.GenerateStringOffsetsMap(binding) }; SaveDbcFile(updateProgress, body, binding); })); }
public void ReloadContents() { var name = Path.GetFileNameWithoutExtension(_filePath); var binding = BindingManager.GetInstance().FindBinding(name); if (binding == null) { throw new Exception($"Binding not found: {name}.txt"); } var headerWatch = new Stopwatch(); var bodyWatch = new Stopwatch(); var stringWatch = new Stopwatch(); Body = new DBCBody(); Reader = new DBCReader(_filePath); // Header headerWatch.Start(); Header = Reader.ReadDBCHeader(); headerWatch.Stop(); // Body bodyWatch.Start(); Reader.ReadDBCRecords(Body, name); bodyWatch.Stop(); // Strings stringWatch.Start(); Reader.ReadStringBlock(); stringWatch.Stop(); // Total var totalElapsed = stringWatch.ElapsedMilliseconds + bodyWatch.ElapsedMilliseconds; Logger.Info( $"Loaded {name}.dbc into memory in {totalElapsed}ms.\n" + $"\tHeader: {headerWatch.ElapsedMilliseconds}ms\n" + $"\tRecords: {bodyWatch.ElapsedMilliseconds}ms\n" + $"\tStrings: {stringWatch.ElapsedMilliseconds}ms"); }
public Task ExportToDbc(IDatabaseAdapter adapter, MainWindow.UpdateProgressFunc updateProgress, string IdKey, string bindingName) { return(Task.Run(() => { var binding = BindingManager.GetInstance().FindBinding(bindingName); if (binding == null) { throw new Exception("Binding not found: " + bindingName); } var orderClause = binding.Fields.FirstOrDefault(f => f.Name.Equals(IdKey)) != null ? $" ORDER BY `{IdKey}`" : ""; var rows = adapter.Query(string.Format($"SELECT * FROM `{bindingName}`{orderClause}")).Rows; uint numRows = uint.Parse(rows.Count.ToString()); if (numRows == 0) { throw new Exception("No rows to export"); } Header = new DBCHeader(); Header.FieldCount = (uint)binding.Fields.Count(); // Magic is always 'WDBC' https://wowdev.wiki/DBC Header.Magic = 1128416343; Header.RecordCount = numRows; Header.RecordSize = (uint)binding.CalcRecordSize(); Header.StringBlockSize = 0; var body = new DBCBodyToSerialize(); body.Records = new List <Dictionary <string, object> >((int)Header.RecordCount); for (int i = 0; i < numRows; ++i) { body.Records.Add(ConvertDataRowToDictionary(rows[i])); } Header.StringBlockSize = body.GenerateStringOffsetsMap(binding); SaveDbcFile(updateProgress, body, binding); })); }
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 }
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 }