Example #1
0
        public void Save(string file)
        {
            Console.WriteLine(file);
            using (var bw = new BinaryWriter(File.Create(file)))
            {
                // skip header until later ------------------------------------------------------------------------------------

                bw.Pad(Header.HeaderLength);

                if (EventGroupsA.Count != EventGroupsB.Count)
                {
                    throw new Exception($"Event groups A and B count don't match ({EventGroupsA.Count}, {EventGroupsB.Count})");
                }
                int numGroups = EventGroupsA.Count;

                // write the list containing the number of items in each subgroup ----------------------------------------------

                for (int i = 0; i < numGroups; i++)
                {
                    var groupA = EventGroupsA[i];
                    var groupB = EventGroupsB[i];
                    if (groupA.Count != groupB.Count)
                    {
                        throw new Exception($"Event group {i} does not contain the same number of events in A and B");
                    }
                    bw.Write(groupA.Count);
                }

                // skip offset table until later ------------------------------------------------------------------------------

                int numOffsets = EventGroupsA.Sum(i => i.Count);

                // the +1 is because there's an 'end' one too
                // *4 for each byte in an offset entry
                // *2 for the two tables A and B
                int dataStart = OffsetTableStart + (numOffsets + 1) * 4 * 2;
                bw.BaseStream.Seek(dataStart, SeekOrigin.Begin);

                // write data, keep track of offsets ----------------------------------------------------------------------------

                List <List <int> > offsetsA = new List <List <int> >();
                long startOffsetA           = bw.BaseStream.Position;
                foreach (var group in EventGroupsA)
                {
                    List <int> subgroupOffsets = new List <int>();
                    offsetsA.Add(subgroupOffsets);

                    foreach (var(b, e) in group)
                    {
                        subgroupOffsets.Add((int)(bw.BaseStream.Position - startOffsetA));
                        bw.Write(b);
                        e.WriteTo(bw);
                    }
                }

                List <List <int> > offsetsB = new List <List <int> >();
                long startOffsetB           = bw.BaseStream.Position;
                int  tableBDataOffset       = (int)(startOffsetB - startOffsetA);
                foreach (var group in EventGroupsB)
                {
                    List <int> subgroupOffsets = new List <int>();
                    offsetsB.Add(subgroupOffsets);

                    foreach (var e in group)
                    {
                        subgroupOffsets.Add((int)(bw.BaseStream.Position - startOffsetB));
                        e.WriteTo(bw);
                    }
                }

                int dataEndB = (int)(bw.BaseStream.Position - startOffsetB);

                // pad the file to be divisible by 0x10
                while (bw.BaseStream.Length % 8 != 0)
                {
                    bw.Pad(1);
                }

                // write offsets ----------------------------------------------------------------------------------------------

                bw.BaseStream.Position = OffsetTableStart;
                foreach (var offsets in offsetsA)
                {
                    foreach (var o in offsets)
                    {
                        bw.Write(o);
                    }
                }
                bw.Write(tableBDataOffset);
                foreach (var offsets in offsetsB)
                {
                    foreach (var o in offsets)
                    {
                        bw.Write(o);
                    }
                }
                bw.Write(dataEndB);

                // write the header ----------------------------------------------------------------------------------------------
                var header = new Header()
                {
                    FortyEight       = 0x48,
                    FileId           = FileId,
                    Unknown          = HeaderUnknown,
                    NumGroups        = numGroups,
                    TableBDataOffset = tableBDataOffset,
                    FileLength       = (int)bw.BaseStream.Length,
                    NumOffsets       = numOffsets
                };
                bw.BaseStream.Position = 0;
                header.WriteTo(bw);
            }
        }
