public unsafe bool LoadData() { if (IsLoaded) { return(true); } byte[] signature = mReader.ReadBytes(4); string str = Encoding.UTF8.GetString(signature); if (str != "WDBC") { throw new Exception("Invalid signature in DBC file!"); } var fields = mCreationType.GetFields(); int fieldCount = DBCHelper.FieldCount(fields, mCreationType); uint numRecords = mReader.ReadUInt32(); uint numFields = mReader.ReadUInt32(); uint recordSize = mReader.ReadUInt32(); uint stringSize = mReader.ReadUInt32(); mReader.BaseStream.Position = numRecords * recordSize + 20; byte[] stringData = mReader.ReadBytes((int)stringSize); string fullStr = Encoding.UTF8.GetString(stringData); string[] strings = fullStr.Split(new string[] { "\0" }, StringSplitOptions.None); Dictionary <int, string> stringTable = new Dictionary <int, string>(); int curPos = 0; foreach (var strEnt in strings) { stringTable.Add(curPos, strEnt); curPos += Encoding.UTF8.GetByteCount(strEnt) + 1; } mReader.BaseStream.Position = 20; if (numFields != fieldCount) { throw new Exception("numFields != fieldCount in " + FileName + "!"); } for (uint i = 0; i < numRecords; ++i) { var t = Activator.CreateInstance(mCreationType); long posStart = mReader.BaseStream.Position; foreach (var field in fields) { switch (Type.GetTypeCode(field.FieldType)) { case TypeCode.Int32: { int value = mReader.ReadInt32(); field.SetValue(t, value); break; } case TypeCode.UInt32: { uint uvalue = mReader.ReadUInt32(); field.SetValue(t, uvalue); break; } case TypeCode.String: { int offset = mReader.ReadInt32(); string strFromTable; if (!stringTable.TryGetValue(offset, out strFromTable)) { throw new InvalidOperationException("Invalid index into stringtable found!"); } string strVal = strFromTable; field.SetValue(t, strVal); break; } case TypeCode.Byte: { byte bvalue = mReader.ReadByte(); field.SetValue(t, bvalue); break; } case TypeCode.Object: { try { if (field.FieldType == typeof(LocalizedString)) { string strValue = ""; for (uint j = 0; j < 16; ++j) { int offset = mReader.ReadInt32(); string strFromTable; if (strValue == "" && offset != 0 && stringTable.TryGetValue(offset, out strFromTable)) { strValue = strFromTable; LocalePosition = j; } } // Flag de localisation, utile du côté client ? LocaleFlag = mReader.ReadUInt32(); field.SetValue(t, (LocalizedString)strValue); } else if (field.FieldType.IsArray) { int len; Array array; switch (Type.GetTypeCode(field.FieldType.GetElementType())) { case TypeCode.Int32: len = ((int[])field.GetValue(t)).Length; array = new int[len]; for (var q = 0; q < len; ++q) { array.SetValue(mReader.ReadInt32(), q); } field.SetValue(t, array); break; case TypeCode.UInt32: len = ((uint[])field.GetValue(t)).Length; array = new uint[len]; for (var q = 0; q < len; ++q) { array.SetValue(mReader.ReadUInt32(), q); } field.SetValue(t, array); break; case TypeCode.Single: len = ((float[])field.GetValue(t)).Length; array = new float[len]; for (var q = 0; q < len; ++q) { array.SetValue(mReader.ReadSingle(), q); } field.SetValue(t, array); break; default: throw new NotImplementedException(); } } } catch (System.Exception ex) { MessageBox.Show(ex.ToString()); } break; } case TypeCode.Single: { float fvalue = mReader.ReadSingle(); field.SetValue(t, fvalue); break; } } } long posEnd = mReader.BaseStream.Position; var firstVal = fields[0].GetValue(t); var classAttribs = typeof(T).GetCustomAttributes(typeof(NoPrimaryAttribute), false); uint id; if (classAttribs.Length == 0) { id = (uint)Convert.ChangeType(firstVal, typeof(uint)); } else { id = (uint)mRecords.Count(); } if (mConverter == null) { mRecords.Add(id, (T)t); } else { mRecords.Add(id, mConverter.Convert(t)); } } IsLoaded = true; mReader.Close(); // On peut sauvegarder par dessus notre mReader :D ! return(true); }
internal void WriteDBC(DBCFile <T> file, string path, IComparer <T> comparison) { var dirName = Path.GetDirectoryName(path); if (!string.IsNullOrEmpty(dirName)) { Directory.CreateDirectory(dirName); } try { FileStream strm = File.OpenWrite(path); BinaryWriter bw = new BinaryWriter(strm); byte[] bytes = Encoding.UTF8.GetBytes("WDBC"); bw.Write(bytes); bw.Write(file.Records.Count); Type type = typeof(T); var fields = type.GetFields(); int fieldCount = DBCHelper.FieldCount(fields, type); var classAttribs = typeof(T).GetCustomAttributes(typeof(NoPrimaryAttribute), false); bw.Write(fieldCount); //The charBaseInfo.dbc is weird, and don't have *4. string charBaseInfoPath = Application.ExecutablePath + "\\DBC\\CharBaseInfo.dbc"; if (path == charBaseInfoPath) { bw.Write(fieldCount); } else { bw.Write(fieldCount * 4); } bw.Write(0); // Ajout d'une string vide afin d'obtenir un format blizzlike AddStringToTable(""); List <T> valueCollection = file.Records.ToList(); if (comparison != null) { valueCollection.Sort(comparison); } // Ecriture de chaque champ de chaque enregistrement foreach (var rec in valueCollection) { foreach (var field in fields) { switch (Type.GetTypeCode(field.FieldType)) { case TypeCode.Int32: { int value = (int)field.GetValue(rec); bw.Write(value); break; } case TypeCode.UInt32: { uint uvalue = (uint)field.GetValue(rec); bw.Write(uvalue); break; } case TypeCode.String: { string str = field.GetValue(rec) as string; bw.Write(AddStringToTable(str)); break; } case TypeCode.Single: { float fvalue = (float)field.GetValue(rec); bw.Write(fvalue); break; } //Added typecode byte for the charbaseinfo, don't work properly case TypeCode.Byte: byte bvalue = (byte)field.GetValue(rec); bw.Write(bvalue); break; case TypeCode.Object: { if (field.FieldType == typeof(LocalizedString)) { int pos = AddStringToTable((LocalizedString)field.GetValue(rec)); for (uint j = 0; j < file.LocalePosition; ++j) { bw.Write((int)0); } bw.Write(pos); for (uint j = file.LocalePosition + 1; j < 16; ++j) { bw.Write((int)0); } // 17ème champ de localisation bw.Write((uint)file.LocaleFlag); } else { int len; Array array; switch (Type.GetTypeCode(field.FieldType.GetElementType())) { case TypeCode.Int32: array = field.GetValue(rec) as Array; len = array.Length; for (var q = 0; q < len; ++q) { bw.Write((int)array.GetValue(q)); } break; case TypeCode.UInt32: array = field.GetValue(rec) as Array; len = array.Length; for (var q = 0; q < len; ++q) { bw.Write((uint)array.GetValue(q)); } break; case TypeCode.Single: array = field.GetValue(rec) as Array; len = array.Length; for (var q = 0; q < len; ++q) { bw.Write((float)array.GetValue(q)); } break; default: throw new NotImplementedException(); } } } break; } } } foreach (var str in _stringTable.Values) { bytes = Encoding.UTF8.GetBytes(str); bw.Write(bytes); bw.Write((byte)0); } bw.BaseStream.Position = 16; if (_stringTable.Count > 0) { bw.Write(_stringTable.Last().Key + Encoding.UTF8.GetByteCount(_stringTable.Last().Value) + 1); } strm.Close(); } catch (IOException ex) { MessageBox.Show(ex.Message); } }