public void LoadFileDataComplete(CASCHandler casc) { if (!casc.FileExists("DBFilesClient\\FileDataComplete.db2")) { return; } Logger.WriteLine("WowRootHandler: loading file names from FileDataComplete.db2..."); using (var s = casc.OpenFile("DBFilesClient\\FileDataComplete.db2")) { WDB5Reader fd = new WDB5Reader(s); Jenkins96 hasher = new Jenkins96(); foreach (var row in fd) { string path = row.Value.GetField <string>(0); string name = row.Value.GetField <string>(1); string fullname = path + name; ulong fileHash = hasher.ComputeHash(fullname); // skip invalid names if (!casc.FileExists(fileHash)) { //Logger.WriteLine("Invalid file name: {0}", fullname); continue; } CASCFile.Files[fileHash] = new CASCFile(fileHash, fullname); } } }
public Storage(Stream stream) { DB2Reader reader; using (stream) using (var bin = new BinaryReader(stream)) { var identifier = new string(bin.ReadChars(4)); stream.Position = 0; switch (identifier) { case "WDC3": reader = new WDC3Reader(stream); break; case "WDC2": case "1SLC": reader = new WDC2Reader(stream); break; case "WDC1": reader = new WDC1Reader(stream); break; case "WDB6": reader = new WDB6Reader(stream); break; case "WDB5": reader = new WDB5Reader(stream); break; case "WDB4": reader = new WDB4Reader(stream); break; case "WDB3": reader = new WDB3Reader(stream); break; case "WDB2": reader = new WDB2Reader(stream); break; case "WDBC": reader = new WDBCReader(stream); break; default: throw new Exception("DB type " + identifier + " is not supported!"); } } FieldInfo[] fields = typeof(T).GetFields(); FieldCache <T>[] fieldCache = new FieldCache <T> [fields.Length]; for (int i = 0; i < fields.Length; ++i) { bool indexMapAttribute = reader.Flags.HasFlagExt(DB2Flags.Index) ? Attribute.IsDefined(fields[i], typeof(IndexAttribute)) : false; fieldCache[i] = new FieldCache <T>(fields[i], indexMapAttribute); } Parallel.ForEach(reader.AsEnumerable(), new ParallelOptions() { MaxDegreeOfParallelism = 1 }, row => { T entry = new T(); row.Value.GetFields(fieldCache, entry); lock (this) Add(row.Value.Id, entry); }); }
private const uint WDB5FmtSig = 0x35424457; // WDB5 public WDB5Writer(WDB5Reader reader, IDictionary <int, T> storage, Stream stream) : base(reader) { // always 2 empties StringTableSize++; WDB5RowSerializer <T> serializer = new WDB5RowSerializer <T>(this); serializer.Serialize(storage); serializer.GetCopyRows(); RecordsCount = serializer.Records.Count - CopyData.Count; using (var writer = new BinaryWriter(stream)) { int minIndex = storage.Keys.Min(); int maxIndex = storage.Keys.Max(); int copyTableSize = Flags.HasFlagExt(DB2Flags.Sparse) ? 0 : CopyData.Count * 8; writer.Write(WDB5FmtSig); writer.Write(RecordsCount); writer.Write(FieldsCount); writer.Write(RecordSize); writer.Write(StringTableSize); // if flags & 0x01 != 0, offset to the offset_map writer.Write(reader.TableHash); writer.Write(reader.LayoutHash); writer.Write(minIndex); writer.Write(maxIndex); writer.Write(reader.Locale); writer.Write(copyTableSize); // copytablesize writer.Write((uint)Flags); writer.Write((ushort)IdFieldIndex); if (storage.Count == 0) { return; } // field meta writer.WriteArray(Meta); // record data uint recordsOffset = (uint)writer.BaseStream.Position; foreach (var record in serializer.Records) { if (!CopyData.ContainsKey(record.Key)) { record.Value.CopyTo(writer.BaseStream); } } // string table if (!Flags.HasFlagExt(DB2Flags.Sparse)) { writer.WriteCString(""); foreach (var str in StringTable) { writer.WriteCString(str.Key); } } // sparse data if (Flags.HasFlagExt(DB2Flags.Sparse)) { // change the StringTableSize to the offset_map position long oldPos = writer.BaseStream.Position; writer.BaseStream.Position = 16; writer.Write((uint)oldPos); writer.BaseStream.Position = oldPos; WriteOffsetRecords(writer, serializer, recordsOffset, maxIndex - minIndex + 1); } // secondary key if (Flags.HasFlagExt(DB2Flags.SecondaryKey)) { WriteSecondaryKeyData(writer, storage, maxIndex - minIndex + 1); } // index table if (Flags.HasFlagExt(DB2Flags.Index)) { writer.WriteArray(serializer.Records.Keys.Except(CopyData.Keys).ToArray()); } // copy table if (!Flags.HasFlagExt(DB2Flags.Sparse)) { foreach (var copyRecord in CopyData) { writer.Write(copyRecord.Key); writer.Write(copyRecord.Value); } } } }