public static void Read(string fileName) { string dataPath = dbfilesclient + fileName; string path = Casc.GetFile(dataPath); byte[] fileData = File.ReadAllBytes(path); // Check DB2 Version // // WDC // if (fileData[0] == Convert.ToByte('W') && fileData[1] == Convert.ToByte('D') && fileData[2] == Convert.ToByte('C')) { // WDC 1 // if (fileData[3] == Convert.ToByte('1')) { WDC1.Read(fileName, fileData); } // WDC 2 // if (fileData[3] == Convert.ToByte('2')) { WDC2.Read(fileName, fileData); } } // WDB // else { Debug.LogWarning("Warning: " + "DB2 Format not supported: " + fileData[0] + fileData[1] + fileData[2] + fileData[3] + fileName); } }
private DBHeader ExtractHeader(BinaryReader dbReader) { DBHeader header = null; string signature = dbReader.ReadString(4); if (string.IsNullOrWhiteSpace(signature)) { return(null); } switch (signature) { case "WDB5": header = new WDB5(); break; case "WDB6": header = new WDB6(); break; case "WDC1": header = new WDC1(); break; default: return(null); } header?.ReadHeader(ref dbReader, signature); return(header); }
public void Read(string fileName) { string file = "BattlePetAbilityEffect.dbd"; var stream = File.Open(fileName, FileMode.Open, FileAccess.Read, FileShare.Read); //var stream = Casc.GetFileStream(fileName); using (var bin = new BinaryReader(stream)) { DB2Reader reader; var identifier = new string(bin.ReadChars(4)); stream.Position = 0; switch (identifier) { case "WDC1": reader = new WDC1(fileName, stream); break; case "WDC2": reader = new WDC2(fileName, stream); break; default: Debug.Log("DBC Type " + identifier + " is not supported"); break; } } }
private DBHeader ExtractHeader(BinaryReader dbReader) { DBHeader header = null; string signature = dbReader.ReadString(4); if (string.IsNullOrWhiteSpace(signature)) { return(null); } if (signature[0] != 'W') { signature = signature.Reverse(); } switch (signature) { case "WDBC": header = new WDBC(); break; case "WDB2": case "WCH2": header = new WDB2(); break; case "WDB5": header = new WDB5(); break; case "WDB6": header = new WDB6(); break; case "WCH5": header = new WCH5(FileName); break; case "WCH7": header = new WCH7(FileName); break; case "WCH8": header = new WCH8(FileName); break; case "WDC1": header = new WDC1(); break; case "WDC2": header = new WDC2(); break; case "WMOB": case "WGOB": case "WQST": case "WIDB": case "WNDB": case "WITX": case "WNPC": case "WPTX": case "WRDN": header = new WDB(); break; case "HTFX": header = new HTFX(); break; } header?.ReadHeader(ref dbReader, signature); return(header); }
private void ParseWDC1(MemoryStream stream, string file) { stream.Position = 0; Dictionary <int, FieldType> FieldTypes = new Dictionary <int, FieldType>() { { 8, FieldType.ULONG }, { 4, FieldType.INT }, { 2, FieldType.USHORT }, { 1, FieldType.BYTE }, }; using (var dbReader = new BinaryReader(stream, Encoding.UTF8)) { WDC1 header = ExtractHeader(dbReader) as WDC1; if (header == null) { return; } if (header.RecordCount == 0 || header.RecordSize == 0) { return; } long pos = dbReader.BaseStream.Position; Dictionary <int, string> StringTable = new StringTable().Read(dbReader, pos, pos + header.StringBlockSize); bool stringtableused = StringTable.Values.Any(x => !string.IsNullOrWhiteSpace(x)) && !header.HasOffsetTable; List <FieldInfo> fields = new List <FieldInfo>(); var copyTable = header.ReadOffsetData(dbReader, dbReader.BaseStream.Position); for (int f = 0; f < header.ColumnMeta.Count; f++) { FieldType byteType; if (f == header.IdIndex || (f == 0 && header.HasIndexTable)) { fields.Add(new FieldInfo() { ArraySize = 1, Type = FieldType.INT }); continue; } if (header.ColumnMeta[f].CompressionType == CompressionType.None) { int bitSize = header.FieldStructure[f].BitCount; byteType = FieldTypes[NextPow2(~~(bitSize + 7) / 8)]; } else if (header.ColumnMeta[f].CompressionType > CompressionType.Immediate) { byteType = FieldType.INT; } else { byteType = FieldTypes[NextPow2(~~(header.ColumnMeta[f].BitWidth + 7) / 8)]; } fields.Add(new FieldInfo() { ArraySize = header.ColumnMeta[f].ArraySize, Type = byteType == FieldType.INT ? FieldType.UNKNOWN : byteType }); } int offset = 0; for (int i = 0; i < fields.Count; i++) { switch (fields[i].Type) { case FieldType.BYTE: offset++; continue; case FieldType.USHORT: offset += 2; continue; case FieldType.INT: offset += 4; continue; case FieldType.ULONG: offset += 8; continue; } List <FieldType> options = new List <FieldType>() { FieldType.INT, FieldType.FLOAT, FieldType.STRING }; if (!stringtableused) { options.Remove(FieldType.STRING); //Stringtable not used } List <int> ints = new List <int>(); List <float> floats = new List <float>(); foreach (var c in copyTable) { for (int x = 0; x < fields[i].ArraySize; x++) { int asInt = BitConverter.ToInt32(c.Value.Skip(offset + (4 * x)).Take(4).ToArray(), 0); if (asInt > 0) { ints.Add(asInt); if (FloatUtil.IsLikelyFloat(asInt)) { floats.Add(BitConverter.ToSingle(BitConverter.GetBytes(asInt), 0)); } } } } // remove 0's as they could be anything - if all removed then guess its an int ints.RemoveAll(x => x == 0); if (ints.Count == 0) { fields[i].Type = FieldType.INT; offset += (4 * fields[i].ArraySize); continue; } // stringtable doesn't contain string so cant be a string if (options.Contains(FieldType.STRING) && ints.Any(x => !StringTable.ContainsKey(x))) { options.Remove(FieldType.STRING); } if (floats.Count / (float)ints.Count >= 0.85) { fields[i].Type = FieldType.FLOAT; } else if (options.Contains(FieldType.STRING)) { fields[i].Type = FieldType.STRING; } else if (header.ColumnMeta[i].CompressionType == CompressionType.Immediate && header.ColumnMeta[i].Cardinality == 0) { fields[i].Type = FieldType.UINT; } else { fields[i].Type = FieldType.INT; } offset += (4 * fields[i].ArraySize); } Table table = new Table(); table.Name = Path.GetFileNameWithoutExtension(file); table.Fields = new List <Field>(); string format = $"X{fields.Count.ToString("X").Length}"; //X2, X3 etc for (int i = 0; i < fields.Count; i++) { if (header.RelationshipCount > 0 && i == fields.Count - 1) { continue; } Field field = new Field(); field.Name = (i == header.IdIndex ? "ID" : $"field{i.ToString(format)}"); field.IsIndex = (i == header.IdIndex); field.ArraySize = (field.IsIndex ? 1 : fields[i].ArraySize); field.Type = fields[i].Type.ToString().ToLower(); table.Fields.Add(field); Console.WriteLine($"Name: {field.Name} | Array: {field.ArraySize} | Type: {field.Type}"); } tables.Add(table); Database.ForceGC(); } }