Beispiel #1
0
 public void SetMove(RangeInt64 section, long loc)
 {
     if (section.Width == 0)
     {
         return;
     }
     if (loc == section.Min)
     {
         return;
     }
     if (loc <= section.Max)
     {
         throw new NotImplementedException("Cannot move a section earlier in the stream, within the move itself, or into the same spot");
     }
     if (_moveRanges.Collides(section))
     {
         throw new ArgumentException("Can not have colliding moves.");
     }
     _moveRanges.Add(section);
     _moves[section] = loc;
     _sameLocMoves.GetOrAdd(loc).Add(section);
     if (_moveRanges.IsEncapsulated(loc))
     {
         throw new ArgumentException($"Cannot move to a section that is marked to be moved: {loc}");
     }
 }
        public void Move_Overlap_And_Another()
        {
            var  section     = new RangeInt64(BUFFER_SIZE - 2, BUFFER_SIZE + 2);
            long loc         = BUFFER_SIZE + 4;
            var  section2    = new RangeInt64(BUFFER_SIZE + 7, BUFFER_SIZE + 9);
            long loc2        = BUFFER_SIZE + 12;
            var  sourceBuf   = GetBuffer((int)(BUFFER_SIZE * 2));
            var  expectedBuf = DoMove(
                GetBuffer((int)(BUFFER_SIZE * 2)),
                section,
                loc);

            expectedBuf = DoMove(
                expectedBuf,
                section2,
                loc2);
            BinaryFileProcessor.Config config = new BinaryFileProcessor.Config();
            config.SetMove(section, loc);
            config.SetMove(section2, loc2);
            var outputBuf = GetBytes(
                config,
                sourceBuf);

            Assert.Equal(expectedBuf, outputBuf);
        }
        public byte[] DoMove(byte[] buf, RangeInt64 section, long loc)
        {
            byte[] move = new byte[section.Width];
            Array.Copy(buf, section.Min, move, 0, section.Width);
            List <byte> ret = new List <byte>(buf);

            ret.InsertRange((int)(loc), move);
            ret.RemoveRange((int)section.Min, checked ((int)section.Width));
            return(ret.ToArray());
        }
Beispiel #4
0
    private void ProcessLeveledItemDataFields(
        MajorRecordFrame majorFrame,
        long fileOffset)
    {
        if (!majorFrame.TryLocateSubrecordFrame(RecordTypes.DATA, out var dataFrame, out var dataIndex))
        {
            return;
        }

        int amount   = 0;
        var dataFlag = dataFrame.AsUInt8();

        if (dataFlag == 1)
        {
            var lvld = majorFrame.LocateSubrecord(RecordTypes.LVLD, out var index);
            index += lvld.HeaderLength + 1;
            this._instructions.SetAddition(
                loc: index + fileOffset,
                addition: new byte[]
            {
                (byte)'L',
                (byte)'V',
                (byte)'L',
                (byte)'F',
                0x1,
                0x0,
                0x2
            });
            amount += 7;
        }
        else
        {
            var    existingLen = dataFrame.ContentLength;
            byte[] lenData     = new byte[2];
            using (var writer = new MutagenWriter(new MemoryStream(lenData), this.GameRelease))
            {
                writer.Write((ushort)(existingLen - 7));
            }
            this._instructions.SetSubstitution(
                loc: fileOffset + Plugins.Internals.Constants.HeaderLength,
                sub: lenData);
        }

        // Remove DATA
        var dataRange = new RangeInt64(dataIndex + fileOffset, dataIndex + fileOffset + 7 - 1);

        this._instructions.SetRemove(dataRange);
        amount -= (int)dataRange.Width;

        ProcessLengths(
            majorFrame,
            amount,
            fileOffset);
    }
        public void Move_Overlap()
        {
            var  section     = new RangeInt64(BUFFER_SIZE - 3, BUFFER_SIZE + 3);
            long loc         = BUFFER_SIZE + 7;
            var  sourceBuf   = GetBuffer((int)(BUFFER_SIZE * 2));
            var  expectedBuf = DoMove(
                GetBuffer((int)(BUFFER_SIZE * 2)),
                section,
                loc);

            BinaryFileProcessor.Config config = new BinaryFileProcessor.Config();
            config.SetMove(section, loc);
            var outputBuf = GetBytes(
                config,
                sourceBuf);

            Assert.Equal(expectedBuf, outputBuf);
        }
        public void Move_Inside_FirstPass()
        {
            var  section     = new RangeInt64(5, 6);
            long loc         = 11;
            var  sourceBuf   = GetBuffer((int)(BUFFER_SIZE * 2));
            var  expectedBuf = DoMove(
                GetBuffer((int)(BUFFER_SIZE * 2)),
                section,
                loc);

            BinaryFileProcessor.Config config = new BinaryFileProcessor.Config();
            config.SetMove(section, loc);
            var outputBuf = GetBytes(
                config,
                sourceBuf);

            Assert.Equal(expectedBuf, outputBuf);
        }
