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()); }
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); }
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); } }
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); }
public void SetRemove(RangeInt64 section) { SetMove( section: section, loc: long.MaxValue); }
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); }
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); }