public void SaveToFile(string bindingName) { var binding = BindingManager.GetInstance().FindBinding(bindingName); // Convert all string offsets to real strings binding.Fields.Where((field) => field.Type == BindingType.STRING_OFFSET).ToList().ForEach((field) => { MemoryData.ForEach((record) => { var value = record[field.Name].ToString(); if (uint.TryParse(value, out var offset)) { record[field.Name] = Reader.LookupStringOffset(offset); } }); }); Logger.Debug("Saving to DBC file: " + bindingName); var newBody = new DBCBodyToSerialize { Records = MemoryData }; newBody.GenerateStringOffsetsMap(binding); SaveDbcFile(UpdateProgress, newBody, binding); }
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()); // Hardcode for 3.3.5a 12340 Header = new DBCHeader(); Header.FieldCount = (uint)binding.Fields.Count(); Header.Magic = 1128416343; Header.RecordCount = numRows; Header.RecordSize = (uint)binding.CalcRecordSize(); Header.StringBlockSize = 0; var body = new DBCBodyToSerialize(); body.Records = new List <DataRow>((int)Header.RecordCount); for (int i = 0; i < numRows; ++i) { body.Records.Add(rows[i]); } Header.StringBlockSize = body.GenerateStringOffsetsMap(binding); SaveDbcFile(updateProgress, body, binding); })); }
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); })); }
protected void SaveDbcFile(MainWindow.UpdateProgressFunc updateProgress, DBCBodyToSerialize body, Binding.Binding binding) { string path = $"Export/{binding.Name}.dbc"; Directory.CreateDirectory(Path.GetDirectoryName(path)); if (File.Exists(path)) { File.Delete(path); } using (FileStream fileStream = new FileStream(path, FileMode.Create)) { using (BinaryWriter writer = new BinaryWriter(fileStream)) { // Write the header file int count = Marshal.SizeOf(typeof(DBCHeader)); byte[] buffer = new byte[count]; GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned); Marshal.StructureToPtr(Header, handle.AddrOfPinnedObject(), true); writer.Write(buffer, 0, count); handle.Free(); // Write each record for (int i = 0; i < Header.RecordCount; ++i) { if (i % 250 == 0) { // Visual studio says these casts are redundant but it does not work without them double percent = (double)i / (double)Header.RecordCount; updateProgress(percent); } var record = body.Records[i]; foreach (var entry in binding.Fields) { if (!record.Table.Columns.Contains(entry.Name)) { throw new Exception($"Column binding not found {entry.Name} in table, using binding {binding.Name}.txt"); } var data = record[entry.Name].ToString(); if (entry.Type == BindingType.INT) { if (int.TryParse(data, out int value)) { writer.Write(value); } else { writer.Write(0); } } else if (entry.Type == BindingType.UINT) { if (uint.TryParse(data, out uint value)) { writer.Write(value); } else { writer.Write(0u); } } else if (entry.Type == BindingType.FLOAT) { if (float.TryParse(data, out float value)) { writer.Write(value); } else { writer.Write(0f); } } else if (entry.Type == BindingType.DOUBLE) { if (double.TryParse(data, out double value)) { writer.Write(value); } else { writer.Write(0d); } } else if (entry.Type == BindingType.STRING_OFFSET) { writer.Write(data.Length == 0 ? 0 : body.OffsetStorage[data.GetHashCode()]); } else { throw new Exception($"Unknwon type: {entry.Type} on entry {entry.Name} binding {binding.Name}"); } } } // Write string block int[] offsetsStored = body.OffsetStorage.Values.ToArray(); writer.Write(Encoding.UTF8.GetBytes("\0")); for (int i = 0; i < offsetsStored.Length; ++i) { writer.Write(Encoding.UTF8.GetBytes(body.ReverseStorage[offsetsStored[i]] + "\0")); } } } }