Beispiel #7
0
        private void ProcessRegions(
            MajorRecordFrame majorFrame,
            long fileOffset)
        {
            var rdat = UtilityTranslation.FindFirstSubrecord(majorFrame.Content, majorFrame.Meta, RecordTypes.RDAT, navigateToContent: false);

            if (rdat == null)
            {
                return;
            }

            // Order RDATs by index
            SortedList <uint, RangeInt64> rdats = new SortedList <uint, RangeInt64>();
            List <uint> raw = new List <uint>();

            while (rdat != null)
            {
                var rdatHeader = majorFrame.Meta.SubrecordFrame(majorFrame.Content.Slice(rdat.Value));
                var index      = BinaryPrimitives.ReadUInt32LittleEndian(rdatHeader.Content);
                var nextRdat   = UtilityTranslation.FindFirstSubrecord(
                    majorFrame.Content,
                    majorFrame.Meta,
                    RecordTypes.RDAT,
                    navigateToContent: false,
                    offset: rdat.Value + rdatHeader.TotalLength);
                rdats[index] =
                    new RangeInt64(
                        fileOffset + majorFrame.HeaderLength + rdat.Value,
                        nextRdat == null ? fileOffset + majorFrame.TotalLength - 1 : nextRdat.Value - 1 + fileOffset + majorFrame.HeaderLength);
                raw.Add(index);
                rdat = nextRdat;
            }
            if (raw.SequenceEqual(rdats.Keys))
            {
                return;
            }
            foreach (var item in rdats.Reverse())
            {
                this._Instructions.SetMove(
                    loc: fileOffset + majorFrame.TotalLength,
                    section: item.Value);
            }
        }
Beispiel #8
0
        private void ProcessPlaced(
            MajorRecordFrame majorFrame,
            long fileOffset)
        {
            var sizeChange = 0;

            if (majorFrame.TryLocateSubrecordPinFrame(RecordTypes.DATA, out var dataRec))
            {
                ProcessZeroFloats(dataRec, fileOffset, 6);
            }

            if (majorFrame.TryLocateSubrecordPinFrame(RecordTypes.XTEL, out var xtelRec))
            {
                var offset = 4;
                ProcessZeroFloats(xtelRec, fileOffset, ref offset, 6);
            }

            if (majorFrame.TryLocateSubrecordPinFrame(RecordTypes.XPRM, out var xprmRec))
            {
                int offset = 0;
                ProcessZeroFloats(xprmRec, fileOffset, ref offset, 3);
                ProcessColorFloat(xprmRec, fileOffset, ref offset);
                ProcessZeroFloat(xprmRec, fileOffset, ref offset);
            }

            if (majorFrame.TryLocateSubrecordFrame(RecordTypes.XRMR, out var xrmrRec, out var xrmrIndex))
            {
                if (xrmrRec.AsInt32() == 0)
                {
                    _Instructions.SetRemove(
                        RangeInt64.FactoryFromLength(
                            fileOffset + xrmrIndex,
                            10));
                    sizeChange -= 10;
                }
            }

            ProcessLengths(
                majorFrame,
                sizeChange,
                fileOffset);
        }
        public void Move_Cross()
        {
            var  section     = new RangeInt64(2, 3);
            long loc         = 12;
            var  section2    = new RangeInt64(6, 8);
            long loc2        = 10;
            var  sourceBuf   = GetBuffer((int)(BUFFER_SIZE));
            var  expectedBuf = new byte[]
            {
                0,
                1,
                4,
                5,
                9,
                6,
                7,
                8,
                10,
                11,
                2,
                3,
                12,
                13,
                14,
                15
            };

            BinaryFileProcessor.Config config = new BinaryFileProcessor.Config();
            config.SetMove(section, loc);
            config.SetMove(section2, loc2);
            var outputBuf = GetBytes(
                config,
                sourceBuf);

            Assert.Equal(expectedBuf, outputBuf);
        }
Beispiel #10
0
 public void SetRemove(RangeInt64 section)
 {
     SetMove(
         section: section,
         loc: long.MaxValue);
 }
