Beispiel #1
0
 public NormalCategory(IList <PropertyData> data, CategoryReference reference, AssetReader asset, byte[] extras) : base(reference, asset, extras)
 {
     Data = data;
 }
Beispiel #2
0
        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);
                    }
                }
            }
        }
Beispiel #3
0
 public DataTableCategory(DataTable data, CategoryReference reference, AssetReader asset, byte[] extras) : base(reference, asset, extras)
 {
     Data2 = data;
 }
Beispiel #4
0
 public NormalCategory(CategoryReference reference, AssetReader asset, byte[] extras) : base(reference, asset, extras)
 {
 }
Beispiel #5
0
 public Category()
 {
     ReferenceData = new CategoryReference();
 }
Beispiel #6
0
 public BlueprintGeneratedClassCategory(CategoryReference reference, AssetReader asset, byte[] extras) : base(reference, asset, extras)
 {
 }
Beispiel #7
0
 public Category(CategoryReference reference, AssetReader asset, byte[] extras)
 {
     ReferenceData = reference;
     Asset         = asset;
     Extras        = extras;
 }
Beispiel #8
0
 public RawCategory(byte[] data, CategoryReference reference, AssetReader asset, byte[] extras) : base(reference, asset, extras)
 {
     Data = data;
 }
Beispiel #9
0
        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);
        }