public NormalCategory(IList <PropertyData> data, CategoryReference reference, AssetReader asset, byte[] extras) : base(reference, asset, extras) { Data = data; }
public void Read(BinaryReader reader, int[] manualSkips = null, int[] forceReads = null) { // Header byte[] header = reader.ReadBytes(185); ReadHeader(new BinaryReader(new MemoryStream(header))); // Section 1 reader.BaseStream.Position += 8; ClearHeaderIndexList(); for (int i = 0; i < sectionOneStringCount; i++) { var str = reader.ReadUStringWithGUID(out uint guid); AddHeaderReference(str); } // Section 2 links = new List <Link>(); // base, class, link, connection if (sectionTwoOffset > 0) { reader.BaseStream.Seek(sectionTwoOffset, SeekOrigin.Begin); for (int i = 0; i < sectionTwoLinkCount; i++) { ulong bbase = reader.ReadUInt64(); ulong bclass = reader.ReadUInt64(); int link = reader.ReadInt32(); ulong property = reader.ReadUInt64(); links.Add(new Link(bbase, bclass, link, property, Utils.GetLinkIndex(i))); } } // Section 3 categories = new List <Category>(); // connection, connect, category, link, typeIndex, type, length, start, garbage1, garbage2, garbage3 if (sectionThreeOffset > 0) { reader.BaseStream.Seek(sectionThreeOffset, SeekOrigin.Begin); for (int i = 0; i < dataCategoryCount; i++) { int connection = reader.ReadInt32(); int connect = reader.ReadInt32(); int category = reader.ReadInt32(); int link = reader.ReadInt32(); int typeIndex = reader.ReadInt32(); int garbage1 = reader.ReadInt32(); ushort type = reader.ReadUInt16(); ushort garbageNew = reader.ReadUInt16(); int lengthV = reader.ReadInt32(); // !!! int garbage2 = reader.ReadInt32(); int startV = reader.ReadInt32(); // !!! categories.Add(new Category(new CategoryReference(connection, connect, category, link, typeIndex, type, lengthV, startV, garbage1, garbage2, garbageNew, reader.ReadBytes(104 - (10 * 4))), this, new byte[0])); } } // Section 4 categoryIntReference = new List <int[]>(); if (sectionFourOffset > 0) { reader.BaseStream.Seek(sectionFourOffset, SeekOrigin.Begin); for (int i = 0; i < dataCategoryCount; i++) { int size = reader.ReadInt32(); int[] data = new int[size]; for (int j = 0; j < size; j++) { data[j] = reader.ReadInt32(); } categoryIntReference.Add(data); } } // Section 5 categoryStringReference = new List <string>(); if (sectionFiveOffset > 0) { reader.BaseStream.Seek(sectionFiveOffset, SeekOrigin.Begin); for (int i = 0; i < sectionFiveStringCount; i++) { categoryStringReference.Add(reader.ReadUString()); } } // Section 6 if (sectionSixOffset > 0 && categories.Count > 0) { if (UseSeparateBulkDataFiles) { reader.BaseStream.Seek(uexpDataOffset, SeekOrigin.Begin); UExpData = new List <int>(); int firstStart = categories[0].ReferenceData.startV; while (reader.BaseStream.Position < firstStart) { UExpData.Add(reader.ReadInt32()); } } for (int i = 0; i < categories.Count; i++) { CategoryReference refData = categories[i].ReferenceData; reader.BaseStream.Seek(refData.startV, SeekOrigin.Begin); if (manualSkips != null && manualSkips.Contains(i)) { if (forceReads == null || !forceReads.Contains(i)) { categories[i] = new RawCategory(categories[i]); ((RawCategory)categories[i]).Data = reader.ReadBytes(refData.lengthV); continue; } } //Debug.WriteLine(refData.type + " " + GetHeaderReference(GetLinkReference(refData.connection))); try { switch (GetHeaderReference(GetLinkReference(refData.connection))) { case "BlueprintGeneratedClass": categories[i] = new BlueprintGeneratedClassCategory(categories[i]); categories[i].Read(reader); break; case "StringTable": categories[i] = new StringTableCategory(categories[i]); categories[i].Read(reader); break; default: categories[i] = new NormalCategory(categories[i]); categories[i].Read(reader); break; } int nextStarting = (int)reader.BaseStream.Length - 4; if ((categories.Count - 1) > i) { nextStarting = categories[i + 1].ReferenceData.startV; } int extrasLen = nextStarting - (int)reader.BaseStream.Position; if (extrasLen < 0) { throw new FormatException("Invalid padding at end of category " + (i + 1) + ": " + extrasLen + " bytes"); } else { categories[i].Extras = reader.ReadBytes(extrasLen); } } catch (Exception ex) { #if DEBUG Debug.WriteLine("\nFailed to parse category " + (i + 1) + ": " + ex.ToString()); #endif reader.BaseStream.Seek(refData.startV, SeekOrigin.Begin); categories[i] = new RawCategory(categories[i]); ((RawCategory)categories[i]).Data = reader.ReadBytes(refData.lengthV); } } } }
public DataTableCategory(DataTable data, CategoryReference reference, AssetReader asset, byte[] extras) : base(reference, asset, extras) { Data2 = data; }
public NormalCategory(CategoryReference reference, AssetReader asset, byte[] extras) : base(reference, asset, extras) { }
public Category() { ReferenceData = new CategoryReference(); }
public BlueprintGeneratedClassCategory(CategoryReference reference, AssetReader asset, byte[] extras) : base(reference, asset, extras) { }
public Category(CategoryReference reference, AssetReader asset, byte[] extras) { ReferenceData = reference; Asset = asset; Extras = extras; }
public RawCategory(byte[] data, CategoryReference reference, AssetReader asset, byte[] extras) : base(reference, asset, extras) { Data = data; }
public MemoryStream WriteData(BinaryReader reader) { var stre = new MemoryStream(); BinaryWriter writer = new BinaryWriter(stre); // Header writer.Seek(0, SeekOrigin.Begin); writer.Write(MakeHeader(reader)); // Section 1 writer.Seek(193, SeekOrigin.Begin); data.sectionOneStringCount = data.headerIndexList.Count; for (int i = 0; i < data.headerIndexList.Count; i++) { writer.WriteUString(data.headerIndexList[i]); writer.Write(CRCGenerator.GenerateHash(data.headerIndexList[i])); } // Section 2 if (data.links.Count > 0) { data.sectionTwoOffset = (int)writer.BaseStream.Position; data.sectionTwoLinkCount = data.links.Count; int newIndex = 0; for (int i = 0; i < data.links.Count; i++) { writer.Write(data.links[i].Base); writer.Write(data.links[i].Class); writer.Write(data.links[i].Linkage); writer.Write(data.links[i].Property); data.links[i].Index = --newIndex; } } else { data.sectionTwoOffset = 0; } // Section 3 if (data.categories.Count > 0) { data.sectionThreeOffset = (int)writer.BaseStream.Position; data.dataCategoryCount = data.categories.Count; for (int i = 0; i < data.categories.Count; i++) { CategoryReference us = data.categories[i].ReferenceData; writer.Write(us.connection); writer.Write(us.connect); writer.Write(us.category); writer.Write(us.link); writer.Write(us.typeIndex); writer.Write(us.garbage1); writer.Write(us.type); writer.Write(us.garbageNew); writer.Write(us.lengthV); writer.Write(us.garbage2); writer.Write(us.startV); writer.Write(us.garbage3); } } else { data.sectionThreeOffset = 0; } // Section 4 if (data.categoryIntReference.Count > 0) { data.sectionFourOffset = (int)writer.BaseStream.Position; for (int i = 0; i < data.categories.Count; i++) { if (i >= data.categoryIntReference.Count) { data.categoryIntReference.Add(new int[0]); } int[] currentData = data.categoryIntReference[i]; writer.Write(currentData.Length); for (int j = 0; j < currentData.Length; j++) { writer.Write(currentData[j]); } } } else { data.sectionFourOffset = 0; } // Section 5 if (data.categoryStringReference.Count > 0) { data.sectionFiveOffset = (int)writer.BaseStream.Position; data.sectionFiveStringCount = data.categoryStringReference.Count; for (int i = 0; i < data.categoryStringReference.Count; i++) { writer.WriteUString(data.categoryStringReference[i]); } } else { data.sectionFiveOffset = 0; } // Uexp Data data.uexpDataOffset = (int)stre.Position; if (data.UseSeparateBulkDataFiles) { foreach (int part in data.UExpData) { writer.Write(part); } } else { writer.Write((int)0); } // Section 6 int oldOffset = data.sectionSixOffset; data.sectionSixOffset = (int)writer.BaseStream.Position; int[] categoryStarts = new int[data.categories.Count]; if (WillWriteSectionSix) { if (data.categories.Count > 0) { for (int i = 0; i < data.categories.Count; i++) { categoryStarts[i] = (int)writer.BaseStream.Position; Category us = data.categories[i]; us.Write(writer); writer.Write(us.Extras); } } writer.Write(new byte[] { 0xC1, 0x83, 0x2A, 0x9E }); } else // Old behavior { reader.BaseStream.Seek(oldOffset, SeekOrigin.Begin); writer.Write(reader.ReadBytes((int)reader.BaseStream.Length - oldOffset)); int additionalOffset = data.sectionSixOffset - oldOffset; for (int i = 0; i < data.categories.Count; i++) { CategoryReference us = data.categories[i].ReferenceData; categoryStarts[i] = us.startV + additionalOffset; } } data.fileSize = (int)stre.Length; // Rewrite Section 3 if (data.categories.Count > 0) { writer.Seek(data.sectionThreeOffset, SeekOrigin.Begin); for (int i = 0; i < data.categories.Count; i++) { CategoryReference us = data.categories[i].ReferenceData; int nextLoc = data.fileSize - 4; if ((data.categories.Count - 1) > i) { nextLoc = categoryStarts[i + 1]; } us.startV = categoryStarts[i]; us.lengthV = nextLoc - categoryStarts[i]; writer.Write(us.connection); writer.Write(us.connect); writer.Write(us.category); writer.Write(us.link); writer.Write(us.typeIndex); writer.Write(us.garbage1); writer.Write(us.type); writer.Write(us.garbageNew); writer.Write(us.lengthV); // !!! writer.Write(us.garbage2); writer.Write(us.startV); // !!! writer.Write(us.garbage3); } } // Rewrite Header writer.Seek(0, SeekOrigin.Begin); writer.Write(MakeHeader(reader)); writer.Seek(0, SeekOrigin.Begin); return(stre); }