/// <summary> /// Updates references to modified strings/data in the data section for the specified entry. /// </summary> /// <param name="entry">Entry being updated</param> /// <param name="updatedOffsets">Mapping of all changed offsets. Key = original offset, Value = new offset.</param> private void UpdateDataOffsets(BaseDat entry, Dictionary <long, long> updatedOffsets) { var properties = entry.GetType().GetProperties(); foreach (var prop in properties) { object[] customAttributes = prop.GetCustomAttributes(false); if (customAttributes.Length == 0) { continue; } if (customAttributes.Any(n => n is UInt64Index) || customAttributes.Any(n => n is UInt32Index) || customAttributes.Any(n => n is Int32Index)) { continue; } int offset = (int)prop.GetValue(entry, null); if (updatedOffsets.ContainsKey(offset)) { //Console.WriteLine("Updating offset {0} for {1} (now {2})", offset, prop.Name, updatedOffsets[offset]); prop.SetValue(entry, (int)updatedOffsets[offset], null); } } }
/// <summary> /// Resolve external references in the record /// </summary> public virtual void ResolveReferences() { foreach (var propInfo in this.GetType().GetProperties()) { if (propInfo.GetCustomAttributes(false).Any(n => n is ExternalReference)) { var foreignKey = this.GetType().GetProperties().Where(x => x.Name == propInfo.Name.Replace("Ref", "Key")).FirstOrDefault(); Int64 fkValue; if (foreignKey.GetValue(this, null) is Int64) { fkValue = (Int64)(foreignKey.GetValue(this, null)); } else { fkValue = (Int32)(foreignKey.GetValue(this, null)); } BaseDat newVal = ReferenceManager.Instance.AllDats[propInfo.PropertyType.Name + ".dat"].Where(x => x.Key == fkValue).FirstOrDefault(); propInfo.SetValue(this, newVal, null); } if (propInfo.GetCustomAttributes(false).Any(n => n is ExternalReferenceList)) { var foreignKey = this.GetType().GetProperties().Where(x => x.Name == propInfo.Name.Replace("ListRef", "ListData")).FirstOrDefault(); object untypedFkValues = foreignKey.GetValue(this, null); if (untypedFkValues is UInt64List) { UInt64List fkValues = (untypedFkValues as UInt64List); List <BaseDat> newVals = new List <BaseDat>(); Type genericDatType = propInfo.PropertyType.GetGenericArguments()[0]; var newExternalDatList = propInfo.PropertyType.GetConstructor(new Type[0]).Invoke(new Object[0]); foreach (UInt64 fkValue in fkValues.Data) { BaseDat newVal = ReferenceManager.Instance.AllDats[genericDatType.Name + ".dat"].Where(x => x.Key == fkValue).FirstOrDefault(); newVals.Add(newVal); } newExternalDatList.GetType().GetProperty("Data").SetValue(newExternalDatList, newVals, null); propInfo.SetValue(this, newExternalDatList, null); } else if (untypedFkValues is UInt32List) { UInt32List fkValues = (untypedFkValues as UInt32List); List <BaseDat> newVals = new List <BaseDat>(); Type genericDatType = propInfo.PropertyType.GetGenericArguments()[0]; var newExternalDatList = propInfo.PropertyType.GetConstructor(new Type[0]).Invoke(new Object[0]); foreach (UInt32 fkValue in fkValues.Data) { BaseDat newVal = ReferenceManager.Instance.AllDats[genericDatType.Name + ".dat"].Where(x => x.Key == fkValue).FirstOrDefault(); newVals.Add(newVal); } newExternalDatList.GetType().GetProperty("Data").SetValue(newExternalDatList, newVals, null); propInfo.SetValue(this, newExternalDatList, null); } else { } } } }
/// <summary> /// Reads the .dat frile from the specified stream /// </summary> /// <param name="inStream">Stream containing contents of .dat file</param> private void Read(BinaryReader inStream) { numberOfEntries = inStream.ReadInt32(); if (inStream.ReadUInt64() == 0xBBbbBBbbBBbbBBbb) { Entries = new List <BaseDat>(); return; } inStream.BaseStream.Seek(-8, SeekOrigin.Current); Entries = new List <BaseDat>(numberOfEntries); if (DatType == null) { throw new Exception("Missing dat parser for type " + datName); } for (uint i = 0; i < numberOfEntries; i++) { BaseDat bd = DatFactory.Create(datName, inStream); bd.Key = i; Entries.Add(bd); } if (inStream.ReadUInt64() != 0xBBbbBBbbBBbbBBbb) { throw new ApplicationException("Missing magic number after records"); } DataTableBegin = inStream.BaseStream.Position - 8; inStream.BaseStream.Seek(-8, SeekOrigin.Current); originalDataTable = inStream.ReadBytes((int)(inStream.BaseStream.Length - inStream.BaseStream.Position)); for (int i = 0; i < numberOfEntries; i++) { if (i == numberOfEntries - 1) { } Entries[i].ReadResources(inStream, DataTableBegin); } // Read all referenced string and data entries from the data following the entries (starting at magic number) foreach (var item in Entries) { AddDataToTable(item, inStream); } }
/// <summary> /// Finds all known references to strings and other data in the data section and adds them to the DataEntries. /// Accomplished by reading the [StringIndex] and [DataIndex] attributes of our dat structure. /// </summary> /// <param name="entry">Dat parser created from parsing a single entry of the .dat file.</param> /// <param name="inStream">Stream containing contents of .dat file. Stream position not preserved.</param> private void AddDataToTable(BaseDat entry, BinaryReader inStream) { var properties = entry.GetType().GetProperties(); foreach (var prop in properties) { object[] customAttributes = prop.GetCustomAttributes(false); if (customAttributes.Length == 0) { continue; } if (customAttributes.Any(n => n is ResourceOnly)) { continue; } if (customAttributes.Any(n => n is Hidden)) { continue; } if (customAttributes.Any(n => n is ExternalReference)) { continue; } if (customAttributes.Any(n => n is ExternalReferenceList)) { continue; } int offset = (int)prop.GetValue(entry, null); if (DataEntries.ContainsKey(offset)) { continue; } if (customAttributes.Any(n => n is StringIndex)) { DataEntries[offset] = new UnicodeString(inStream, offset, DataTableBegin, (customAttributes.Any(n => n is UserStringIndex))); // Console.WriteLine("{0} -> {1}", offset, DataEntries[offset]); } else if (customAttributes.Any(n => n is DataIndex)) { DataEntries[offset] = new UnkownData(inStream, offset, DataTableBegin); } } }
/// <summary> /// Finds all known references to strings and other data in the data section and adds them to the DataEntries. /// Accomplished by reading the [StringIndex] and [DataIndex] attributes of our dat structure. /// </summary> /// <param name="entry">Dat parser created from parsing a single entry of the .dat file.</param> /// <param name="inStream">Stream containing contents of .dat file. Stream position not preserved.</param> private void AddDataToTable(BaseDat entry, BinaryReader inStream) { var properties = entry.GetType().GetProperties(); foreach (var prop in properties) { object[] customAttributes = prop.GetCustomAttributes(false); if (customAttributes.Length == 0) { continue; } int offset = (int)prop.GetValue(entry, null); if (DataEntries.ContainsKey(offset) && !DataEntries[offset].ToString().Equals("")) { continue; } if (customAttributes.Any(n => n is StringIndex)) { DataEntries[offset] = new UnicodeString(inStream, offset, DataTableBegin, (customAttributes.Any(n => n is UserStringIndex))); // Console.WriteLine("{0} -> {1}", offset, DataEntries[offset]); } else if (customAttributes.Any(n => n is DataIndex)) { DataEntries[offset] = new UnkownData(inStream, offset, DataTableBegin); } else if (customAttributes.Any(n => n is UInt64Index)) { var propLength = entry.GetType().GetProperties().Where(x => x.Name == prop.Name + "Length").FirstOrDefault(); DataEntries[offset] = new UInt64List(inStream, offset, DataTableBegin, (int)(propLength.GetValue(entry, null))); } else if (customAttributes.Any(n => n is UInt32Index)) { var propLength = entry.GetType().GetProperties().Where(x => x.Name == prop.Name + "Length").FirstOrDefault(); DataEntries[offset] = new UInt32List(inStream, offset, DataTableBegin, (int)(propLength.GetValue(entry, null))); } else if (customAttributes.Any(n => n is Int32Index)) { var propLength = entry.GetType().GetProperties().Where(x => x.Name == prop.Name + "Length").FirstOrDefault(); DataEntries[offset] = new Int32List(inStream, offset, DataTableBegin, (int)(propLength.GetValue(entry, null))); } } }
/// <summary> /// Updates references to modified strings/data in the data section for the specified entry. /// </summary> /// <param name="entry">Entry being updated</param> /// <param name="updatedOffsets">Mapping of all changed offsets. Key = original offset, Value = new offset.</param> private void UpdateDataOffsets(BaseDat entry, Dictionary<long, long> updatedOffsets) { var properties = entry.GetType().GetProperties(); foreach (var prop in properties) { object[] customAttributes = prop.GetCustomAttributes(false); if (customAttributes.Length == 0) continue; if (customAttributes.Any(n => n is UInt64Index) || customAttributes.Any(n => n is UInt32Index) || customAttributes.Any(n => n is Int32Index)) continue; int offset = (int)prop.GetValue(entry, null); if (updatedOffsets.ContainsKey(offset)) { //Console.WriteLine("Updating offset {0} for {1} (now {2})", offset, prop.Name, updatedOffsets[offset]); prop.SetValue(entry, (int)updatedOffsets[offset], null); } } }
/// <summary> /// Finds all known references to strings and other data in the data section and adds them to the DataEntries. /// Accomplished by reading the [StringIndex] and [DataIndex] attributes of our dat structure. /// </summary> /// <param name="entry">Dat parser created from parsing a single entry of the .dat file.</param> /// <param name="inStream">Stream containing contents of .dat file. Stream position not preserved.</param> private void AddDataToTable(BaseDat entry, BinaryReader inStream) { var properties = entry.GetType().GetProperties(); foreach (var prop in properties) { object[] customAttributes = prop.GetCustomAttributes(false); if (customAttributes.Length == 0) continue; int offset = (int)prop.GetValue(entry, null); if (DataEntries.ContainsKey(offset) && !DataEntries[offset].ToString().Equals("")) { continue; } if (customAttributes.Any(n => n is StringIndex)) { DataEntries[offset] = new UnicodeString(inStream, offset, DataTableBegin, (customAttributes.Any(n => n is UserStringIndex))); // Console.WriteLine("{0} -> {1}", offset, DataEntries[offset]); } else if (customAttributes.Any(n => n is DataIndex)) { DataEntries[offset] = new UnkownData(inStream, offset, DataTableBegin); } else if (customAttributes.Any(n => n is UInt64Index)) { var propLength = entry.GetType().GetProperties().Where(x => x.Name == prop.Name+"Length").FirstOrDefault(); DataEntries[offset] = new UInt64List(inStream, offset, DataTableBegin, (int)(propLength.GetValue(entry, null))); } else if (customAttributes.Any(n => n is UInt32Index)) { var propLength = entry.GetType().GetProperties().Where(x => x.Name == prop.Name + "Length").FirstOrDefault(); DataEntries[offset] = new UInt32List(inStream, offset, DataTableBegin, (int)(propLength.GetValue(entry, null))); } else if (customAttributes.Any(n => n is Int32Index)) { var propLength = entry.GetType().GetProperties().Where(x => x.Name == prop.Name + "Length").FirstOrDefault(); DataEntries[offset] = new Int32List(inStream, offset, DataTableBegin, (int)(propLength.GetValue(entry, null))); } } }
public virtual int CompareTo(object obj) { BaseDat other = (BaseDat)obj; return(this.ToString().CompareTo(other.ToString())); }