Beispiel #11
0
    private void ProcessWater(
        MajorRecordFrame majorFrame,
        long fileOffset)
    {
        var amount = 0;

        if (majorFrame.TryLocateSubrecord(RecordTypes.DATA, out var dataRec, out var dataLoc))
        {
            var len = dataRec.ContentLength;
            if (len == 0x02)
            {
                this._instructions.SetSubstitution(
                    loc: fileOffset + dataLoc + Plugins.Internals.Constants.HeaderLength,
                    sub: new byte[] { 0, 0 });
                this._instructions.SetRemove(
                    section: RangeInt64.FactoryFromLength(
                        loc: fileOffset + dataLoc + dataRec.HeaderLength,
                        length: 2));
                amount -= 2;
            }

            if (len == 0x56)
            {
                this._instructions.SetSubstitution(
                    loc: fileOffset + dataLoc + Plugins.Internals.Constants.HeaderLength,
                    sub: new byte[] { 0x54, 0 });
                this._instructions.SetRemove(
                    section: RangeInt64.FactoryFromLength(
                        loc: fileOffset + dataLoc + dataRec.HeaderLength + 0x54,
                        length: 2));
                amount -= 2;
            }

            if (len == 0x2A)
            {
                this._instructions.SetSubstitution(
                    loc: fileOffset + dataLoc + Plugins.Internals.Constants.HeaderLength,
                    sub: new byte[] { 0x28, 0 });
                this._instructions.SetRemove(
                    section: RangeInt64.FactoryFromLength(
                        loc: fileOffset + dataLoc + dataRec.HeaderLength + 0x28,
                        length: 2));
                amount -= 2;
            }

            if (len == 0x3E)
            {
                this._instructions.SetSubstitution(
                    loc: fileOffset + dataLoc + Plugins.Internals.Constants.HeaderLength,
                    sub: new byte[] { 0x3C, 0 });
                this._instructions.SetRemove(
                    section: RangeInt64.FactoryFromLength(
                        loc: fileOffset + dataLoc + dataRec.HeaderLength + 0x3C,
                        length: 2));
                amount -= 2;
            }

            var move = 0x39;
            if (len >= 3 + move)
            {
                this._instructions.SetSubstitution(
                    sub: new byte[] { 0, 0, 0 },
                    loc: fileOffset + dataLoc + dataRec.HeaderLength + move);
            }
        }

        ProcessLengths(
            majorFrame,
            amount,
            fileOffset);
    }
Beispiel #12
0
    private void ProcessRegions(
        IMutagenReadStream stream,
        MajorRecordFrame majorFrame,
        long fileOffset)
    {
        if (!majorFrame.TryLocateSubrecordFrame(RecordTypes.RDAT, out var rdatFrame, out var rdatIndex))
        {
            return;
        }
        int amount = 0;
        SortedList <uint, RangeInt64> rdats = new SortedList <uint, RangeInt64>();
        bool foundNext = true;

        while (foundNext)
        {
            foundNext = majorFrame.TryLocateSubrecordFrame(RecordTypes.RDAT, offset: rdatIndex + rdatFrame.TotalLength, out var nextRdatFrame, out var nextRdatIndex);
            var index = rdatFrame.Content.UInt32();
            rdats[index] =
                new RangeInt64(
                    rdatIndex + fileOffset,
                    foundNext ? nextRdatIndex - 1 + fileOffset : fileOffset + majorFrame.TotalLength - 1);
            rdatFrame = nextRdatFrame;
            rdatIndex = nextRdatIndex;
        }

        foreach (var item in rdats.Reverse())
        {
            if (item.Key == (int)RegionData.RegionDataType.Icon)
            {
                continue;
            }
            this._instructions.SetMove(
                loc: fileOffset + majorFrame.TotalLength,
                section: item.Value);
        }

        if (rdats.ContainsKey((int)RegionData.RegionDataType.Icon))
        { // Need to create icon record
            if (!majorFrame.TryLocateSubrecordFrame("EDID", out var edidFrame, out var edidLoc))
            {
                throw new ArgumentException();
            }
            var locToPlace = fileOffset + edidLoc + edidFrame.TotalLength;

            // Get icon string
            var iconLoc = rdats[(int)RegionData.RegionDataType.Icon];
            stream.Position = iconLoc.Min + 20;
            var iconStr = BinaryStringUtility.ToZString(stream.ReadMemory((int)(iconLoc.Max - stream.Position)), MutagenEncodingProvider._1252);

            // Get icon bytes
            MemoryStream memStream = new MemoryStream();
            using (var writer = new MutagenWriter(memStream, this.GameRelease))
            {
                using (HeaderExport.Header(
                           writer,
                           new RecordType("ICON"),
                           ObjectType.Subrecord))
                {
                    StringBinaryTranslation.Instance.Write(writer, iconStr, StringBinaryType.NullTerminate);
                }
            }

            var arr = memStream.ToArray();
            this._instructions.SetAddition(
                loc: locToPlace,
                addition: arr);
            this._instructions.SetRemove(
                section: iconLoc);
            amount += arr.Length;
            amount -= (int)iconLoc.Width;
        }

        ProcessLengths(
            majorFrame,
            amount,
            fileOffset);
    }