Example #2
0
        public EVE(string file)
        {
            Console.WriteLine(file);
            using (var br = new BinaryReader(File.OpenRead(file)))
            {
                // Header ------------------------------------------------------------------------------------

                var header = new Header(br);
                FileId        = header.FileId;
                HeaderUnknown = header.Unknown;

                //Console.WriteLine("GroupItemCounts:");
                int[] groupItemCounts = new int[header.NumGroups];
                for (int i = 0; i < header.NumGroups; i++)
                {
                    groupItemCounts[i] = br.ReadInt32();
                    //Console.WriteLine($"  0x{groupItemCounts[i]:X}");
                }

                // Offset Tables -------------------------------------------------------------------------------

                //Console.WriteLine("OffsetTableA:");
                br.BaseStream.Position = OffsetTableStart;
                int[][] groupsA = new int[header.NumGroups][];
                for (int groupId = 0; groupId < header.NumGroups; groupId++)
                {
                    //Console.WriteLine($"  Group {groupId} (numItems:{groupItemCounts[groupId]}):");
                    groupsA[groupId] = new int[groupItemCounts[groupId]];
                    for (int idWithinGroup = 0; idWithinGroup < groupItemCounts[groupId]; idWithinGroup++)
                    {
                        groupsA[groupId][idWithinGroup] = br.ReadInt32();
                        //Console.WriteLine($"    0x{groupsA[groupId][idWithinGroup]:X} (id: {idWithinGroup})");
                    }
                }

                Debug.Assert(groupsA.Sum(i => i.Length) == header.NumOffsets);

                var shift = br.ReadUInt32();
                if (shift != header.TableBDataOffset)
                {
                    throw new InvalidDataException("Listed offset doesnt match earlier value");
                }


                //Console.WriteLine("OffsetTableB:");
                int[][] groupsB = new int[header.NumGroups][];
                for (int groupId = 0; groupId < header.NumGroups; groupId++)
                {
                    //Console.WriteLine($"  Group {groupId}:");
                    groupsB[groupId] = new int[groupItemCounts[groupId]];
                    for (int idWithinGroup = 0; idWithinGroup < groupItemCounts[groupId]; idWithinGroup++)
                    {
                        groupsB[groupId][idWithinGroup] = br.ReadInt32();
                        //Console.WriteLine($"    0x{groupsB[groupId][idWithinGroup]:X} (id: {idWithinGroup})");
                    }
                }

                Debug.Assert(groupsB.Sum(i => i.Length) == header.NumOffsets);

                var end = br.ReadInt32();
                //Console.WriteLine($"END OF OFFSETS VALUE = 0x{end:X}");

                // Data ---------------------------------------------------------------------------------------

                var startOffsetA = br.BaseStream.Position;
                for (int a = 0; a < groupsA.Length; a++)
                {
                    int[] group    = groupsA[a];
                    var   eveGroup = new List <(byte[], Event)>();
                    EventGroupsA.Add(eveGroup);
                    for (int i = 0; i < group.Length; i++)
                    {
                        var eventOffset = group[i];
                        br.BaseStream.Position = startOffsetA + eventOffset;
                        byte[] unknown = br.ReadBytes(0x40);
                        eveGroup.Add((unknown, new Event(br)));
                    }
                }

                var startOffsetB = br.BaseStream.Position;
                //Console.WriteLine("START OFFSET B: 0x{0:X}", startOffsetB);
                var expectedStartOffsetB = startOffsetA + header.TableBDataOffset;
                Debug.Assert(startOffsetB == expectedStartOffsetB, $"Start offset of B is unexpected: 0x{startOffsetB:X} (expected: 0x{expectedStartOffsetB:X})");

                for (int b = 0; b < groupsB.Length; b++)
                {
                    int[] group    = groupsB[b];
                    var   eveGroup = new List <Event>();
                    EventGroupsB.Add(eveGroup);
                    for (int i = 0; i < group.Length; i++)
                    {
                        var eventOffset = group[i];
                        br.BaseStream.Position = startOffsetB + eventOffset;
                        eveGroup.Add(new Event(br));
                    }
                }

                // ----------------------------------------------------------------------------
            }
        }