Decompiled source of Gundomizer v1.1.0
AssetsTools.NET.dll
Decompiled 2 days ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Text; using System.Text.RegularExpressions; using AssetsTools.NET.Extra; using AssetsTools.NET.Extra.Decompressors.LZ4; using LZ4ps; using SevenZip; using SevenZip.Compression.LZ; using SevenZip.Compression.LZMA; using SevenZip.Compression.RangeCoder; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("AssetsTools.NET")] [assembly: AssemblyDescription("A remake and port of SeriousCache's AssetTools")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("nesrak1")] [assembly: AssemblyProduct("AssetsTools.NET")] [assembly: AssemblyCopyright("Written by nes")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("e09d5ac2-1a2e-4ec1-94ad-3f5e22f17658")] [assembly: AssemblyFileVersion("3.0.0.0")] [assembly: AssemblyVersion("3.0.0.0")] namespace SevenZip { internal class CRC { public static readonly uint[] Table; private uint _value = uint.MaxValue; static CRC() { Table = new uint[256]; for (uint num = 0u; num < 256; num++) { uint num2 = num; for (int i = 0; i < 8; i++) { num2 = (((num2 & 1) == 0) ? (num2 >> 1) : ((num2 >> 1) ^ 0xEDB88320u)); } Table[num] = num2; } } public void Init() { _value = uint.MaxValue; } public void UpdateByte(byte b) { _value = Table[(byte)_value ^ b] ^ (_value >> 8); } public void Update(byte[] data, uint offset, uint size) { for (uint num = 0u; num < size; num++) { _value = Table[(byte)_value ^ data[offset + num]] ^ (_value >> 8); } } public uint GetDigest() { return _value ^ 0xFFFFFFFFu; } private static uint CalculateDigest(byte[] data, uint offset, uint size) { CRC cRC = new CRC(); cRC.Update(data, offset, size); return cRC.GetDigest(); } private static bool VerifyDigest(uint digest, byte[] data, uint offset, uint size) { return CalculateDigest(data, offset, size) == digest; } } internal class DataErrorException : ApplicationException { public DataErrorException() : base("Data Error") { } } internal class InvalidParamException : ApplicationException { public InvalidParamException() : base("Invalid Parameter") { } } public interface ICodeProgress { void SetProgress(long inSize, long outSize); } public interface ICoder { void Code(Stream inStream, Stream outStream, long inSize, long outSize, ICodeProgress progress); } public enum CoderPropID { DefaultProp, DictionarySize, UsedMemorySize, Order, BlockSize, PosStateBits, LitContextBits, LitPosBits, NumFastBytes, MatchFinder, MatchFinderCycles, NumPasses, Algorithm, NumThreads, EndMarker } public interface ISetCoderProperties { void SetCoderProperties(CoderPropID[] propIDs, object[] properties); } public interface IWriteCoderProperties { void WriteCoderProperties(Stream outStream); } public interface ISetDecoderProperties { void SetDecoderProperties(byte[] properties); } } namespace SevenZip.Compression.RangeCoder { internal class Encoder { public const uint kTopValue = 16777216u; private Stream Stream; public ulong Low; public uint Range; private uint _cacheSize; private byte _cache; private long StartPosition; public void SetStream(Stream stream) { Stream = stream; } public void ReleaseStream() { Stream = null; } public void Init() { StartPosition = Stream.Position; Low = 0uL; Range = uint.MaxValue; _cacheSize = 1u; _cache = 0; } public void FlushData() { for (int i = 0; i < 5; i++) { ShiftLow(); } } public void FlushStream() { Stream.Flush(); } public void CloseStream() { Stream.Close(); } public void Encode(uint start, uint size, uint total) { Low += start * (Range /= total); Range *= size; while (Range < 16777216) { Range <<= 8; ShiftLow(); } } public void ShiftLow() { if ((uint)Low < 4278190080u || (int)(Low >> 32) == 1) { byte b = _cache; do { Stream.WriteByte((byte)(b + (Low >> 32))); b = byte.MaxValue; } while (--_cacheSize != 0); _cache = (byte)((uint)Low >> 24); } _cacheSize++; Low = (uint)((int)Low << 8); } public void EncodeDirectBits(uint v, int numTotalBits) { for (int num = numTotalBits - 1; num >= 0; num--) { Range >>= 1; if (((v >> num) & 1) == 1) { Low += Range; } if (Range < 16777216) { Range <<= 8; ShiftLow(); } } } public void EncodeBit(uint size0, int numTotalBits, uint symbol) { uint num = (Range >> numTotalBits) * size0; if (symbol == 0) { Range = num; } else { Low += num; Range -= num; } while (Range < 16777216) { Range <<= 8; ShiftLow(); } } public long GetProcessedSizeAdd() { return _cacheSize + Stream.Position - StartPosition + 4; } } internal class Decoder { public const uint kTopValue = 16777216u; public uint Range; public uint Code; public Stream Stream; public void Init(Stream stream) { Stream = stream; Code = 0u; Range = uint.MaxValue; for (int i = 0; i < 5; i++) { Code = (Code << 8) | (byte)Stream.ReadByte(); } } public void ReleaseStream() { Stream = null; } public void CloseStream() { Stream.Close(); } public void Normalize() { while (Range < 16777216) { Code = (Code << 8) | (byte)Stream.ReadByte(); Range <<= 8; } } public void Normalize2() { if (Range < 16777216) { Code = (Code << 8) | (byte)Stream.ReadByte(); Range <<= 8; } } public uint GetThreshold(uint total) { return Code / (Range /= total); } public void Decode(uint start, uint size, uint total) { Code -= start * Range; Range *= size; Normalize(); } public uint DecodeDirectBits(int numTotalBits) { uint num = Range; uint num2 = Code; uint num3 = 0u; for (int num4 = numTotalBits; num4 > 0; num4--) { num >>= 1; uint num5 = num2 - num >> 31; num2 -= num & (num5 - 1); num3 = (num3 << 1) | (1 - num5); if (num < 16777216) { num2 = (num2 << 8) | (byte)Stream.ReadByte(); num <<= 8; } } Range = num; Code = num2; return num3; } public uint DecodeBit(uint size0, int numTotalBits) { uint num = (Range >> numTotalBits) * size0; uint result; if (Code < num) { result = 0u; Range = num; } else { result = 1u; Code -= num; Range -= num; } Normalize(); return result; } } internal struct BitEncoder { public const int kNumBitModelTotalBits = 11; public const uint kBitModelTotal = 2048u; private const int kNumMoveBits = 5; private const int kNumMoveReducingBits = 2; public const int kNumBitPriceShiftBits = 6; private uint Prob; private static uint[] ProbPrices; public void Init() { Prob = 1024u; } public void UpdateModel(uint symbol) { if (symbol == 0) { Prob += 2048 - Prob >> 5; } else { Prob -= Prob >> 5; } } public void Encode(Encoder encoder, uint symbol) { uint num = (encoder.Range >> 11) * Prob; if (symbol == 0) { encoder.Range = num; Prob += 2048 - Prob >> 5; } else { encoder.Low += num; encoder.Range -= num; Prob -= Prob >> 5; } if (encoder.Range < 16777216) { encoder.Range <<= 8; encoder.ShiftLow(); } } static BitEncoder() { ProbPrices = new uint[512]; for (int num = 8; num >= 0; num--) { int num2 = 1 << 9 - num - 1; uint num3 = (uint)(1 << 9 - num); for (uint num4 = (uint)num2; num4 < num3; num4++) { ProbPrices[num4] = (uint)(num << 6) + (num3 - num4 << 6 >> 9 - num - 1); } } } public uint GetPrice(uint symbol) { return ProbPrices[(((Prob - symbol) ^ (int)(0 - symbol)) & 0x7FF) >> 2]; } public uint GetPrice0() { return ProbPrices[Prob >> 2]; } public uint GetPrice1() { return ProbPrices[2048 - Prob >> 2]; } } internal struct BitDecoder { public const int kNumBitModelTotalBits = 11; public const uint kBitModelTotal = 2048u; private const int kNumMoveBits = 5; private uint Prob; public void UpdateModel(int numMoveBits, uint symbol) { if (symbol == 0) { Prob += 2048 - Prob >> numMoveBits; } else { Prob -= Prob >> numMoveBits; } } public void Init() { Prob = 1024u; } public uint Decode(Decoder rangeDecoder) { uint num = (rangeDecoder.Range >> 11) * Prob; if (rangeDecoder.Code < num) { rangeDecoder.Range = num; Prob += 2048 - Prob >> 5; if (rangeDecoder.Range < 16777216) { rangeDecoder.Code = (rangeDecoder.Code << 8) | (byte)rangeDecoder.Stream.ReadByte(); rangeDecoder.Range <<= 8; } return 0u; } rangeDecoder.Range -= num; rangeDecoder.Code -= num; Prob -= Prob >> 5; if (rangeDecoder.Range < 16777216) { rangeDecoder.Code = (rangeDecoder.Code << 8) | (byte)rangeDecoder.Stream.ReadByte(); rangeDecoder.Range <<= 8; } return 1u; } } internal struct BitTreeEncoder { private BitEncoder[] Models; private int NumBitLevels; public BitTreeEncoder(int numBitLevels) { NumBitLevels = numBitLevels; Models = new BitEncoder[1 << numBitLevels]; } public void Init() { for (uint num = 1u; num < 1 << NumBitLevels; num++) { Models[num].Init(); } } public void Encode(Encoder rangeEncoder, uint symbol) { uint num = 1u; int num2 = NumBitLevels; while (num2 > 0) { num2--; uint num3 = (symbol >> num2) & 1; Models[num].Encode(rangeEncoder, num3); num = (num << 1) | num3; } } public void ReverseEncode(Encoder rangeEncoder, uint symbol) { uint num = 1u; for (uint num2 = 0u; num2 < NumBitLevels; num2++) { uint num3 = symbol & 1; Models[num].Encode(rangeEncoder, num3); num = (num << 1) | num3; symbol >>= 1; } } public uint GetPrice(uint symbol) { uint num = 0u; uint num2 = 1u; int num3 = NumBitLevels; while (num3 > 0) { num3--; uint num4 = (symbol >> num3) & 1; num += Models[num2].GetPrice(num4); num2 = (num2 << 1) + num4; } return num; } public uint ReverseGetPrice(uint symbol) { uint num = 0u; uint num2 = 1u; for (int num3 = NumBitLevels; num3 > 0; num3--) { uint num4 = symbol & 1; symbol >>= 1; num += Models[num2].GetPrice(num4); num2 = (num2 << 1) | num4; } return num; } public static uint ReverseGetPrice(BitEncoder[] Models, uint startIndex, int NumBitLevels, uint symbol) { uint num = 0u; uint num2 = 1u; for (int num3 = NumBitLevels; num3 > 0; num3--) { uint num4 = symbol & 1; symbol >>= 1; num += Models[startIndex + num2].GetPrice(num4); num2 = (num2 << 1) | num4; } return num; } public static void ReverseEncode(BitEncoder[] Models, uint startIndex, Encoder rangeEncoder, int NumBitLevels, uint symbol) { uint num = 1u; for (int i = 0; i < NumBitLevels; i++) { uint num2 = symbol & 1; Models[startIndex + num].Encode(rangeEncoder, num2); num = (num << 1) | num2; symbol >>= 1; } } } internal struct BitTreeDecoder { private BitDecoder[] Models; private int NumBitLevels; public BitTreeDecoder(int numBitLevels) { NumBitLevels = numBitLevels; Models = new BitDecoder[1 << numBitLevels]; } public void Init() { for (uint num = 1u; num < 1 << NumBitLevels; num++) { Models[num].Init(); } } public uint Decode(Decoder rangeDecoder) { uint num = 1u; for (int num2 = NumBitLevels; num2 > 0; num2--) { num = (num << 1) + Models[num].Decode(rangeDecoder); } return num - (uint)(1 << NumBitLevels); } public uint ReverseDecode(Decoder rangeDecoder) { uint num = 1u; uint num2 = 0u; for (int i = 0; i < NumBitLevels; i++) { uint num3 = Models[num].Decode(rangeDecoder); num <<= 1; num += num3; num2 |= num3 << i; } return num2; } public static uint ReverseDecode(BitDecoder[] Models, uint startIndex, Decoder rangeDecoder, int NumBitLevels) { uint num = 1u; uint num2 = 0u; for (int i = 0; i < NumBitLevels; i++) { uint num3 = Models[startIndex + num].Decode(rangeDecoder); num <<= 1; num += num3; num2 |= num3 << i; } return num2; } } } namespace SevenZip.Compression.LZ { internal interface IInWindowStream { void SetStream(Stream inStream); void Init(); void ReleaseStream(); byte GetIndexByte(int index); uint GetMatchLen(int index, uint distance, uint limit); uint GetNumAvailableBytes(); } internal interface IMatchFinder : IInWindowStream { void Create(uint historySize, uint keepAddBufferBefore, uint matchMaxLen, uint keepAddBufferAfter); uint GetMatches(uint[] distances); void Skip(uint num); } public class BinTree : InWindow, IMatchFinder, IInWindowStream { private uint _cyclicBufferPos; private uint _cyclicBufferSize; private uint _matchMaxLen; private uint[] _son; private uint[] _hash; private uint _cutValue = 255u; private uint _hashMask; private uint _hashSizeSum; private bool HASH_ARRAY = true; private const uint kHash2Size = 1024u; private const uint kHash3Size = 65536u; private const uint kBT2HashSize = 65536u; private const uint kStartMaxLen = 1u; private const uint kHash3Offset = 1024u; private const uint kEmptyHashValue = 0u; private const uint kMaxValForNormalize = 2147483647u; private uint kNumHashDirectBytes; private uint kMinMatchCheck = 4u; private uint kFixHashSize = 66560u; public void SetType(int numHashBytes) { HASH_ARRAY = numHashBytes > 2; if (HASH_ARRAY) { kNumHashDirectBytes = 0u; kMinMatchCheck = 4u; kFixHashSize = 66560u; } else { kNumHashDirectBytes = 2u; kMinMatchCheck = 3u; kFixHashSize = 0u; } } public new void SetStream(Stream stream) { base.SetStream(stream); } public new void ReleaseStream() { base.ReleaseStream(); } public new void Init() { base.Init(); for (uint num = 0u; num < _hashSizeSum; num++) { _hash[num] = 0u; } _cyclicBufferPos = 0u; ReduceOffsets(-1); } public new void MovePos() { if (++_cyclicBufferPos >= _cyclicBufferSize) { _cyclicBufferPos = 0u; } base.MovePos(); if (_pos == int.MaxValue) { Normalize(); } } public new byte GetIndexByte(int index) { return base.GetIndexByte(index); } public new uint GetMatchLen(int index, uint distance, uint limit) { return base.GetMatchLen(index, distance, limit); } public new uint GetNumAvailableBytes() { return base.GetNumAvailableBytes(); } public void Create(uint historySize, uint keepAddBufferBefore, uint matchMaxLen, uint keepAddBufferAfter) { if (historySize > 2147483391) { throw new Exception(); } _cutValue = 16 + (matchMaxLen >> 1); uint keepSizeReserv = (historySize + keepAddBufferBefore + matchMaxLen + keepAddBufferAfter) / 2 + 256; Create(historySize + keepAddBufferBefore, matchMaxLen + keepAddBufferAfter, keepSizeReserv); _matchMaxLen = matchMaxLen; uint num = historySize + 1; if (_cyclicBufferSize != num) { _son = new uint[(_cyclicBufferSize = num) * 2]; } uint num2 = 65536u; if (HASH_ARRAY) { num2 = historySize - 1; num2 |= num2 >> 1; num2 |= num2 >> 2; num2 |= num2 >> 4; num2 |= num2 >> 8; num2 >>= 1; num2 |= 0xFFFF; if (num2 > 16777216) { num2 >>= 1; } _hashMask = num2; num2++; num2 += kFixHashSize; } if (num2 != _hashSizeSum) { _hash = new uint[_hashSizeSum = num2]; } } public uint GetMatches(uint[] distances) { uint num; if (_pos + _matchMaxLen <= _streamPos) { num = _matchMaxLen; } else { num = _streamPos - _pos; if (num < kMinMatchCheck) { MovePos(); return 0u; } } uint num2 = 0u; uint num3 = ((_pos > _cyclicBufferSize) ? (_pos - _cyclicBufferSize) : 0u); uint num4 = _bufferOffset + _pos; uint num5 = 1u; uint num6 = 0u; uint num7 = 0u; uint num10; if (HASH_ARRAY) { uint num8 = CRC.Table[_bufferBase[num4]] ^ _bufferBase[num4 + 1]; num6 = num8 & 0x3FF; int num9 = (int)num8 ^ (_bufferBase[num4 + 2] << 8); num7 = (uint)(num9 & 0xFFFF); num10 = ((uint)num9 ^ (CRC.Table[_bufferBase[num4 + 3]] << 5)) & _hashMask; } else { num10 = (uint)(_bufferBase[num4] ^ (_bufferBase[num4 + 1] << 8)); } uint num11 = _hash[kFixHashSize + num10]; if (HASH_ARRAY) { uint num12 = _hash[num6]; uint num13 = _hash[1024 + num7]; _hash[num6] = _pos; _hash[1024 + num7] = _pos; if (num12 > num3 && _bufferBase[_bufferOffset + num12] == _bufferBase[num4]) { num5 = (distances[num2++] = 2u); distances[num2++] = _pos - num12 - 1; } if (num13 > num3 && _bufferBase[_bufferOffset + num13] == _bufferBase[num4]) { if (num13 == num12) { num2 -= 2; } num5 = (distances[num2++] = 3u); distances[num2++] = _pos - num13 - 1; num12 = num13; } if (num2 != 0 && num12 == num11) { num2 -= 2; num5 = 1u; } } _hash[kFixHashSize + num10] = _pos; uint num14 = (_cyclicBufferPos << 1) + 1; uint num15 = _cyclicBufferPos << 1; uint val2; uint val = (val2 = kNumHashDirectBytes); if (kNumHashDirectBytes != 0 && num11 > num3 && _bufferBase[_bufferOffset + num11 + kNumHashDirectBytes] != _bufferBase[num4 + kNumHashDirectBytes]) { num5 = (distances[num2++] = kNumHashDirectBytes); distances[num2++] = _pos - num11 - 1; } uint cutValue = _cutValue; while (true) { if (num11 <= num3 || cutValue-- == 0) { _son[num14] = (_son[num15] = 0u); break; } uint num16 = _pos - num11; uint num17 = ((num16 <= _cyclicBufferPos) ? (_cyclicBufferPos - num16) : (_cyclicBufferPos - num16 + _cyclicBufferSize)) << 1; uint num18 = _bufferOffset + num11; uint num19 = Math.Min(val, val2); if (_bufferBase[num18 + num19] == _bufferBase[num4 + num19]) { while (++num19 != num && _bufferBase[num18 + num19] == _bufferBase[num4 + num19]) { } if (num5 < num19) { num5 = (distances[num2++] = num19); distances[num2++] = num16 - 1; if (num19 == num) { _son[num15] = _son[num17]; _son[num14] = _son[num17 + 1]; break; } } } if (_bufferBase[num18 + num19] < _bufferBase[num4 + num19]) { _son[num15] = num11; num15 = num17 + 1; num11 = _son[num15]; val2 = num19; } else { _son[num14] = num11; num14 = num17; num11 = _son[num14]; val = num19; } } MovePos(); return num2; } public void Skip(uint num) { do { uint num2; if (_pos + _matchMaxLen <= _streamPos) { num2 = _matchMaxLen; } else { num2 = _streamPos - _pos; if (num2 < kMinMatchCheck) { MovePos(); continue; } } uint num3 = ((_pos > _cyclicBufferSize) ? (_pos - _cyclicBufferSize) : 0u); uint num4 = _bufferOffset + _pos; uint num9; if (HASH_ARRAY) { uint num5 = CRC.Table[_bufferBase[num4]] ^ _bufferBase[num4 + 1]; uint num6 = num5 & 0x3FF; _hash[num6] = _pos; int num7 = (int)num5 ^ (_bufferBase[num4 + 2] << 8); uint num8 = (uint)(num7 & 0xFFFF); _hash[1024 + num8] = _pos; num9 = ((uint)num7 ^ (CRC.Table[_bufferBase[num4 + 3]] << 5)) & _hashMask; } else { num9 = (uint)(_bufferBase[num4] ^ (_bufferBase[num4 + 1] << 8)); } uint num10 = _hash[kFixHashSize + num9]; _hash[kFixHashSize + num9] = _pos; uint num11 = (_cyclicBufferPos << 1) + 1; uint num12 = _cyclicBufferPos << 1; uint val2; uint val = (val2 = kNumHashDirectBytes); uint cutValue = _cutValue; while (true) { if (num10 <= num3 || cutValue-- == 0) { _son[num11] = (_son[num12] = 0u); break; } uint num13 = _pos - num10; uint num14 = ((num13 <= _cyclicBufferPos) ? (_cyclicBufferPos - num13) : (_cyclicBufferPos - num13 + _cyclicBufferSize)) << 1; uint num15 = _bufferOffset + num10; uint num16 = Math.Min(val, val2); if (_bufferBase[num15 + num16] == _bufferBase[num4 + num16]) { while (++num16 != num2 && _bufferBase[num15 + num16] == _bufferBase[num4 + num16]) { } if (num16 == num2) { _son[num12] = _son[num14]; _son[num11] = _son[num14 + 1]; break; } } if (_bufferBase[num15 + num16] < _bufferBase[num4 + num16]) { _son[num12] = num10; num12 = num14 + 1; num10 = _son[num12]; val2 = num16; } else { _son[num11] = num10; num11 = num14; num10 = _son[num11]; val = num16; } } MovePos(); } while (--num != 0); } private void NormalizeLinks(uint[] items, uint numItems, uint subValue) { for (uint num = 0u; num < numItems; num++) { uint num2 = items[num]; num2 = ((num2 > subValue) ? (num2 - subValue) : 0u); items[num] = num2; } } private void Normalize() { uint subValue = _pos - _cyclicBufferSize; NormalizeLinks(_son, _cyclicBufferSize * 2, subValue); NormalizeLinks(_hash, _hashSizeSum, subValue); ReduceOffsets((int)subValue); } public void SetCutValue(uint cutValue) { _cutValue = cutValue; } } public class InWindow { public byte[] _bufferBase; private Stream _stream; private uint _posLimit; private bool _streamEndWasReached; private uint _pointerToLastSafePosition; public uint _bufferOffset; public uint _blockSize; public uint _pos; private uint _keepSizeBefore; private uint _keepSizeAfter; public uint _streamPos; public void MoveBlock() { uint num = _bufferOffset + _pos - _keepSizeBefore; if (num != 0) { num--; } uint num2 = _bufferOffset + _streamPos - num; for (uint num3 = 0u; num3 < num2; num3++) { _bufferBase[num3] = _bufferBase[num + num3]; } _bufferOffset -= num; } public virtual void ReadBlock() { if (_streamEndWasReached) { return; } while (true) { int num = (int)(0 - _bufferOffset + _blockSize - _streamPos); if (num == 0) { return; } int num2 = _stream.Read(_bufferBase, (int)(_bufferOffset + _streamPos), num); if (num2 == 0) { break; } _streamPos += (uint)num2; if (_streamPos >= _pos + _keepSizeAfter) { _posLimit = _streamPos - _keepSizeAfter; } } _posLimit = _streamPos; if (_bufferOffset + _posLimit > _pointerToLastSafePosition) { _posLimit = _pointerToLastSafePosition - _bufferOffset; } _streamEndWasReached = true; } private void Free() { _bufferBase = null; } public void Create(uint keepSizeBefore, uint keepSizeAfter, uint keepSizeReserv) { _keepSizeBefore = keepSizeBefore; _keepSizeAfter = keepSizeAfter; uint num = keepSizeBefore + keepSizeAfter + keepSizeReserv; if (_bufferBase == null || _blockSize != num) { Free(); _blockSize = num; _bufferBase = new byte[_blockSize]; } _pointerToLastSafePosition = _blockSize - keepSizeAfter; } public void SetStream(Stream stream) { _stream = stream; } public void ReleaseStream() { _stream = null; } public void Init() { _bufferOffset = 0u; _pos = 0u; _streamPos = 0u; _streamEndWasReached = false; ReadBlock(); } public void MovePos() { _pos++; if (_pos > _posLimit) { if (_bufferOffset + _pos > _pointerToLastSafePosition) { MoveBlock(); } ReadBlock(); } } public byte GetIndexByte(int index) { return _bufferBase[_bufferOffset + _pos + index]; } public uint GetMatchLen(int index, uint distance, uint limit) { if (_streamEndWasReached && _pos + index + limit > _streamPos) { limit = _streamPos - (uint)(int)(_pos + index); } distance++; uint num = _bufferOffset + _pos + (uint)index; uint num2; for (num2 = 0u; num2 < limit && _bufferBase[num + num2] == _bufferBase[num + num2 - distance]; num2++) { } return num2; } public uint GetNumAvailableBytes() { return _streamPos - _pos; } public void ReduceOffsets(int subValue) { _bufferOffset += (uint)subValue; _posLimit -= (uint)subValue; _pos -= (uint)subValue; _streamPos -= (uint)subValue; } } public class OutWindow { private byte[] _buffer; private uint _pos; private uint _windowSize; private uint _streamPos; private Stream _stream; public uint TrainSize; public void Create(uint windowSize) { if (_windowSize != windowSize) { _buffer = new byte[windowSize]; } _windowSize = windowSize; _pos = 0u; _streamPos = 0u; } public void Init(Stream stream, bool solid) { ReleaseStream(); _stream = stream; if (!solid) { _streamPos = 0u; _pos = 0u; TrainSize = 0u; } } public bool Train(Stream stream) { long length = stream.Length; uint num = (TrainSize = (uint)((length < _windowSize) ? length : _windowSize)); stream.Position = length - num; _streamPos = (_pos = 0u); while (num != 0) { uint num2 = _windowSize - _pos; if (num < num2) { num2 = num; } int num3 = stream.Read(_buffer, (int)_pos, (int)num2); if (num3 == 0) { return false; } num -= (uint)num3; _pos += (uint)num3; _streamPos += (uint)num3; if (_pos == _windowSize) { _streamPos = (_pos = 0u); } } return true; } public void ReleaseStream() { Flush(); _stream = null; } public void Flush() { uint num = _pos - _streamPos; if (num != 0) { _stream.Write(_buffer, (int)_streamPos, (int)num); if (_pos >= _windowSize) { _pos = 0u; } _streamPos = _pos; } } public void CopyBlock(uint distance, uint len) { uint num = _pos - distance - 1; if (num >= _windowSize) { num += _windowSize; } while (len != 0) { if (num >= _windowSize) { num = 0u; } _buffer[_pos++] = _buffer[num++]; if (_pos >= _windowSize) { Flush(); } len--; } } public void PutByte(byte b) { _buffer[_pos++] = b; if (_pos >= _windowSize) { Flush(); } } public byte GetByte(uint distance) { uint num = _pos - distance - 1; if (num >= _windowSize) { num += _windowSize; } return _buffer[num]; } } } namespace SevenZip.Compression.LZMA { internal abstract class Base { public struct State { public uint Index; public void Init() { Index = 0u; } public void UpdateChar() { if (Index < 4) { Index = 0u; } else if (Index < 10) { Index -= 3u; } else { Index -= 6u; } } public void UpdateMatch() { Index = ((Index < 7) ? 7u : 10u); } public void UpdateRep() { Index = ((Index < 7) ? 8u : 11u); } public void UpdateShortRep() { Index = ((Index < 7) ? 9u : 11u); } public bool IsCharState() { return Index < 7; } } public const uint kNumRepDistances = 4u; public const uint kNumStates = 12u; public const int kNumPosSlotBits = 6; public const int kDicLogSizeMin = 0; public const int kNumLenToPosStatesBits = 2; public const uint kNumLenToPosStates = 4u; public const uint kMatchMinLen = 2u; public const int kNumAlignBits = 4; public const uint kAlignTableSize = 16u; public const uint kAlignMask = 15u; public const uint kStartPosModelIndex = 4u; public const uint kEndPosModelIndex = 14u; public const uint kNumPosModels = 10u; public const uint kNumFullDistances = 128u; public const uint kNumLitPosStatesBitsEncodingMax = 4u; public const uint kNumLitContextBitsMax = 8u; public const int kNumPosStatesBitsMax = 4; public const uint kNumPosStatesMax = 16u; public const int kNumPosStatesBitsEncodingMax = 4; public const uint kNumPosStatesEncodingMax = 16u; public const int kNumLowLenBits = 3; public const int kNumMidLenBits = 3; public const int kNumHighLenBits = 8; public const uint kNumLowLenSymbols = 8u; public const uint kNumMidLenSymbols = 8u; public const uint kNumLenSymbols = 272u; public const uint kMatchMaxLen = 273u; public static uint GetLenToPosState(uint len) { len -= 2; if (len < 4) { return len; } return 3u; } } public class Decoder : ICoder, ISetDecoderProperties { private class LenDecoder { private BitDecoder m_Choice; private BitDecoder m_Choice2; private BitTreeDecoder[] m_LowCoder = new BitTreeDecoder[16]; private BitTreeDecoder[] m_MidCoder = new BitTreeDecoder[16]; private BitTreeDecoder m_HighCoder = new BitTreeDecoder(8); private uint m_NumPosStates; public void Create(uint numPosStates) { for (uint num = m_NumPosStates; num < numPosStates; num++) { m_LowCoder[num] = new BitTreeDecoder(3); m_MidCoder[num] = new BitTreeDecoder(3); } m_NumPosStates = numPosStates; } public void Init() { m_Choice.Init(); for (uint num = 0u; num < m_NumPosStates; num++) { m_LowCoder[num].Init(); m_MidCoder[num].Init(); } m_Choice2.Init(); m_HighCoder.Init(); } public uint Decode(SevenZip.Compression.RangeCoder.Decoder rangeDecoder, uint posState) { if (m_Choice.Decode(rangeDecoder) == 0) { return m_LowCoder[posState].Decode(rangeDecoder); } uint num = 8u; if (m_Choice2.Decode(rangeDecoder) == 0) { return num + m_MidCoder[posState].Decode(rangeDecoder); } num += 8; return num + m_HighCoder.Decode(rangeDecoder); } } private class LiteralDecoder { private struct Decoder2 { private BitDecoder[] m_Decoders; public void Create() { m_Decoders = new BitDecoder[768]; } public void Init() { for (int i = 0; i < 768; i++) { m_Decoders[i].Init(); } } public byte DecodeNormal(SevenZip.Compression.RangeCoder.Decoder rangeDecoder) { uint num = 1u; do { num = (num << 1) | m_Decoders[num].Decode(rangeDecoder); } while (num < 256); return (byte)num; } public byte DecodeWithMatchByte(SevenZip.Compression.RangeCoder.Decoder rangeDecoder, byte matchByte) { uint num = 1u; do { uint num2 = (uint)((matchByte >> 7) & 1); matchByte <<= 1; uint num3 = m_Decoders[(1 + num2 << 8) + num].Decode(rangeDecoder); num = (num << 1) | num3; if (num2 != num3) { while (num < 256) { num = (num << 1) | m_Decoders[num].Decode(rangeDecoder); } break; } } while (num < 256); return (byte)num; } } private Decoder2[] m_Coders; private int m_NumPrevBits; private int m_NumPosBits; private uint m_PosMask; public void Create(int numPosBits, int numPrevBits) { if (m_Coders == null || m_NumPrevBits != numPrevBits || m_NumPosBits != numPosBits) { m_NumPosBits = numPosBits; m_PosMask = (uint)((1 << numPosBits) - 1); m_NumPrevBits = numPrevBits; uint num = (uint)(1 << m_NumPrevBits + m_NumPosBits); m_Coders = new Decoder2[num]; for (uint num2 = 0u; num2 < num; num2++) { m_Coders[num2].Create(); } } } public void Init() { uint num = (uint)(1 << m_NumPrevBits + m_NumPosBits); for (uint num2 = 0u; num2 < num; num2++) { m_Coders[num2].Init(); } } private uint GetState(uint pos, byte prevByte) { return ((pos & m_PosMask) << m_NumPrevBits) + (uint)(prevByte >> 8 - m_NumPrevBits); } public byte DecodeNormal(SevenZip.Compression.RangeCoder.Decoder rangeDecoder, uint pos, byte prevByte) { return m_Coders[GetState(pos, prevByte)].DecodeNormal(rangeDecoder); } public byte DecodeWithMatchByte(SevenZip.Compression.RangeCoder.Decoder rangeDecoder, uint pos, byte prevByte, byte matchByte) { return m_Coders[GetState(pos, prevByte)].DecodeWithMatchByte(rangeDecoder, matchByte); } } private OutWindow m_OutWindow = new OutWindow(); private SevenZip.Compression.RangeCoder.Decoder m_RangeDecoder = new SevenZip.Compression.RangeCoder.Decoder(); private BitDecoder[] m_IsMatchDecoders = new BitDecoder[192]; private BitDecoder[] m_IsRepDecoders = new BitDecoder[12]; private BitDecoder[] m_IsRepG0Decoders = new BitDecoder[12]; private BitDecoder[] m_IsRepG1Decoders = new BitDecoder[12]; private BitDecoder[] m_IsRepG2Decoders = new BitDecoder[12]; private BitDecoder[] m_IsRep0LongDecoders = new BitDecoder[192]; private BitTreeDecoder[] m_PosSlotDecoder = new BitTreeDecoder[4]; private BitDecoder[] m_PosDecoders = new BitDecoder[114]; private BitTreeDecoder m_PosAlignDecoder = new BitTreeDecoder(4); private LenDecoder m_LenDecoder = new LenDecoder(); private LenDecoder m_RepLenDecoder = new LenDecoder(); private LiteralDecoder m_LiteralDecoder = new LiteralDecoder(); private uint m_DictionarySize; private uint m_DictionarySizeCheck; private uint m_PosStateMask; private bool _solid; public Decoder() { m_DictionarySize = uint.MaxValue; for (int i = 0; (long)i < 4L; i++) { m_PosSlotDecoder[i] = new BitTreeDecoder(6); } } private void SetDictionarySize(uint dictionarySize) { if (m_DictionarySize != dictionarySize) { m_DictionarySize = dictionarySize; m_DictionarySizeCheck = Math.Max(m_DictionarySize, 1u); uint windowSize = Math.Max(m_DictionarySizeCheck, 4096u); m_OutWindow.Create(windowSize); } } private void SetLiteralProperties(int lp, int lc) { if (lp > 8) { throw new InvalidParamException(); } if (lc > 8) { throw new InvalidParamException(); } m_LiteralDecoder.Create(lp, lc); } private void SetPosBitsProperties(int pb) { if (pb > 4) { throw new InvalidParamException(); } uint num = (uint)(1 << pb); m_LenDecoder.Create(num); m_RepLenDecoder.Create(num); m_PosStateMask = num - 1; } private void Init(Stream inStream, Stream outStream) { m_RangeDecoder.Init(inStream); m_OutWindow.Init(outStream, _solid); for (uint num = 0u; num < 12; num++) { for (uint num2 = 0u; num2 <= m_PosStateMask; num2++) { uint num3 = (num << 4) + num2; m_IsMatchDecoders[num3].Init(); m_IsRep0LongDecoders[num3].Init(); } m_IsRepDecoders[num].Init(); m_IsRepG0Decoders[num].Init(); m_IsRepG1Decoders[num].Init(); m_IsRepG2Decoders[num].Init(); } m_LiteralDecoder.Init(); for (uint num = 0u; num < 4; num++) { m_PosSlotDecoder[num].Init(); } for (uint num = 0u; num < 114; num++) { m_PosDecoders[num].Init(); } m_LenDecoder.Init(); m_RepLenDecoder.Init(); m_PosAlignDecoder.Init(); } public void Code(Stream inStream, Stream outStream, long inSize, long outSize, ICodeProgress progress) { Init(inStream, outStream); Base.State state = default(Base.State); state.Init(); uint num = 0u; uint num2 = 0u; uint num3 = 0u; uint num4 = 0u; ulong num5 = 0uL; if (num5 < (ulong)outSize) { if (m_IsMatchDecoders[state.Index << 4].Decode(m_RangeDecoder) != 0) { throw new DataErrorException(); } state.UpdateChar(); byte b = m_LiteralDecoder.DecodeNormal(m_RangeDecoder, 0u, 0); m_OutWindow.PutByte(b); num5++; } while (num5 < (ulong)outSize) { uint num6 = (uint)(int)num5 & m_PosStateMask; if (m_IsMatchDecoders[(state.Index << 4) + num6].Decode(m_RangeDecoder) == 0) { byte prevByte = m_OutWindow.GetByte(0u); byte b2 = (state.IsCharState() ? m_LiteralDecoder.DecodeNormal(m_RangeDecoder, (uint)num5, prevByte) : m_LiteralDecoder.DecodeWithMatchByte(m_RangeDecoder, (uint)num5, prevByte, m_OutWindow.GetByte(num))); m_OutWindow.PutByte(b2); state.UpdateChar(); num5++; continue; } uint num8; if (m_IsRepDecoders[state.Index].Decode(m_RangeDecoder) == 1) { if (m_IsRepG0Decoders[state.Index].Decode(m_RangeDecoder) == 0) { if (m_IsRep0LongDecoders[(state.Index << 4) + num6].Decode(m_RangeDecoder) == 0) { state.UpdateShortRep(); m_OutWindow.PutByte(m_OutWindow.GetByte(num)); num5++; continue; } } else { uint num7; if (m_IsRepG1Decoders[state.Index].Decode(m_RangeDecoder) == 0) { num7 = num2; } else { if (m_IsRepG2Decoders[state.Index].Decode(m_RangeDecoder) == 0) { num7 = num3; } else { num7 = num4; num4 = num3; } num3 = num2; } num2 = num; num = num7; } num8 = m_RepLenDecoder.Decode(m_RangeDecoder, num6) + 2; state.UpdateRep(); } else { num4 = num3; num3 = num2; num2 = num; num8 = 2 + m_LenDecoder.Decode(m_RangeDecoder, num6); state.UpdateMatch(); uint num9 = m_PosSlotDecoder[Base.GetLenToPosState(num8)].Decode(m_RangeDecoder); if (num9 >= 4) { int num10 = (int)((num9 >> 1) - 1); num = (2 | (num9 & 1)) << num10; if (num9 < 14) { num += BitTreeDecoder.ReverseDecode(m_PosDecoders, num - num9 - 1, m_RangeDecoder, num10); } else { num += m_RangeDecoder.DecodeDirectBits(num10 - 4) << 4; num += m_PosAlignDecoder.ReverseDecode(m_RangeDecoder); } } else { num = num9; } } if (num >= m_OutWindow.TrainSize + num5 || num >= m_DictionarySizeCheck) { if (num == uint.MaxValue) { break; } throw new DataErrorException(); } m_OutWindow.CopyBlock(num, num8); num5 += num8; } m_OutWindow.Flush(); m_OutWindow.ReleaseStream(); m_RangeDecoder.ReleaseStream(); } public void SetDecoderProperties(byte[] properties) { if (properties.Length < 5) { throw new InvalidParamException(); } int lc = properties[0] % 9; int num = properties[0] / 9; int lp = num % 5; int num2 = num / 5; if (num2 > 4) { throw new InvalidParamException(); } uint num3 = 0u; for (int i = 0; i < 4; i++) { num3 += (uint)(properties[1 + i] << i * 8); } SetDictionarySize(num3); SetLiteralProperties(lp, lc); SetPosBitsProperties(num2); } public bool Train(Stream stream) { _solid = true; return m_OutWindow.Train(stream); } } public class Encoder : ICoder, ISetCoderProperties, IWriteCoderProperties { private enum EMatchFinderType { BT2, BT4 } private class LiteralEncoder { public struct Encoder2 { private BitEncoder[] m_Encoders; public void Create() { m_Encoders = new BitEncoder[768]; } public void Init() { for (int i = 0; i < 768; i++) { m_Encoders[i].Init(); } } public void Encode(SevenZip.Compression.RangeCoder.Encoder rangeEncoder, byte symbol) { uint num = 1u; for (int num2 = 7; num2 >= 0; num2--) { uint num3 = (uint)((symbol >> num2) & 1); m_Encoders[num].Encode(rangeEncoder, num3); num = (num << 1) | num3; } } public void EncodeMatched(SevenZip.Compression.RangeCoder.Encoder rangeEncoder, byte matchByte, byte symbol) { uint num = 1u; bool flag = true; for (int num2 = 7; num2 >= 0; num2--) { uint num3 = (uint)((symbol >> num2) & 1); uint num4 = num; if (flag) { uint num5 = (uint)((matchByte >> num2) & 1); num4 += 1 + num5 << 8; flag = num5 == num3; } m_Encoders[num4].Encode(rangeEncoder, num3); num = (num << 1) | num3; } } public uint GetPrice(bool matchMode, byte matchByte, byte symbol) { uint num = 0u; uint num2 = 1u; int num3 = 7; if (matchMode) { while (num3 >= 0) { uint num4 = (uint)((matchByte >> num3) & 1); uint num5 = (uint)((symbol >> num3) & 1); num += m_Encoders[(1 + num4 << 8) + num2].GetPrice(num5); num2 = (num2 << 1) | num5; if (num4 != num5) { num3--; break; } num3--; } } while (num3 >= 0) { uint num6 = (uint)((symbol >> num3) & 1); num += m_Encoders[num2].GetPrice(num6); num2 = (num2 << 1) | num6; num3--; } return num; } } private Encoder2[] m_Coders; private int m_NumPrevBits; private int m_NumPosBits; private uint m_PosMask; public void Create(int numPosBits, int numPrevBits) { if (m_Coders == null || m_NumPrevBits != numPrevBits || m_NumPosBits != numPosBits) { m_NumPosBits = numPosBits; m_PosMask = (uint)((1 << numPosBits) - 1); m_NumPrevBits = numPrevBits; uint num = (uint)(1 << m_NumPrevBits + m_NumPosBits); m_Coders = new Encoder2[num]; for (uint num2 = 0u; num2 < num; num2++) { m_Coders[num2].Create(); } } } public void Init() { uint num = (uint)(1 << m_NumPrevBits + m_NumPosBits); for (uint num2 = 0u; num2 < num; num2++) { m_Coders[num2].Init(); } } public Encoder2 GetSubCoder(uint pos, byte prevByte) { return m_Coders[(int)((pos & m_PosMask) << m_NumPrevBits) + (prevByte >> 8 - m_NumPrevBits)]; } } private class LenEncoder { private BitEncoder _choice; private BitEncoder _choice2; private BitTreeEncoder[] _lowCoder = new BitTreeEncoder[16]; private BitTreeEncoder[] _midCoder = new BitTreeEncoder[16]; private BitTreeEncoder _highCoder = new BitTreeEncoder(8); public LenEncoder() { for (uint num = 0u; num < 16; num++) { _lowCoder[num] = new BitTreeEncoder(3); _midCoder[num] = new BitTreeEncoder(3); } } public void Init(uint numPosStates) { _choice.Init(); _choice2.Init(); for (uint num = 0u; num < numPosStates; num++) { _lowCoder[num].Init(); _midCoder[num].Init(); } _highCoder.Init(); } public void Encode(SevenZip.Compression.RangeCoder.Encoder rangeEncoder, uint symbol, uint posState) { if (symbol < 8) { _choice.Encode(rangeEncoder, 0u); _lowCoder[posState].Encode(rangeEncoder, symbol); return; } symbol -= 8; _choice.Encode(rangeEncoder, 1u); if (symbol < 8) { _choice2.Encode(rangeEncoder, 0u); _midCoder[posState].Encode(rangeEncoder, symbol); } else { _choice2.Encode(rangeEncoder, 1u); _highCoder.Encode(rangeEncoder, symbol - 8); } } public void SetPrices(uint posState, uint numSymbols, uint[] prices, uint st) { uint price = _choice.GetPrice0(); uint price2 = _choice.GetPrice1(); uint num = price2 + _choice2.GetPrice0(); uint num2 = price2 + _choice2.GetPrice1(); uint num3 = 0u; for (num3 = 0u; num3 < 8; num3++) { if (num3 >= numSymbols) { return; } prices[st + num3] = price + _lowCoder[posState].GetPrice(num3); } for (; num3 < 16; num3++) { if (num3 >= numSymbols) { return; } prices[st + num3] = num + _midCoder[posState].GetPrice(num3 - 8); } for (; num3 < numSymbols; num3++) { prices[st + num3] = num2 + _highCoder.GetPrice(num3 - 8 - 8); } } } private class LenPriceTableEncoder : LenEncoder { private uint[] _prices = new uint[4352]; private uint _tableSize; private uint[] _counters = new uint[16]; public void SetTableSize(uint tableSize) { _tableSize = tableSize; } public uint GetPrice(uint symbol, uint posState) { return _prices[posState * 272 + symbol]; } private void UpdateTable(uint posState) { SetPrices(posState, _tableSize, _prices, posState * 272); _counters[posState] = _tableSize; } public void UpdateTables(uint numPosStates) { for (uint num = 0u; num < numPosStates; num++) { UpdateTable(num); } } public new void Encode(SevenZip.Compression.RangeCoder.Encoder rangeEncoder, uint symbol, uint posState) { base.Encode(rangeEncoder, symbol, posState); if (--_counters[posState] == 0) { UpdateTable(posState); } } } private class Optimal { public Base.State State; public bool Prev1IsChar; public bool Prev2; public uint PosPrev2; public uint BackPrev2; public uint Price; public uint PosPrev; public uint BackPrev; public uint Backs0; public uint Backs1; public uint Backs2; public uint Backs3; public void MakeAsChar() { BackPrev = uint.MaxValue; Prev1IsChar = false; } public void MakeAsShortRep() { BackPrev = 0u; Prev1IsChar = false; } public bool IsShortRep() { return BackPrev == 0; } } private const uint kIfinityPrice = 268435455u; private static byte[] g_FastPos; private Base.State _state; private byte _previousByte; private uint[] _repDistances = new uint[4]; private const int kDefaultDictionaryLogSize = 22; private const uint kNumFastBytesDefault = 32u; private const uint kNumLenSpecSymbols = 16u; private const uint kNumOpts = 4096u; private Optimal[] _optimum = new Optimal[4096]; private IMatchFinder _matchFinder; private SevenZip.Compression.RangeCoder.Encoder _rangeEncoder = new SevenZip.Compression.RangeCoder.Encoder(); private BitEncoder[] _isMatch = new BitEncoder[192]; private BitEncoder[] _isRep = new BitEncoder[12]; private BitEncoder[] _isRepG0 = new BitEncoder[12]; private BitEncoder[] _isRepG1 = new BitEncoder[12]; private BitEncoder[] _isRepG2 = new BitEncoder[12]; private BitEncoder[] _isRep0Long = new BitEncoder[192]; private BitTreeEncoder[] _posSlotEncoder = new BitTreeEncoder[4]; private BitEncoder[] _posEncoders = new BitEncoder[114]; private BitTreeEncoder _posAlignEncoder = new BitTreeEncoder(4); private LenPriceTableEncoder _lenEncoder = new LenPriceTableEncoder(); private LenPriceTableEncoder _repMatchLenEncoder = new LenPriceTableEncoder(); private LiteralEncoder _literalEncoder = new LiteralEncoder(); private uint[] _matchDistances = new uint[548]; private uint _numFastBytes = 32u; private uint _longestMatchLength; private uint _numDistancePairs; private uint _additionalOffset; private uint _optimumEndIndex; private uint _optimumCurrentIndex; private bool _longestMatchWasFound; private uint[] _posSlotPrices = new uint[256]; private uint[] _distancesPrices = new uint[512]; private uint[] _alignPrices = new uint[16]; private uint _alignPriceCount; private uint _distTableSize = 44u; private int _posStateBits = 2; private uint _posStateMask = 3u; private int _numLiteralPosStateBits; private int _numLiteralContextBits = 3; private uint _dictionarySize = 4194304u; private uint _dictionarySizePrev = uint.MaxValue; private uint _numFastBytesPrev = uint.MaxValue; private long nowPos64; private bool _finished; private Stream _inStream; private EMatchFinderType _matchFinderType = EMatchFinderType.BT4; private bool _writeEndMark; private bool _needReleaseMFStream; private uint[] reps = new uint[4]; private uint[] repLens = new uint[4]; private const int kPropSize = 5; private byte[] properties = new byte[5]; private uint[] tempPrices = new uint[128]; private uint _matchPriceCount; private static string[] kMatchFinderIDs; private uint _trainSize; static Encoder() { g_FastPos = new byte[2048]; kMatchFinderIDs = new string[2] { "BT2", "BT4" }; int num = 2; g_FastPos[0] = 0; g_FastPos[1] = 1; for (byte b = 2; b < 22; b++) { uint num2 = (uint)(1 << (b >> 1) - 1); uint num3 = 0u; while (num3 < num2) { g_FastPos[num] = b; num3++; num++; } } } private static uint GetPosSlot(uint pos) { if (pos < 2048) { return g_FastPos[pos]; } if (pos < 2097152) { return (uint)(g_FastPos[pos >> 10] + 20); } return (uint)(g_FastPos[pos >> 20] + 40); } private static uint GetPosSlot2(uint pos) { if (pos < 131072) { return (uint)(g_FastPos[pos >> 6] + 12); } if (pos < 134217728) { return (uint)(g_FastPos[pos >> 16] + 32); } return (uint)(g_FastPos[pos >> 26] + 52); } private void BaseInit() { _state.Init(); _previousByte = 0; for (uint num = 0u; num < 4; num++) { _repDistances[num] = 0u; } } private void Create() { if (_matchFinder == null) { BinTree binTree = new BinTree(); int type = 4; if (_matchFinderType == EMatchFinderType.BT2) { type = 2; } binTree.SetType(type); _matchFinder = binTree; } _literalEncoder.Create(_numLiteralPosStateBits, _numLiteralContextBits); if (_dictionarySize != _dictionarySizePrev || _numFastBytesPrev != _numFastBytes) { _matchFinder.Create(_dictionarySize, 4096u, _numFastBytes, 274u); _dictionarySizePrev = _dictionarySize; _numFastBytesPrev = _numFastBytes; } } public Encoder() { for (int i = 0; (long)i < 4096L; i++) { _optimum[i] = new Optimal(); } for (int j = 0; (long)j < 4L; j++) { _posSlotEncoder[j] = new BitTreeEncoder(6); } } private void SetWriteEndMarkerMode(bool writeEndMarker) { _writeEndMark = writeEndMarker; } private void Init() { BaseInit(); _rangeEncoder.Init(); for (uint num = 0u; num < 12; num++) { for (uint num2 = 0u; num2 <= _posStateMask; num2++) { uint num3 = (num << 4) + num2; _isMatch[num3].Init(); _isRep0Long[num3].Init(); } _isRep[num].Init(); _isRepG0[num].Init(); _isRepG1[num].Init(); _isRepG2[num].Init(); } _literalEncoder.Init(); for (uint num = 0u; num < 4; num++) { _posSlotEncoder[num].Init(); } for (uint num = 0u; num < 114; num++) { _posEncoders[num].Init(); } _lenEncoder.Init((uint)(1 << _posStateBits)); _repMatchLenEncoder.Init((uint)(1 << _posStateBits)); _posAlignEncoder.Init(); _longestMatchWasFound = false; _optimumEndIndex = 0u; _optimumCurrentIndex = 0u; _additionalOffset = 0u; } private void ReadMatchDistances(out uint lenRes, out uint numDistancePairs) { lenRes = 0u; numDistancePairs = _matchFinder.GetMatches(_matchDistances); if (numDistancePairs != 0) { lenRes = _matchDistances[numDistancePairs - 2]; if (lenRes == _numFastBytes) { lenRes += _matchFinder.GetMatchLen((int)(lenRes - 1), _matchDistances[numDistancePairs - 1], 273 - lenRes); } } _additionalOffset++; } private void MovePos(uint num) { if (num != 0) { _matchFinder.Skip(num); _additionalOffset += num; } } private uint GetRepLen1Price(Base.State state, uint posState) { return _isRepG0[state.Index].GetPrice0() + _isRep0Long[(state.Index << 4) + posState].GetPrice0(); } private uint GetPureRepPrice(uint repIndex, Base.State state, uint posState) { uint price; if (repIndex == 0) { price = _isRepG0[state.Index].GetPrice0(); return price + _isRep0Long[(state.Index << 4) + posState].GetPrice1(); } price = _isRepG0[state.Index].GetPrice1(); if (repIndex == 1) { return price + _isRepG1[state.Index].GetPrice0(); } price += _isRepG1[state.Index].GetPrice1(); return price + _isRepG2[state.Index].GetPrice(repIndex - 2); } private uint GetRepPrice(uint repIndex, uint len, Base.State state, uint posState) { return _repMatchLenEncoder.GetPrice(len - 2, posState) + GetPureRepPrice(repIndex, state, posState); } private uint GetPosLenPrice(uint pos, uint len, uint posState) { uint lenToPosState = Base.GetLenToPosState(len); uint num = ((pos >= 128) ? (_posSlotPrices[(lenToPosState << 6) + GetPosSlot2(pos)] + _alignPrices[pos & 0xF]) : _distancesPrices[lenToPosState * 128 + pos]); return num + _lenEncoder.GetPrice(len - 2, posState); } private uint Backward(out uint backRes, uint cur) { _optimumEndIndex = cur; uint posPrev = _optimum[cur].PosPrev; uint backPrev = _optimum[cur].BackPrev; do { if (_optimum[cur].Prev1IsChar) { _optimum[posPrev].MakeAsChar(); _optimum[posPrev].PosPrev = posPrev - 1; if (_optimum[cur].Prev2) { _optimum[posPrev - 1].Prev1IsChar = false; _optimum[posPrev - 1].PosPrev = _optimum[cur].PosPrev2; _optimum[posPrev - 1].BackPrev = _optimum[cur].BackPrev2; } } uint num = posPrev; uint backPrev2 = backPrev; backPrev = _optimum[num].BackPrev; posPrev = _optimum[num].PosPrev; _optimum[num].BackPrev = backPrev2; _optimum[num].PosPrev = cur; cur = num; } while (cur != 0); backRes = _optimum[0].BackPrev; _optimumCurrentIndex = _optimum[0].PosPrev; return _optimumCurrentIndex; } private uint GetOptimum(uint position, out uint backRes) { if (_optimumEndIndex != _optimumCurrentIndex) { uint result = _optimum[_optimumCurrentIndex].PosPrev - _optimumCurrentIndex; backRes = _optimum[_optimumCurrentIndex].BackPrev; _optimumCurrentIndex = _optimum[_optimumCurrentIndex].PosPrev; return result; } _optimumCurrentIndex = (_optimumEndIndex = 0u); uint lenRes; uint numDistancePairs; if (!_longestMatchWasFound) { ReadMatchDistances(out lenRes, out numDistancePairs); } else { lenRes = _longestMatchLength; numDistancePairs = _numDistancePairs; _longestMatchWasFound = false; } uint num = _matchFinder.GetNumAvailableBytes() + 1; if (num < 2) { backRes = uint.MaxValue; return 1u; } if (num > 273) { num = 273u; } uint num2 = 0u; for (uint num3 = 0u; num3 < 4; num3++) { reps[num3] = _repDistances[num3]; repLens[num3] = _matchFinder.GetMatchLen(-1, reps[num3], 273u); if (repLens[num3] > repLens[num2]) { num2 = num3; } } if (repLens[num2] >= _numFastBytes) { backRes = num2; uint num4 = repLens[num2]; MovePos(num4 - 1); return num4; } if (lenRes >= _numFastBytes) { backRes = _matchDistances[numDistancePairs - 1] + 4; MovePos(lenRes - 1); return lenRes; } byte indexByte = _matchFinder.GetIndexByte(-1); byte indexByte2 = _matchFinder.GetIndexByte((int)(0 - _repDistances[0] - 1 - 1)); if (lenRes < 2 && indexByte != indexByte2 && repLens[num2] < 2) { backRes = uint.MaxValue; return 1u; } _optimum[0].State = _state; uint num5 = position & _posStateMask; _optimum[1].Price = _isMatch[(_state.Index << 4) + num5].GetPrice0() + _literalEncoder.GetSubCoder(position, _previousByte).GetPrice(!_state.IsCharState(), indexByte2, indexByte); _optimum[1].MakeAsChar(); uint price = _isMatch[(_state.Index << 4) + num5].GetPrice1(); uint num6 = price + _isRep[_state.Index].GetPrice1(); if (indexByte2 == indexByte) { uint num7 = num6 + GetRepLen1Price(_state, num5); if (num7 < _optimum[1].Price) { _optimum[1].Price = num7; _optimum[1].MakeAsShortRep(); } } uint num8 = ((lenRes >= repLens[num2]) ? lenRes : repLens[num2]); if (num8 < 2) { backRes = _optimum[1].BackPrev; return 1u; } _optimum[1].PosPrev = 0u; _optimum[0].Backs0 = reps[0]; _optimum[0].Backs1 = reps[1]; _optimum[0].Backs2 = reps[2]; _optimum[0].Backs3 = reps[3]; uint num9 = num8; do { _optimum[num9--].Price = 268435455u; } while (num9 >= 2); for (uint num3 = 0u; num3 < 4; num3++) { uint num10 = repLens[num3]; if (num10 < 2) { continue; } uint num11 = num6 + GetPureRepPrice(num3, _state, num5); do { uint num12 = num11 + _repMatchLenEncoder.GetPrice(num10 - 2, num5); Optimal optimal = _optimum[num10]; if (num12 < optimal.Price) { optimal.Price = num12; optimal.PosPrev = 0u; optimal.BackPrev = num3; optimal.Prev1IsChar = false; } } while (--num10 >= 2); } uint num13 = price + _isRep[_state.Index].GetPrice0(); num9 = ((repLens[0] >= 2) ? (repLens[0] + 1) : 2u); if (num9 <= lenRes) { uint num14; for (num14 = 0u; num9 > _matchDistances[num14]; num14 += 2) { } while (true) { uint num15 = _matchDistances[num14 + 1]; uint num16 = num13 + GetPosLenPrice(num15, num9, num5); Optimal optimal2 = _optimum[num9]; if (num16 < optimal2.Price) { optimal2.Price = num16; optimal2.PosPrev = 0u; optimal2.BackPrev = num15 + 4; optimal2.Prev1IsChar = false; } if (num9 == _matchDistances[num14]) { num14 += 2; if (num14 == numDistancePairs) { break; } } num9++; } } uint num17 = 0u; uint lenRes2; while (true) { num17++; if (num17 == num8) { return Backward(out backRes, num17); } ReadMatchDistances(out lenRes2, out numDistancePairs); if (lenRes2 >= _numFastBytes) { break; } position++; uint num18 = _optimum[num17].PosPrev; Base.State state; if (_optimum[num17].Prev1IsChar) { num18--; if (_optimum[num17].Prev2) { state = _optimum[_optimum[num17].PosPrev2].State; if (_optimum[num17].BackPrev2 < 4) { state.UpdateRep(); } else { state.UpdateMatch(); } } else { state = _optimum[num18].State; } state.UpdateChar(); } else { state = _optimum[num18].State; } if (num18 == num17 - 1) { if (_optimum[num17].IsShortRep()) { state.UpdateShortRep(); } else { state.UpdateChar(); } } else { uint num19; if (_optimum[num17].Prev1IsChar && _optimum[num17].Prev2) { num18 = _optimum[num17].PosPrev2; num19 = _optimum[num17].BackPrev2; state.UpdateRep(); } else { num19 = _optimum[num17].BackPrev; if (num19 < 4) { state.UpdateRep(); } else { state.UpdateMatch(); } } Optimal optimal3 = _optimum[num18]; switch (num19) { case 0u: reps[0] = optimal3.Backs0; reps[1] = optimal3.Backs1; reps[2] = optimal3.Backs2; reps[3] = optimal3.Backs3; break; case 1u: reps[0] = optimal3.Backs1; reps[1] = optimal3.Backs0; reps[2] = optimal3.Backs2; reps[3] = optimal3.Backs3; break; case 2u: reps[0] = optimal3.Backs2; reps[1] = optimal3.Backs0; reps[2] = optimal3.Backs1; reps[3] = optimal3.Backs3; break; case 3u: reps[0] = optimal3.Backs3; reps[1] = optimal3.Backs0; reps[2] = optimal3.Backs1; reps[3] = optimal3.Backs2; break; default: reps[0] = num19 - 4; reps[1] = optimal3.Backs0; reps[2] = optimal3.Backs1; reps[3] = optimal3.Backs2; break; } } _optimum[num17].State = state; _optimum[num17].Backs0 = reps[0]; _optimum[num17].Backs1 = reps[1]; _optimum[num17].Backs2 = reps[2]; _optimum[num17].Backs3 = reps[3]; uint price2 = _optimum[num17].Price; indexByte = _matchFinder.GetIndexByte(-1); indexByte2 = _matchFinder.GetIndexByte((int)(0 - reps[0] - 1 - 1)); num5 = position & _posStateMask; uint num20 = price2 + _isMatch[(state.Index << 4) + num5].GetPrice0() + _literalEncoder.GetSubCoder(position, _matchFinder.GetIndexByte(-2)).GetPrice(!state.IsCharState(), indexByte2, indexByte); Optimal optimal4 = _optimum[num17 + 1]; bool flag = false; if (num20 < optimal4.Price) { optimal4.Price = num20; optimal4.PosPrev = num17; optimal4.MakeAsChar(); flag = true; } price = price2 + _isMatch[(state.Index << 4) + num5].GetPrice1(); num6 = price + _isRep[state.Index].GetPrice1(); if (indexByte2 == indexByte && (optimal4.PosPrev >= num17 || optimal4.BackPrev != 0)) { uint num21 = num6 + GetRepLen1Price(state, num5); if (num21 <= optimal4.Price) { optimal4.Price = num21; optimal4.PosPrev = num17; optimal4.MakeAsShortRep(); flag = true; } } uint val = _matchFinder.GetNumAvailableBytes() + 1; val = Math.Min(4095 - num17, val); num = val; if (num < 2) { continue; } if (num > _numFastBytes) { num = _numFastBytes; } if (!flag && indexByte2 != indexByte) { uint limit = Math.Min(val - 1, _numFastBytes); uint matchLen = _matchFinder.GetMatchLen(0, reps[0], limit); if (matchLen >= 2) { Base.State state2 = state; state2.UpdateChar(); uint num22 = (position + 1) & _posStateMask; uint num23 = num20 + _isMatch[(state2.Index << 4) + num22].GetPrice1() + _isRep[state2.Index].GetPrice1(); uint num24 = num17 + 1 + matchLen; while (num8 < num24) { _optimum[++num8].Price = 268435455u; } uint num25 = num23 + GetRepPrice(0u, matchLen, state2, num22); Optimal optimal5 = _optimum[num24]; if (num25 < optimal5.Price) { optimal5.Price = num25; optimal5.PosPrev = num17 + 1; optimal5.BackPrev = 0u; optimal5.Prev1IsChar = true; optimal5.Prev2 = false; } } } uint num26 = 2u; for (uint num27 = 0u; num27 < 4; num27++) { uint num28 = _matchFinder.GetMatchLen(-1, reps[num27], num); if (num28 < 2) { continue; } uint num29 = num28; while (true) { if (num8 < num17 + num28) { _optimum[++num8].Price = 268435455u; continue; } uint num30 = num6 + GetRepPrice(num27, num28, state, num5); Optimal optimal6 = _optimum[num17 + num28]; if (num30 < optimal6.Price) { optimal6.Price = num30; optimal6.PosPrev = num17; optimal6.BackPrev = num27; optimal6.Prev1IsChar = false; } if (--num28 < 2) { break; } } num28 = num29; if (num27 == 0) { num26 = num28 + 1; } if (num28 >= val) { continue; } uint limit2 = Math.Min(val - 1 - num28, _numFastBytes); uint matchLen2 = _matchFinder.GetMatchLen((int)num28, reps[num27], limit2); if (matchLen2 >= 2) { Base.State state3 = state; state3.UpdateRep(); uint num31 = (position + num28) & _posStateMask; uint num32 = num6 + GetRepPrice(num27, num28, state, num5) + _isMatch[(state3.Index << 4) + num31].GetPrice0() + _literalEncoder.GetSubCoder(position + num28, _matchFinder.GetIndexByte((int)(num28 - 1 - 1))).GetPrice(matchMode: true, _matchFinder.GetIndexByte((int)(num28 - 1 - (reps[num27] + 1))), _matchFinder.GetIndexByte((int)(num28 - 1))); state3.UpdateChar(); num31 = (position + num28 + 1) & _posStateMask; uint num33 = num32 + _isMatch[(state3.Index << 4) + num31].GetPrice1() + _isRep[state3.Index].GetPrice1(); uint num34 = num28 + 1 + matchLen2; while (num8 < num17 + num34) { _optimum[++num8].Price = 268435455u; } uint num35 = num33 + GetRepPrice(0u, matchLen2, state3, num31); Optimal optimal7 = _optimum[num17 + num34]; if (num35 < optimal7.Price) { optimal7.Price = num35; optimal7.PosPrev = num17 + num28 + 1; optimal7.BackPrev = 0u; optimal7.Prev1IsChar = true; optimal7.Prev2 = true; optimal7.PosPrev2 = num17; optimal7.BackPrev2 = num27; } } } if (lenRes2 > num) { lenRes2 = num; for (numDistancePairs = 0u; lenRes2 > _matchDistances[numDistancePairs]; numDistancePairs += 2) { } _matchDistances[numDistancePairs] = lenRes2; numDistancePairs += 2; } if (lenRes2 < num26) { continue; } num13 = price + _isRep[state.Index].GetPrice0(); while (num8 < num17 + lenRes2) { _optimum[++num8].Price = 268435455u; } uint num36; for (num36 = 0u; num26 > _matchDistances[num36]; num36 += 2) { } uint num37 = num26; while (true) { uint num38 = _matchDistances[num36 + 1]; uint num39 = num13 + GetPosLenPrice(num38, num37, num5); Optimal optimal8 = _optimum[num17 + num37]; if (num39 < optimal8.Price) { optimal8.Price = num39; optimal8.PosPrev = num17; optimal8.BackPrev = num38 + 4; optimal8.Prev1IsChar = false; } if (num37 == _matchDistances[num36]) { if (num37 < val) { uint limit3 = Math.Min(val - 1 - num37, _numFastBytes); uint matchLen3 = _matchFinder.GetMatchLen((int)num37, num38, limit3); if (matchLen3 >= 2) { Base.State state4 = state; state4.UpdateMatch(); uint num40 = (position + num37) & _posStateMask; uint num41 = num39 + _isMatch[(state4.Index << 4) + num40].GetPrice0() + _literalEncoder.GetSubCoder(position + num37, _matchFinder.GetIndexByte((int)(num37 - 1 - 1))).GetPrice(matchMode: true, _matchFinder.GetIndexByte((int)(num37 - (num38 + 1) - 1)), _matchFinder.GetIndexByte((int)(num37 - 1))); state4.UpdateChar(); num40 = (position + num37 + 1) & _posStateMask; uint num42 = num41 + _isMatch[(state4.Index << 4) + num40].GetPrice1() + _isRep[state4.Index].GetPrice1(); uint num43 = num37 + 1 + matchLen3; while (num8 < num17 + num43) { _optimum[++num8].Price = 268435455u; } num39 = num42 + GetRepPrice(0u, matchLen3, state4, num40); optimal8 = _optimum[num17 + num43]; if (num39 < optimal8.Price) { optimal8.Price = num39; optimal8.PosPrev = num17 + num37 + 1; optimal8.BackPrev = 0u; optimal8.Prev1IsChar = true; optimal8.Prev2 = true; optimal8.PosPrev2 = num17; optimal8.BackPrev2 = num38 + 4; } } } num36 += 2; if (num36 == numDistancePairs) { break; } } num37++; } } _numDistancePairs = numDistancePairs; _longestMatchLength = lenRes2; _longestMatchWasFound = true; return Backward(out backRes, num17); } private bool ChangePair(uint smallDist, uint bigDist) { if (smallDist < 33554432) { return bigDist >= smallDist << 7; } return false; } private void WriteEndMarker(uint posState) { if (_writeEndMark) { _isMatch[(_state.Index << 4) + posState].Encode(_rangeEncoder, 1u); _isRep[_state.Index].Encode(_rangeEncoder, 0u); _state.UpdateMatch(); uint num = 2u; _lenEncoder.Encode(_rangeEncoder, num - 2, posState); uint symbol = 63u; uint lenToPosState = Base.GetLenToPosState(num); _posSlotEncoder[lenToPosState].Encode(_rangeEncoder, symbol); int num2 = 30; uint num3 = (uint)((1 << num2) - 1); _rangeEncoder.EncodeDirectBits(num3 >> 4, num2 - 4); _posAlignEncoder.ReverseEncode(_rangeEncoder, num3 & 0xF); } } private void Flush(uint nowPos) { ReleaseMFStream(); WriteEndMarker(nowPos & _posStateMask); _rangeEncoder.FlushData(); _rangeEncoder.FlushStream(); } public void CodeOneBlock(out long inSize, out long outSize, out bool finished) { inSize = 0L; outSize = 0L; finished = true; if (_inStream != null) { _matchFinder.SetStream(_inStream); _matchFinder.Init(); _needReleaseMFStream = true; _inStream = null; if (_trainSize != 0) { _matchFinder.Skip(_trainSize); } } if (_finished) { return; } _finished = true; long num = nowPos64; if (nowPos64 == 0L) { if (_matchFinder.GetNumAvailableBytes() == 0) { Flush((uint)nowPos64); return; } ReadMatchDistances(out var _, out var _); uint num2 = (uint)(int)nowPos64 & _posStateMask; _isMatch[(_state.Index << 4) + num2].Encode(_rangeEncoder, 0u); _state.UpdateChar(); byte indexByte = _matchFinder.GetIndexByte((int)(0 - _additionalOffset)); _literalEncoder.GetSubCoder((uint)nowPos64, _previousByte).Encode(_rangeEncoder, indexByte); _previousByte = indexByte; _additionalOffset--; nowPos64++; } if (_matchFinder.GetNumAvailableBytes() == 0) { Flush((uint)nowPos64); return; } while (true) { uint backRes; uint optimum = GetOptimum((uint)nowPos64, out backRes); uint num3 = (uint)(int)nowPos64 & _posStateMask; uint num4 = (_state.Index << 4) + num3; if (optimum == 1 && backRes == uint.MaxValue) { _isMatch[num4].Encode(_rangeEncoder, 0u); byte indexByte2 = _matchFinder.GetIndexByte((int)(0 - _additionalOffset)); LiteralEncoder.Encoder2 subCoder = _literalEncoder.GetSubCoder((uint)nowPos64, _previousByte); if (!_state.IsCharState()) { byte indexByte3 = _matchFinder.GetIndexByte((int)(0 - _repDistances[0] - 1 - _additionalOffset)); subCoder.EncodeMatched(_rangeEncoder, indexByte3, indexByte2); } else { subCoder.Encode(_rangeEncoder, indexByte2); } _previousByte = indexByte2; _state.UpdateChar(); } else { _isMatch[num4].Encode(_rangeEncoder, 1u); if (backRes < 4) { _isRep[_state.Index].Encode(_rangeEncoder, 1u); if (backRes == 0) { _isRepG0[_state.Index].Encode(_rangeEncoder, 0u); if (optimum == 1) { _isRep0Long[num4].Encode(_rangeEncoder, 0u); } else { _isRep0Long[num4].Encode(_rangeEncoder, 1u); } } else { _isRepG0[_state.Index].Encode(_rangeEncoder, 1u); if (backRes == 1) { _isRepG1[_state.Index].Encode(_rangeEncoder, 0u); } else { _isRepG1[_state.Index].Encode(_rangeEncoder, 1u); _isRepG2[_state.Index].Encode(_rangeEncoder, backRes - 2); } } if (optimum == 1) { _state.UpdateShortRep(); } else { _repMatchLenEncoder.Encode(_rangeEncoder, optimum - 2, num3); _state.UpdateRep(); } uint num5 = _repDistances[backRes]; if (backRes != 0) { for (uint num6 = backRes; num6 >= 1; num6--) { _repDistances[num6] = _repDistances[num6 - 1]; } _repDistances[0] = num5; } } else { _isRep[_state.Index].Encode(_rangeEncoder, 0u); _state.UpdateMatch(); _lenEncoder.Encode(_rangeEncoder, optimum - 2, num3); backRes -= 4; uint posSlot = GetPosSlot(backRes); uint lenToPosState = Base.GetLenToPosState(optimum); _posSlotEncoder[lenToPosState].Encode(_rangeEncoder, posSlot); if (posSlot >= 4) { int num7 = (int)((posSlot >> 1) - 1); uint num8 = (2 | (posSlot & 1)) << num7; uint num9 = backRes - num8; if (posSlot < 14) { BitTreeEncoder.ReverseEncode(_posEncoders, num8 - posSlot - 1, _rangeEncoder, num7, num9); } else { _rangeEncoder.EncodeDirectBits(num9 >> 4, num7 - 4); _posAlignEncoder.ReverseEncode(_rangeEncoder, num9 & 0xF); _alignPriceCount++; } } uint num10 = backRes; for (uint num11 = 3u; num11 >= 1; num11--) { _repDistances[num11] = _repDistances[num11 - 1]; } _repDistances[0] = num10; _matchPriceCount++; } _previousByte = _matchFinder.GetIndexByte((int)(optimum - 1 - _additionalOffset)); } _additionalOffset -= optimum; nowPos64 += optimum; if (_additionalOffset == 0) { if (_matchPriceCount >= 128) { FillDistancesPrices(); } if (_alignPriceCount >= 16) { FillAlignPrices(); } inSize = nowPos64; outSize = _rangeEncoder.GetProcessedSizeAdd(); if (_matchFinder.GetNumAvailableBytes() == 0) { Flush((uint)nowPos64); return; } if (nowPos64 - num >= 4096) { break; } } } _finished = false; finished = false; } private void ReleaseMFStream() { if (_matchFinder != null && _needReleaseMFStream) { _matchFinder.ReleaseStream(); _needReleaseMFStream = false; } } private void SetOutStream(Stream outStream) { _rangeEncoder.SetStream(outStream); } private void ReleaseOutStream() { _rangeEncoder.ReleaseStream(); } private void ReleaseStreams() { ReleaseMFStream(); ReleaseOutStream(); } private void SetStreams(Stream inStream, Stream outStream, long inSize, long outSize) { _inStream = inStream; _finished = false; Create(); SetOutStream(outStream); Init(); FillDistancesPrices(); FillAlignPrices(); _lenEncoder.SetTableSize(_numFastBytes + 1 - 2); _lenEncoder.UpdateTables((uint)(1 << _posStateBits)); _repMatchLenEncoder.SetTableSize(_numFastBytes + 1 - 2); _repMatchLenEncoder.UpdateTables((uint)(1 << _posStateBits)); nowPos64 = 0L; } public void Code(Stream inStream, Stream outStream, long inSize, long outSize, ICodeProgress progress) { _needReleaseMFStream = false; try { SetStreams(inStream, outStream, inSize, outSize); while (true) { CodeOneBlock(out var inSize2, out var outSize2, out var finished); if (finished) { break; } progress?.SetProgress(inSize2, outSize2); } } finally { ReleaseStreams(); } } public void WriteCoderProperties(Stream outStream) { properties[0] = (byte)((_posStateBits * 5 + _numLiteralPosStateBits) * 9 + _numLiteralContextBits); for (int i = 0; i < 4; i++) { properties[1 + i] = (byte)((_dictionarySize >> 8 * i) & 0xFF); } outStream.Write(properties, 0, 5); } private void FillDistancesPrices() { for (uint num = 4u; num < 128; num++) { uint posSlot = GetPosSlot(num); int num2 = (int)((posSlot >> 1) - 1); uint num3 = (2 | (posSlot & 1)) << num2; tempPrices[num] = BitTreeEncoder.ReverseGetPrice(_posEncoders, num3 - posSlot - 1, num2, num - num3); } for (uint num4 = 0u; num4 < 4; num4++) { BitTreeEncoder bitTreeEncoder = _posSlotEncoder[num4]; uint num5 = num4 << 6; for (uint num6 = 0u; num6 < _distTableSize; num6++) { _posSlotPrices[num5 + num6] = bitTreeEncoder.GetPrice(num6); } for (uint num6 = 14u; num6 < _distTableSize; num6++) { _posSlotPrices[num5 + num6] += (num6 >> 1) - 1 - 4 << 6; } uint num7 = num4 * 128; uint num8; for (num8 = 0u; num8 < 4; num8++) { _distancesPrices[num7 + num8] = _posSlotPrices[num5 + num8]; } for (; num8 < 128; num8++) { _distancesPrices[num7 + num8] = _posSlotPrices[num5 + GetPosSlot(num8)] + tempPrices[num8]; } } _matchPriceCount = 0u; } private void FillAlignPrices() { for (uint num = 0u; num < 16; num++) { _alignPrices[num] = _posAlignEncoder.ReverseGetPrice(num); } _alignPriceCount = 0u; } private static int FindMatchFinder(string s) { for (int i = 0; i < kMatchFinderIDs.Length; i++) { if (s == kMatchFinderIDs[i]) { return i; } } return -1; } public void SetCoderProperties(CoderPropID[] propIDs, object[] properties) { for (uint num = 0u; num < properties.Length; num++) { object obj = properties[num]; switch (propIDs[num]) { case CoderPropID.NumFastBytes: if (!(obj is int num2)) { throw new InvalidParamException(); } if (num2 < 5 || (long)num2 > 273L) { throw new InvalidParamException(); } _numFastBytes = (uint)num2; break; case CoderPropID.MatchFinder: { if (!(obj is string)) { throw new InvalidParamException(); } EMatchFinderType matchFinderType = _matchFinderType; int num6 = FindMatchFinder(((string)obj).ToUpper()); if (num6 < 0) { throw new InvalidParamException(); } _matchFinderType = (EMatchFinderType)num6; if (_matchFinder != null && matchFinderType != _matchFinderType) { _dictionarySizePrev = uint.MaxValue; _matchFinder = null; } break; } case CoderPropID.DictionarySize: { if (!(obj is int num7)) { throw new InvalidParamException(); } if ((long)num7 < 1L || (long)num7 > 1073741824L) { throw new InvalidParamException(); } _dictionarySize = (uint)num7; int i; for (i = 0; (long)i < 30L && num7 > (uint)(1 << i); i++) { } _distTableSize = (uint)(i * 2); break; } case CoderPropID.PosStateBits: if (!(obj is int num3)) { throw new InvalidParamException(); } if (num3 < 0 || (long)num3 > 4L) { throw new InvalidParamException(); } _posStateBits = num3; _posStateMask = (uint)((1 << _posStateBits) - 1); break; case CoderPropID.LitPosBits: if (!(obj is int num5)) { throw new InvalidParamException(); } if (num5 < 0 || (long)num5 > 4L) { throw new InvalidParamException(); } _numLiteralPosStateBits = num5; break; case CoderPropID.LitContextBits: if (!(obj is int num4)) { throw new InvalidParamException(); } if (num4 < 0 || (long)num4 > 8L) { throw new InvalidParamException(); } _numLiteralContextBits = num4; break; case CoderPropID.EndMarker: if (!(obj is bool)) { throw new InvalidParamException(); } SetWriteEndMarkerMode((bool)obj); break; default: throw new InvalidParamException(); case CoderPropID.Algorithm: break; } } } public void SetTrainSize(uint trainSize) { _trainSize = trainSize; } } public static class SevenZipHelper { private static CoderPropID[] propIDs = new CoderPropID[8] { CoderPropID.DictionarySize, CoderPropID.PosStateBits, CoderPropID.LitContextBits, CoderPropID.LitPosBits, CoderPropID.Algorithm, CoderPropID.NumFastBytes, CoderPropID.MatchFinder, CoderPropID.EndMarker }; private static object[] properties = new object[8] { 2097152, 2, 3, 0, 2, 32, "bt4", false }; public static byte[] Compress(byte[] inputBytes, ICodeProgress progress = null) { MemoryStream inStream = new MemoryStream(inputBytes); MemoryStream memoryStream = new MemoryStream(); Compress(inStream, memoryStream, progress); return memoryStream.ToArray(); } public static void Compress(Stream inStream, Stream outStream, ICodeProgress progress = null) { Encoder encoder = new Encoder(); encoder.SetCoderProperties(propIDs, properties); encoder.WriteCoderProperties(outStream); encoder.Code(inStream, outStream, -1L, -1L, progress); } public static byte[] Decompress(byte[] inputBytes) { MemoryStream memoryStream = new MemoryStream(inputBytes); Decoder decoder = new Decoder(); memoryStream.Seek(0L, SeekOrigin.Begin); MemoryStream memoryStream2 = new MemoryStream(); byte[] array = new byte[5]; if (memoryStream.Read(array, 0, 5) != 5) { throw new Exception("input .lzma is too short"); } long num = 0L; for (int i = 0; i < 8; i++) { int num2 = memoryStream.ReadByte(); if (num2 < 0) { throw new Exception("Can't Read 1"); } num |= (long)((ulong)(byte)num2 << 8 * i); } decoder.SetDecoderProperties(array); long inSize = memoryStream.Length - memoryStream.Position; decoder.Code(memoryStream, memoryStream2, inSize, num, null); return memoryStream2.ToArray(); } public static MemoryStream StreamDecompress(MemoryStream newInStream) { Decoder decoder = new Decoder(); newInStream.Seek(0L, SeekOrigin.Begin); MemoryStream memoryStream = new MemoryStream(); byte[] array = new byte[5]; if (newInStream.Read(array, 0, 5) != 5) { throw new Exception("input .lzma is too short"); } long num = 0L; for (int i = 0; i < 8; i++) { int num2 = newInStream.ReadByte(); if (num2 < 0) { throw new Exception("Can't Read 1"); } num |= (long)((ulong)(byte)num2 << 8 * i); } decoder.SetDecoderProperties(array); long inSize = newInStream.Length - newInStream.Position; decoder.Code(newInStream, memoryStream, inSize, num, null); memoryStream.Position = 0L; return memoryStream; } public static MemoryStream StreamDecompress(MemoryStream newInStream, long outSize) { Decoder decoder = new Decoder(); newInStream.Seek(0L, SeekOrigin.Begin); MemoryStream memoryStream = new MemoryStream(); byte[] array = new byte[5]; if (newInStream.Read(array, 0, 5) != 5) { throw new Exception("input .lzma is too short"); } decoder.SetDecoderProperties(array); long inSize = newInStream.Length - newInStream.Position; decoder.Code(newInStream, memoryStream, inSize, outSize, null); memoryStream.Position = 0L; return memoryStream; } public static void StreamDecompress(Stream compressedStream, Stream decompressedStream, long compressedSize, long decompressedSize) { long position = compressedStream.Position; Decoder decoder = new Decoder(); byte[] array = new byte[5]; if (compressedStream.Read(array, 0, 5) != 5) { throw new Exception("input .lzma is too short"); } decoder.SetDecoderProperties(array); decoder.Code(compressedStream, decompressedStream, compressedSize - 5, decompressedSize, null); compressedStream.Position = position + compressedSize; } } } namespace SevenZip.Buffer { public class InBuffer { private byte[] m_Buffer; private uint m_Pos; private uint m_Limit; private uint m_BufferSize; private Stream m_Stream; private bool m_StreamWasExhausted; private ulong m_ProcessedSize; public InBuffer(uint bufferSize) { m_Buffer = new byte[bufferSize]; m_BufferSize = bufferSize; } public void Init(Stream stream) { m_Stream = stream; m_ProcessedSize = 0uL; m_Limit = 0u; m_Pos = 0u; m_StreamWasExhausted = false; } public bool ReadBlock() { if (m_StreamWasExhausted) { return false; } m_ProcessedSize += m_Pos; int num = m_Stream.Read(m_Buffer, 0, (int)m_BufferSize); m_Pos = 0u; m_Limit = (uint)num; m_StreamWasExhausted = num == 0; return !m_StreamWasExhausted; } public void ReleaseStream() { m_Stream = null; } public bool ReadByte(byte b) { if (m_Pos >= m_Limit && !ReadBlock()) { return false; } b = m_Buffer[m_Pos++]; return true; } public byte ReadByte() { if (m_Pos >= m_Limit && !ReadBlock()) { return byte.MaxValue; } return m_Buffer[m_Pos++]; } public ulong GetProcessedSize() { return m_ProcessedSize + m_Pos; } } public class OutBuffer { private byte[] m_Buffer; private uint m_Pos; private uint m_BufferSize; private Stream m_Stream; private ulong m_ProcessedSize; public OutBuffer(uint bufferSize) { m_Buffer = new byte[bufferSize]; m_BufferSize = bufferSize; } public void SetStream(Stream stream) { m_Stream = stream; } public void FlushStream() { m_Stream.Flush(); } public void CloseStream() { m_Stream.Close(); } public void ReleaseStream() { m_Stream = null; } public void Init() { m_ProcessedSize = 0uL; m_Pos = 0u; } public void WriteByte(byte b) { m_Buffer[m_Pos++] = b; if (m_Pos >= m_BufferSize) { FlushData(); } } public void FlushData() { if (m_Pos != 0) { m_Stream.Write(m_Buffer, 0, (int)m_Pos); m_Pos = 0u; } } public ulong GetProcessedSize() { return m_ProcessedSize + m_Pos; } } } namespace SevenZip.CommandLineParser { public enum SwitchType { Simple, PostMinus, LimitedPostString, UnLimitedPostString, PostChar } public class SwitchForm { public string IDString; public SwitchType Type; public bool Multi; public int MinLen; public int MaxLen; public string PostCharSet; public SwitchForm(string idString, SwitchType type, bool multi, int minLen, int maxLen, string postCharSet) { IDString = idString; Type = type; Multi = multi; MinLen = minLen; MaxLen = maxLen; PostCharSet = postCharSet; } public SwitchForm(string idString, SwitchType type, bool multi, int minLen) : this(idString, type, multi, minLen, 0, "") { } public SwitchForm(string idString, SwitchType type, bool multi) : this(idString, type, multi, 0) { } } public class SwitchResult { public bool ThereIs; public bool WithMinus; public ArrayList PostStrings = new ArrayList(); public int PostCharIndex; public SwitchResult() { ThereIs = false; } } public class Parser { public ArrayList NonSwitchStrings = new ArrayList(); private SwitchResult[] _switches; private const char kSwitchID1 = '-'; private const char kSwitchID2 = '/'; private const char kSwitchMinus = '-'; private const string kStopSwitchParsing = "--"; public SwitchResult this[int index] => _switches[index]; public Parser(int numSwitches) { _switches = new SwitchResult[numSwitches]; for (int i = 0; i < numSwitches; i++) { _switches[i] = new SwitchResult(); } } private bool ParseString(string srcString, SwitchForm[] switchForms) { int length = srcString.Length; if (length == 0) { return false; } int num = 0; if (!IsItSwitchChar(srcString[num])) { return false; } while (num < length) { if (IsItSwitchChar(srcString[num])) { num++; } int num2 = 0; int num3 = -1; for (int i = 0; i < _switches.Length; i++) { int length2 = switchForms[i].IDString.Length; if (length2 > num3 && num + length2 <= length && string.Compare(switchForms[i].IDString, 0, srcString, num, length2, ignoreCase: true) == 0) { num2 = i; num3 = length2; } } if (num3 == -1) { throw new Exception("maxLen == kNoLen"); } SwitchResult switchResult = _switches[num2]; SwitchForm switchForm = switchForms[num2]; if (!switchForm.Multi && switchResult.ThereIs) { throw new Exception("switch must be single"); } switchResult.ThereIs = true; num += num3; int num4 = length - num; SwitchType type = switchForm.Type; switch (type) { case SwitchType.PostMinus: if (num4 == 0) { switchResult.WithMinus = false; break; } switchResult.WithMinus = srcString[num] == '-'; if (switchResult.WithMinus) { num++; } break; case SwitchType.PostChar: { if (num4 < switchForm.MinLen) { throw new Exception("switch is not full"); } string postCharSet = switchForm.PostCharSet; if (num4 == 0) { switchResult.PostCharIndex = -1; break; } int num6 = postCharSet.IndexOf(srcString[num]); if (num6 < 0) { switchResult.PostCharIndex = -1; break; } switchResult.PostCharIndex = num6; num++; break; } case SwitchType.LimitedPostString: case SwitchType.UnLimitedPostString: { int minLen = switchForm.MinLen; if (num4 < minLen) { throw new Exception("switch is not full"); } if (type == SwitchType.UnLimitedPostString) { switchResult.PostStrings.Add(srcString.Substring(num)); return true; } string text = srcString.Substring(num, minLen); num += minLen; int num5 = minLen; while (num5 < switchForm.MaxLen && num < length) { char c = srcString[num]; if (IsItSwitchChar(c)) { break; } text += c; num5++; num++; } switchResult.PostStrings.Add(text); break; } } } return true; } public void ParseStrings(SwitchForm[] switchForms, string[] commandStrings) { int num = commandStrings.Length; bool flag = false; for (int i = 0; i < num; i++) { string text = commandStrings[i]; if (flag) { NonSwitchStrings.Add(text); } else if (text == "--") { flag = true; } else if (!ParseString(text, switchForms)) { NonSwitchStrings.Add(text); } } } public static int ParseCommand(CommandForm[] commandForms, string commandString, out string postString) { for (int i = 0; i < commandForms.Length; i++) { string iDString = commandForms[i].IDString; if (commandForms[i].PostStringMode) { if (commandString.IndexOf(iDString) == 0) { postString = commandString.Substring(iDString.Length); return i; } } else if (commandString == iDString) { postString = ""; return i; } } postString = ""; return -1; } private static bool ParseSubCharsCommand(int numForms, CommandSubCharsSet[] forms, string commandString, ArrayList indices) { indices.Clear(); int num = 0; for (int i = 0; i < numForms; i++) { CommandSubCharsSet commandSubCharsSet = forms[i]; int num2 = -1; int length = commandSubCharsSet.Chars.Length; for (int j = 0; j < length; j++) { char value = commandSubCharsSet.Chars[j]; int num3 = commandString.IndexOf(value); if (num3 >= 0) { if (num2 >= 0) { return false; } if (commandString.IndexOf(value, num3 + 1) >= 0) { return false; } num2 = j; num++; } } if (num2 == -1 && !commandSubCharsSet.EmptyAllowed) { return false; } indices.Add(num2); } return num == commandString.Length; } private static bool IsItSwitchChar(char c) { if (c != '-') { return c == '/'; } return true; } } public class CommandForm { public string IDString = ""; public bool PostStringMode; public CommandForm(string idString, bool postStringMode) { IDString = idString; PostStringMode = postStringMode; } } internal class CommandSubCharsSet { public string Chars = ""; public bool EmptyAllowed; } } namespace LZ4ps { public static class LZ4Codec { private class LZ4HC_Data_Structure { public byte[] src; public int src_base; public int src_end; public int src_LASTLITERALS; public byte[] dst; public int dst_base; public int dst_len; public int dst_end; public int[] hashTable; public ushort[] chainTable; public int nextToUpdate; } private const int MEMORY_USAGE = 14; private const int NOTCOMPRESSIBLE_DETECTIONLEVEL = 6; private const int BLOCK_COPY_LIMIT = 16; private const int MINMATCH = 4; private const int SKIPSTRENGTH = 6; private const int COPYLENGTH = 8; private const int LASTLITERALS = 5; private const int MFLIMIT = 12; private const int MINLENGTH = 13; private const int MAXD_LOG = 16; private const int MAXD = 65536; private const int MAXD_MASK = 65535; private const int MAX_DISTANCE = 65535; private const int ML_BITS = 4; private const int ML_MASK = 15; private const int RUN_BITS = 4; private const int RUN_MASK = 15; private const int STEPSIZE_64 = 8; private const int STEPSIZE_32 = 4; private const int LZ4_64KLIMIT = 65547; private const int HASH_LOG = 12; private const int HASH_TABLESIZE = 4096; private const int HASH_ADJUST = 20; private const int HASH64K_LOG = 13; private const int HASH64K_TABLESIZE = 8192; private const int HASH64K_ADJUST = 19; private const int HASHHC_LOG = 15; private const int HASHHC_TABLESIZE = 32768; private const int HASHHC_ADJUST = 17; private static readonly int[] DECODER_TABLE_32 = new int[8] { 0, 3, 2, 3, 0, 0, 0, 0 }; private static readonly int[] DECODER_TABLE_64 = new int[8] { 0, 0, 0, -1, 0, 1, 2, 3 }; private static readonly int[] DEBRUIJN_TABLE_32 = new int[32] { 0, 0, 3, 0, 3, 1, 3, 0, 3, 2, 2, 1, 3, 2, 0, 1, 3, 3, 1, 2, 2, 2, 2, 0, 3, 1, 2, 0, 1, 0, 1, 1 }; private static readonly int[] DEBRUIJN_TABLE_64 = new int[64] { 0, 0, 0, 0, 0, 1, 1, 2, 0, 3, 1, 3, 1, 4, 2, 7, 0, 2, 3, 6, 1, 5, 3, 5, 1, 3, 4, 4, 2, 5, 6, 7, 7, 0, 1, 2, 3, 3, 4, 6, 2, 6, 5, 5, 3, 4, 5, 6, 7, 1, 2, 4, 6, 4, 4, 5, 7, 2, 6, 5, 7, 6, 7, 7 }; private const int MAX_NB_ATTEMPTS = 256; private const int OPTIMAL_ML = 18; public static int MaximumOutputLength(int inputLength) { return inputLength + inputLength / 255 + 16; } internal static void CheckArguments(byte[] input, int inputOffset, ref int inputLength, byte[] output, int outputOffset, ref int outputLength) { if (inputLength < 0) { inputLength = input.Length - inputOffset; } if (inputLength == 0) { outputLength = 0; return; } if (input == null) { throw new ArgumentNullException("input"); } if (inputOffset < 0 || inputOffset + inputLength > input.Length) { throw new ArgumentException("inputOffset and inputLength are invalid for given input"); } if (outputLength < 0) { outputLength = output.Length - outputOffset; } if (output == null) { throw new ArgumentNullException("output"); } if (outputOffset >= 0 && outputOffset + outputLength <= output.Length) { return; } throw new ArgumentException("outputOffset and outputLength are invalid for given output"); } [Conditional("DEBUG")] private static void Assert(bool condition, string errorMessage) { if (!condition) { throw new ArgumentException(errorMessage); } } internal static void Poke2(byte[] buffer, int offset, ushort value) { buffer[offset] = (byte)value; buffer[offset + 1] = (byte)(value >> 8); } internal static ushort Peek2(byte[] buffer, int offset) { return (ushort)(buffer[offset] | (buffer[offset + 1] << 8)); } internal static uint Peek4(byte[] buffer, int offset) { return (uint)(buffer[offset] | (buffer[offset + 1] << 8) | (buffer[offset + 2] << 16) | (buffer[offset + 3] << 24)); } private static uint Xor4(byte[] buffer, int offset1, int offset2) { int num = buffer[offset1] | (buffer[offset1 + 1] << 8) | (buffer[offset1 + 2] << 16) | (buffer[offset1 + 3] << 24); uint num2 = (uint)(buffer[offset2] | (buffer[offset2 + 1] << 8) | (buffer[offset2 + 2] << 16) | (buffer[offset2 + 3] << 24)); return (uint)num ^ num2; } private static ulong Xor8(byte[] buffer, int offset1, int offset2) { ulong num = buffer[offset1] | ((ulong)buffer[offset1 + 1] << 8) | ((ulong)buffer[offset1 + 2] << 16) | ((ulong)buffer[offset1 + 3] << 24) | ((ulong)buffer[offset1 + 4] << 32) | ((ulong)buffer[offset1 + 5] << 40) | ((ulong)buffer[offset1 + 6] << 48) | ((ulong)buffer[offset1 + 7] << 56); ulong num2 = buffer[offset2] | ((ulong)buffer[offset2 + 1] << 8) | ((ulong)buffer[offset2 + 2] << 16) | ((ulong)buffer[offset2 + 3] << 24) | ((ulong)buffer[offset2 + 4] << 32) | ((ulong)buffer[offset2 + 5] << 40) | ((ulong)buffer[offset2 + 6] << 48) | ((ulong)buffer[offset2 + 7] << 56); return num ^ num2; } private static bool Equal2(byte[] buffer, int offset1, int offset2) { if (buffer[offset1] != buffer[offset2]) { return false; } return buffer[offset1 + 1] == buffer[offset2 + 1]; } private static bool Equal4(byte[] buffer, int offset1, int offset2) { if (buffer[offset1] != buffer[offset2]) { return false; } if (buffer[offset1 + 1] != buffer[offset2 + 1]) { return false; } if (buffer[offset1 + 2] != buffer[offset2 + 2]) { return false; } return buffer[offset1 + 3] == buffer[offset2 + 3]; } private static void Copy4(byte[] buf, int src, int dst) { buf[dst + 3] = buf[src + 3]; buf[dst + 2] = buf[src + 2]; buf[dst + 1] = buf[src + 1]; buf[dst] = buf[src]; } private static void Copy8(byte[] buf, int src, int dst) { buf[dst + 7] = buf[src + 7]; buf[dst + 6] = buf[src + 6]; buf[dst + 5] = buf[src + 5]; buf[dst + 4] = buf[src + 4]; buf[dst + 3] = buf[src + 3]; buf[dst + 2] = buf[src + 2]; buf[dst + 1] = buf[src + 1]; buf[dst] = buf[src]; } private static void BlockCopy(byte[] src, int src_0, byte[] dst, int dst_0, int len) { if (len >= 16) { Buffer.BlockCopy(src, src_0, dst, dst_0, len); return; } while (len >= 8) { dst[dst_0] = src[src_0]; dst[dst_0 + 1] = src[src_0 + 1]; dst[dst_0 + 2] = src[src_0 + 2]; dst[dst_0 + 3] = src[src_0 + 3]; dst[dst_0 + 4] = src[src_0 + 4]; dst[dst_0 + 5] = src[src_0 + 5]; dst[dst_0 + 6] = src[src_0 + 6]; dst[dst_0 + 7] = src[src_0 + 7]; len -= 8; src_0 += 8; dst_0 += 8; } while (len >= 4) { dst[dst_0] = src[src_0]; dst[dst_0 + 1] = src[src_0 + 1]; dst[dst_0 + 2] = src[src_0 + 2]; dst[dst_0 + 3] = src[src_0 + 3]; len -= 4; src_0 += 4; dst_0 += 4; } while (len-- > 0) { dst[dst_0++] = src[src_0++]; } } private static int WildCopy(byte[] src, int src_0, byte[] dst, int dst_0, int dst_end) { int num = dst_end - dst_0; if (num >= 16) { Buffer.BlockCopy(src, src_0, dst, dst_0, num); } else { while (num >= 4) { dst[dst_0] = src[src_0]; dst[dst_0 + 1] = src[src_0 + 1]; dst[dst_0 + 2] = src[src_0 + 2]; dst[dst_0 + 3] = src[src_0 + 3]; num -= 4; src_0 += 4; dst_0 += 4; } while (num-- > 0) { dst[dst_0++] = src[src_0++]; } } return num; } private static int SecureCopy(byte[] buffer, int src, int dst, int dst_end) { int num = dst - src; int num2 = dst_end - dst; int num3 = num2; if (num >= 16) { if (num >= num2) { Buffer.BlockCopy(buffer, src, buffer, dst, num2); return num2; } do { Buffer.BlockCopy(buffer, src, buffer, dst, num); src += num; dst += num; num3 -= num; } while (num3 >= num); } while (num3 >= 4) { buffer[dst] = buffer[src]; buffer[dst + 1] = buffer[src + 1]; buffer[dst + 2] = buffer[src + 2]; buffer[dst + 3] = buffer[src + 3]; dst += 4; src += 4; num3 -= 4; } while (num3-- > 0) { buffer[dst++] = buffer[src++]; } return num2; } public static int Encode32(byte[] input, int inputOffset, int inputLength, byte[] output, int outputOffset, int outputLength) { CheckArguments(input, inputOffset, ref inputLength, output, outputOffset, ref outputLength); if (outputLength == 0) { return 0; } if (inputLength < 65547) { return LZ4_compress64kCtx_safe32(new ushort[8192], input, output, inputOffset, outputOffset, inputLength, outputLength); } return LZ4_compressCtx_safe32(new int[4096], input, output, inputOffset, outputOffset, inputLength, outputLength); } public static byte[] Encode32(byte[] input, int inputOffset, int inputLength) { if (inputLength < 0) { inputLength = input.Length - inputOffset; } if (input == null) { throw new ArgumentNullException("input"); } if (inputOffset < 0 || inputOffset + inputLength > input.Length) { throw new ArgumentException("inputOffset and inputLength are invalid for given input"); } byte[] array = new byte[MaximumOutputLength(inputLength)]; int num = Encode32(input, inputOffset, inputLength, array, 0, array.Length); if (num != array.Length) { if (num < 0) { throw new InvalidOperationException("Compression has been corrupted"); } byte[] array2 = new byte[num]; Buffer.BlockCopy(array, 0, array2, 0, num); return array2; } return array; } public static int Encode64(byte[] input, int inputOffset, int inputLength, byte[] output, int outputOffset, int outputLength) { CheckArguments(input, inputOffset, ref inputLength, output, outputOffset, ref outputLength); if (outputLength == 0) { return 0; } if (inputLength < 65547) { return LZ4_compress64kCtx_safe64(new ushort[8192], input, output, inputOffset, outputOffset, inputLength, outputLength); } return LZ4_compressCtx_safe64(new int[4096], input, output, inputOffset, outputOffset, inputLength, outputLength); } public static byte[] Encode64(byte[] input, int inputOffset, int inputLength) { if (inputLength < 0) { inputLength = input.Length - inputOffset; } if (input == null) { throw new ArgumentNullException("input"); } if (inputOffset < 0 || inputOffset + inputLength > input.Length) { throw new ArgumentException("inputOffset and inputLength are invalid for given input"); } byte[] array = new byte[MaximumOutputLength(inputLength)]; int num = Encode64(input, inputOffset, inputLength, array, 0, array.Length); if (num != array.Length) { if (num < 0) { throw new InvalidOperationException("Compression has been corrupted"); } byte[] array2 = new byte[num]; Buffer.BlockCopy(array, 0, array2, 0, num); return array2; } return array; } public static int Decode32(byte[] input, int inputOffset, int inputLength, byte[] output, int outputOffset, int outputLength, bool knownOutputLength) { CheckArguments(input, inputOffset, ref inputLength, output, outputOffset, ref outputLength); if (outputLength == 0) { return 0; } if (knownOutputLength) { if (LZ4_uncompress_safe32(input, output, inputOffset, outputOffset, outputLength) != inpu
quaternion.gundomizer.dll
Decompiled 2 days ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Security.Cryptography; using System.Text; using System.Text.RegularExpressions; using System.Threading; using Anvil; using AssetsTools.NET; using AssetsTools.NET.Extra; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using FistVR; using Gundomizer.Indexing; using HarmonyLib; using LZ4ps; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyCompany("quaternion")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("Random and held-item-compatible spawning in Item Spawner V2.")] [assembly: AssemblyFileVersion("1.1.0.0")] [assembly: AssemblyInformationalVersion("1.1.0")] [assembly: AssemblyProduct("quaternion.gundomizer")] [assembly: AssemblyTitle("Gundomizer")] [assembly: AssemblyVersion("1.1.0.0")] namespace BepInEx { [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] [Conditional("CodeGeneration")] internal sealed class BepInAutoPluginAttribute : Attribute { public BepInAutoPluginAttribute(string id = null, string name = null, string version = null) { } } } namespace BepInEx.Preloader.Core.Patching { [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] [Conditional("CodeGeneration")] internal sealed class PatcherAutoPluginAttribute : Attribute { public PatcherAutoPluginAttribute(string id = null, string name = null, string version = null) { } } } namespace Gundomizer { internal static class AmmoCatalog { internal sealed class Variant { internal FireArmRoundType Type; internal FireArmRoundClass Class; internal string Key; internal string Name; internal string Caliber; internal string Properties; internal ItemSpawnerID Entry; } internal static HashSet<FireArmRoundType> Types(FVRPhysicalObject held) { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) HashSet<FireArmRoundType> hashSet = new HashSet<FireArmRoundType>(); if ((Object)(object)held == (Object)null) { return hashSet; } foreach (FVRPhysicalObject item in Compatibility.Objects(held)) { FVRFireArm val = (FVRFireArm)(object)((item is FVRFireArm) ? item : null); if ((Object)(object)val != (Object)null && !(val is FlintlockWeapon)) { hashSet.Add(val.RoundType); List<FVRFireArmChamber> chambers = val.GetChambers(); if (chambers != null) { foreach (FVRFireArmChamber item2 in chambers) { if ((Object)(object)item2 != (Object)null) { hashSet.Add(item2.RoundType); } } } AttachableFirearm integratedAttachableFirearm = val.GetIntegratedAttachableFirearm(); if ((Object)(object)integratedAttachableFirearm != (Object)null) { hashSet.Add(integratedAttachableFirearm.RoundType); } } AttachableFirearmPhysicalObject val2 = (AttachableFirearmPhysicalObject)(object)((item is AttachableFirearmPhysicalObject) ? item : null); if ((Object)(object)val2 != (Object)null && (Object)(object)val2.FA != (Object)null) { hashSet.Add(val2.FA.RoundType); } FVRFireArmMagazine val3 = (FVRFireArmMagazine)(object)((item is FVRFireArmMagazine) ? item : null); if ((Object)(object)val3 != (Object)null) { hashSet.Add(val3.RoundType); } FVRFireArmClip val4 = (FVRFireArmClip)(object)((item is FVRFireArmClip) ? item : null); if ((Object)(object)val4 != (Object)null) { hashSet.Add(val4.RoundType); } Speedloader val5 = (Speedloader)(object)((item is Speedloader) ? item : null); if ((Object)(object)val5 != (Object)null && val5.Chambers != null) { foreach (SpeedloaderChamber chamber in val5.Chambers) { if ((Object)(object)chamber != (Object)null) { hashSet.Add(chamber.Type); } } } FVRFireArmRound val6 = (FVRFireArmRound)(object)((item is FVRFireArmRound) ? item : null); if ((Object)(object)val6 != (Object)null) { hashSet.Add(val6.RoundType); } } return hashSet; } internal unsafe static List<Variant> Read(HashSet<FireArmRoundType> types) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_022d: Unknown result type (might be due to invalid IL or missing references) //IL_022e: Unknown result type (might be due to invalid IL or missing references) //IL_0236: Unknown result type (might be due to invalid IL or missing references) //IL_023b: Unknown result type (might be due to invalid IL or missing references) //IL_0241: Unknown result type (might be due to invalid IL or missing references) //IL_0244: Unknown result type (might be due to invalid IL or missing references) //IL_024e: Expected I4, but got Unknown //IL_024e: Expected I4, but got Unknown //IL_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_026d: Unknown result type (might be due to invalid IL or missing references) //IL_0272: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01d5: Unknown result type (might be due to invalid IL or missing references) List<Variant> list = new List<Variant>(); foreach (FireArmRoundType type in types) { if (!AM.STypeDic.TryGetValue(type, out var value)) { continue; } FVRFireArmRoundDisplayData value2; string caliber = (AM.SRoundDisplayDataDic.TryGetValue(type, out value2) ? value2.DisplayName : ((object)(*(FireArmRoundType*)(&type))/*cast due to .constrained prefix*/).ToString()); foreach (KeyValuePair<FireArmRoundClass, DisplayDataClass> item in value) { DisplayDataClass value3 = item.Value; if (value3 == null || (Object)(object)value3.ObjectID == (Object)null) { continue; } FVRObject objectID = value3.ObjectID; ItemSpawnerID val = (OtherLoaderBridge.Active ? OtherLoaderBridge.Resolve(objectID.ItemID) : null); if ((Object)(object)val == (Object)null && !string.IsNullOrEmpty(objectID.SpawnedFromId) && IM.HasSpawnedID(objectID.SpawnedFromId)) { val = IM.GetSpawnerID(objectID.SpawnedFromId); } if ((Object)(object)val == (Object)null) { val = AmmoSpawnerEntries.Get(objectID, caliber, string.IsNullOrEmpty(value3.Name) ? ((object)item.Key/*cast due to .constrained prefix*/).ToString() : value3.Name); } if (!SpawnerBridge.IsAvailable(val) || ((Object)(object)val.MainObject != (Object)(object)objectID && (!OtherLoaderBridge.Active || string.IsNullOrEmpty(objectID.ItemID) || !string.Equals(val.MainObject.ItemID, objectID.ItemID, StringComparison.Ordinal)))) { continue; } List<string> list2 = new List<string>(); foreach (KeyValuePair<FireArmRoundPropertyTag, Dictionary<FireArmRoundType, List<FireArmRoundClass>>> item2 in AM.TagDic) { if ((int)item2.Key != 0 && item2.Value != null && item2.Value.TryGetValue(type, out var value4) && value4 != null && value4.Contains(item.Key)) { list2.Add(Regex.Replace(((object)item2.Key/*cast due to .constrained prefix*/).ToString(), "([a-z])([A-Z])", "$1 $2").Replace('_', ' ')); } } list2.Sort(StringComparer.Ordinal); list.Add(new Variant { Type = type, Class = item.Key, Key = AmmoSelection.Key((int)type, (int)item.Key), Name = (string.IsNullOrEmpty(value3.Name) ? ((object)item.Key/*cast due to .constrained prefix*/).ToString() : value3.Name), Caliber = caliber, Properties = string.Join(", ", list2.ToArray()), Entry = val }); } } list.Sort(delegate(Variant a, Variant b) { int num = string.CompareOrdinal(a.Caliber, b.Caliber); return (num == 0) ? string.CompareOrdinal(a.Name, b.Name) : num; }); return list; } internal static bool Matches(FVRPhysicalObject held, GameObject prefab, Variant variant) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) FVRFireArmRound val = (((Object)(object)prefab == (Object)null) ? null : prefab.GetComponent<FVRFireArmRound>()); if ((Object)(object)val != (Object)null && val.RoundType == variant.Type && val.RoundClass == variant.Class && Types(held).Contains(variant.Type)) { return AmmoSelection.Shared.Includes(variant.Key); } return false; } } internal sealed class AmmoFill { private readonly FVRFireArmRound round; private readonly HashSet<Component> visited = new HashSet<Component>(); internal int Filled { get; private set; } internal int Failed { get; private set; } private AmmoFill(FVRFireArmRound round) { this.round = round; } internal static AmmoFill Apply(FVRPhysicalObject held, FVRFireArmRound round) { //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) AmmoFill ammoFill = new AmmoFill(round); if ((Object)(object)held == (Object)null || (Object)(object)round == (Object)null || round.IsSpent) { return ammoFill; } try { foreach (FVRPhysicalObject item in Compatibility.Objects(held)) { ammoFill.Magazine((FVRFireArmMagazine)(object)((item is FVRFireArmMagazine) ? item : null)); ammoFill.Clip((FVRFireArmClip)(object)((item is FVRFireArmClip) ? item : null)); Speedloader val = (Speedloader)(object)((item is Speedloader) ? item : null); if ((Object)(object)val != (Object)null && val.Chambers != null) { foreach (SpeedloaderChamber chamber in val.Chambers) { if ((Object)(object)chamber != (Object)null && chamber.Type == round.RoundType) { ammoFill.Try((Component)(object)chamber, delegate { //IL_0011: Unknown result type (might be due to invalid IL or missing references) chamber.Load(round.RoundClass, false); }); } } } ammoFill.Firearm((FVRFireArm)(object)((item is FVRFireArm) ? item : null)); AttachableFirearmPhysicalObject val2 = (AttachableFirearmPhysicalObject)(object)((item is AttachableFirearmPhysicalObject) ? item : null); if ((Object)(object)val2 != (Object)null) { ammoFill.Attachable(val2.FA); } } } catch (Exception ex) { ammoFill.Report(ex); } return ammoFill; } private void Magazine(FVRFireArmMagazine magazine) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)magazine != (Object)null && magazine.RoundType == round.RoundType) { Try((Component)(object)magazine, delegate { //IL_0011: Unknown result type (might be due to invalid IL or missing references) magazine.ReloadMagWithType(round.RoundClass); }); } } private void Clip(FVRFireArmClip clip) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)clip != (Object)null && clip.RoundType == round.RoundType) { Try((Component)(object)clip, delegate { //IL_0011: Unknown result type (might be due to invalid IL or missing references) clip.ReloadClipWithType(round.RoundClass); }); } } private void Chamber(FVRFireArmChamber chamber) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)chamber != (Object)null && chamber.RoundType == round.RoundType) { Try((Component)(object)chamber, delegate { chamber.SetRound(round, false); }); } } private void Firearm(FVRFireArm firearm) { //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)firearm == (Object)null || !visited.Add((Component)(object)firearm)) { return; } Magazine(firearm.Magazine); if (firearm.SecondaryMagazineSlots != null) { SecondaryMagazineSlot[] secondaryMagazineSlots = firearm.SecondaryMagazineSlots; foreach (SecondaryMagazineSlot val in secondaryMagazineSlots) { if (val != null) { Magazine(val.Magazine); } } } Clip(firearm.Clip); List<FVRFireArmChamber> chambers = firearm.GetChambers(); if (chambers != null) { foreach (FVRFireArmChamber item in chambers) { Chamber(item); } } Attachable(firearm.GetIntegratedAttachableFirearm()); if (firearm.RoundType != round.RoundType || !firearm.UsesBelts || !((Object)(object)firearm.BeltDD != (Object)null)) { return; } Try((Component)(object)firearm.BeltDD, delegate { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) foreach (FVRLoadedRound beltRound in firearm.BeltDD.BeltRounds) { beltRound.LR_Class = round.RoundClass; beltRound.LR_Mesh = AM.GetRoundMesh(round.RoundType, round.RoundClass); beltRound.LR_Material = AM.GetRoundMaterial(round.RoundType, round.RoundClass); beltRound.LR_ObjectWrapper = AM.GetRoundSelfPrefab(round.RoundType, round.RoundClass); } firearm.BeltDD.UpdateProxyRounds(0); }); } private void Attachable(AttachableFirearm firearm) { if ((Object)(object)firearm == (Object)null || !visited.Add((Component)(object)firearm)) { return; } Firearm(firearm.OverrideFA); Magazine(firearm.Magazine); if (firearm.SecondaryMagazineSlots != null) { SecondaryMagazineSlot[] secondaryMagazineSlots = firearm.SecondaryMagazineSlots; foreach (SecondaryMagazineSlot val in secondaryMagazineSlots) { if (val != null) { Magazine(val.Magazine); } } } Clip(firearm.Clip); FVRFireArmChamber[] componentsInChildren = ((Component)firearm).GetComponentsInChildren<FVRFireArmChamber>(true); foreach (FVRFireArmChamber val2 in componentsInChildren) { if ((Object)(object)((Component)val2).GetComponentInParent<AttachableFirearm>() == (Object)(object)firearm) { Chamber(val2); } } } private void Try(Component component, Action fill) { if (!visited.Add(component)) { return; } try { fill(); int filled = Filled + 1; Filled = filled; } catch (Exception ex) { Report(ex); } } private void Report(Exception ex) { int failed = Failed + 1; Failed = failed; Plugin.Log.LogWarning((object)("Ammo spawned, but a held-item refill failed: " + ex)); } } internal sealed class AmmoPanel { internal const float GroupWidth = 200f; private const int PageSize = 7; private const float Width = 1200f; private const float Height = 850f; private readonly RandomizerController owner; private readonly GameObject template; private readonly RectTransform popup; private readonly RandomizerButton rollButton; private readonly RandomizerButton toggleButton; private readonly List<RandomizerButton> rows = new List<RandomizerButton>(); private readonly Text title; private readonly Text hint; private readonly Text pageText; private readonly RandomizerButton previous; private readonly RandomizerButton next; private List<AmmoCatalog.Variant> variants = new List<AmmoCatalog.Variant>(); private HashSet<FireArmRoundType> types = new HashSet<FireArmRoundType>(); private FVRPhysicalObject held; private int page; private int revision; private int enabledCount; internal bool IsOpen => ((Component)popup).gameObject.activeSelf; internal RandomizerButton RollButton => rollButton; internal string Tooltip { get { if (!rollButton.Hovered) { if (!toggleButton.Hovered) { return null; } return "Choose ammo variants for " + Compatibility.Name(held); } if (enabledCount != 0) { return "Random compatible ammo for " + Compatibility.Name(held) + " (" + enabledCount + " variants enabled)"; } return "Hold an ammo-using item and enable at least one ammo variant."; } } internal AmmoPanel(RandomizerController owner, ItemSpawnerV2 spawner, RectTransform root, GameObject template, float left, float y) { //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01d2: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Unknown result type (might be due to invalid IL or missing references) //IL_0218: Unknown result type (might be due to invalid IL or missing references) //IL_025b: Unknown result type (might be due to invalid IL or missing references) //IL_0275: Unknown result type (might be due to invalid IL or missing references) //IL_028f: Unknown result type (might be due to invalid IL or missing references) //IL_02a9: Unknown result type (might be due to invalid IL or missing references) //IL_02ba: Unknown result type (might be due to invalid IL or missing references) //IL_02ce: Unknown result type (might be due to invalid IL or missing references) //IL_02d3: Unknown result type (might be due to invalid IL or missing references) //IL_02f2: Unknown result type (might be due to invalid IL or missing references) //IL_0389: Unknown result type (might be due to invalid IL or missing references) //IL_0393: Unknown result type (might be due to invalid IL or missing references) //IL_039d: Expected O, but got Unknown //IL_03de: Unknown result type (might be due to invalid IL or missing references) //IL_03e4: Unknown result type (might be due to invalid IL or missing references) //IL_03f0: Unknown result type (might be due to invalid IL or missing references) //IL_040a: Unknown result type (might be due to invalid IL or missing references) //IL_0429: Unknown result type (might be due to invalid IL or missing references) //IL_0453: Unknown result type (might be due to invalid IL or missing references) //IL_047e: Unknown result type (might be due to invalid IL or missing references) //IL_0497: Unknown result type (might be due to invalid IL or missing references) AmmoPanel ammoPanel = this; this.owner = owner; this.template = template; rollButton = owner.CloneButton(template, root, "Ammo", compatible: false, left + 60f, y, 120f); rollButton.Icon.Ammo = true; ((Graphic)rollButton.Icon).SetVerticesDirty(); rollButton.NeedsHeldContext = true; rollButton.Ready = () => owner.CanClick(compatible: true) && ammoPanel.enabledCount > 0; rollButton.Handler = owner.ClickAmmo; toggleButton = owner.CloneButton(template, root, "Ammo choices", compatible: false, left + 160f, y, 80f); toggleButton.Icon.Dropdown = true; ((Graphic)toggleButton.Icon).SetVerticesDirty(); toggleButton.Rainbow = false; ((RawImage)toggleButton.Background).texture = (Texture)(object)Texture2D.whiteTexture; ((Graphic)toggleButton.Background).color = new Color(0.13f, 0.16f, 0.19f, 1f); rollButton.Background.RoundRight = false; toggleButton.Background.RoundLeft = false; RectTransform rectTransform = ((Graphic)rollButton.Background).rectTransform; rectTransform.offsetMax = new Vector2(0f, rectTransform.offsetMax.y); RectTransform rectTransform2 = ((Graphic)toggleButton.Background).rectTransform; rectTransform2.offsetMin = new Vector2(0f, rectTransform2.offsetMin.y); Image component = new GameObject("Group separator", new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(Image) }).GetComponent<Image>(); ((Component)component).gameObject.layer = template.layer; ((Transform)((Graphic)component).rectTransform).SetParent(((Component)toggleButton).transform, false); ((Graphic)component).rectTransform.anchorMin = new Vector2(0f, 0f); ((Graphic)component).rectTransform.anchorMax = new Vector2(0f, 1f); ((Graphic)component).rectTransform.offsetMin = new Vector2(0f, 4f); ((Graphic)component).rectTransform.offsetMax = new Vector2(0.75f, -4f); RectTransform rectTransform3 = ((Graphic)component).rectTransform; ((Transform)rectTransform3).localPosition = ((Transform)rectTransform3).localPosition + new Vector3(0f, 0f, -0.015f); ((Graphic)component).color = new Color(0.65f, 0.68f, 0.7f, 0.6f); ((Graphic)component).raycastTarget = false; toggleButton.NeedsHeldContext = true; toggleButton.Ready = () => owner.CanClick(compatible: true) && ammoPanel.variants.Count > 0; toggleButton.Handler = delegate { if (ammoPanel.IsOpen) { ammoPanel.Hide(); } else { owner.CloseChoices(openingAmmo: true); ammoPanel.Refresh(ammoPanel.held, force: true); ammoPanel.Redraw(); ammoPanel.SetOpen(open: true); } }; popup = (RectTransform)new GameObject("Gundomizer Ammo Choices", new Type[5] { typeof(RectTransform), typeof(CanvasRenderer), typeof(Image), typeof(BoxCollider), typeof(FVRPointable) }).transform; ((Component)popup).gameObject.layer = template.layer; ((Transform)popup).SetParent((Transform)(object)root, false); RectTransform obj = popup; RectTransform obj2 = popup; Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(0.5f, 0.5f); obj2.anchorMax = val; obj.anchorMin = val; popup.pivot = Vector2.zero; popup.sizeDelta = new Vector2(1200f, 850f); ((Transform)popup).localPosition = new Vector3(left, y + 95f, -8f); Image component2 = ((Component)popup).GetComponent<Image>(); ((Graphic)component2).color = new Color(0.025f, 0.03f, 0.04f, 1f); ((Graphic)component2).raycastTarget = true; BoxCollider component3 = ((Component)popup).GetComponent<BoxCollider>(); component3.center = new Vector3(600f, 425f, 2f); component3.size = new Vector3(1200f, 850f, 1f); ((Component)popup).GetComponent<FVRPointable>().MaxPointingRange = ((FVRPointable)rollButton).MaxPointingRange; title = Label("Title", 32f, 790f, 1010f, 76f, 46); hint = Label("Description", 32f, 718f, 1136f, 64f, 32); TextButton("Close", "X", 1125f, 790f, 90f, delegate { ammoPanel.Hide(); }); for (int num = 0; num < 7; num++) { int slot = num; RandomizerButton randomizerButton = TextButton("Variant " + num, "", 600f, 640f - (float)num * 84f, 1136f, delegate { ammoPanel.Toggle(slot); }); randomizerButton.Caption.alignment = (TextAnchor)3; rows.Add(randomizerButton); } TextButton("All", "All", 130f, 48f, 180f, delegate { ammoPanel.SetAll(include: true); }); TextButton("None", "None", 335f, 48f, 180f, delegate { ammoPanel.SetAll(include: false); }); previous = TextButton("Previous", "<", 780f, 48f, 140f, delegate { ammoPanel.page--; ammoPanel.Redraw(); }); next = TextButton("Next", ">", 1090f, 48f, 140f, delegate { ammoPanel.page++; ammoPanel.Redraw(); }); pageText = Label("Page", 860f, 48f, 160f, 70f, 40); pageText.alignment = (TextAnchor)4; ((Component)popup).gameObject.SetActive(false); } private Text Label(string name, float left, float y, float width, float height, int size) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) Text component = new GameObject(name, new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(Text) }).GetComponent<Text>(); ((Component)component).gameObject.layer = template.layer; ((Transform)((Graphic)component).rectTransform).SetParent((Transform)(object)popup, false); RectTransform rectTransform = ((Graphic)component).rectTransform; Vector2 anchorMin = (((Graphic)component).rectTransform.anchorMax = Vector2.zero); rectTransform.anchorMin = anchorMin; ((Graphic)component).rectTransform.pivot = new Vector2(0f, 0.5f); ((Graphic)component).rectTransform.sizeDelta = new Vector2(width, height); ((Transform)((Graphic)component).rectTransform).localPosition = new Vector3(left, y, -1f); component.font = template.GetComponent<Text>().font; component.fontSize = size; component.supportRichText = false; ((Graphic)component).color = Color.white; component.alignment = (TextAnchor)3; component.horizontalOverflow = (HorizontalWrapMode)0; component.verticalOverflow = (VerticalWrapMode)0; ((Graphic)component).raycastTarget = false; return component; } private RandomizerButton TextButton(string name, string caption, float x, float y, float width, Action<FVRViveHand> handler) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_0194: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Unknown result type (might be due to invalid IL or missing references) //IL_0213: Unknown result type (might be due to invalid IL or missing references) RandomizerButton randomizerButton = owner.CloneButton(template, popup, "Ammo " + name, compatible: false, x, y, width); RectTransform val = (RectTransform)((Component)randomizerButton).transform; Vector2 anchorMin = (val.anchorMax = Vector2.zero); val.anchorMin = anchorMin; ((Transform)val).localPosition = new Vector3(x, y, -1f); BoxCollider component = ((Component)randomizerButton).GetComponent<BoxCollider>(); component.size = new Vector3(component.size.x, component.size.y * 0.55f, 0.25f); val.sizeDelta = new Vector2(val.sizeDelta.x, val.sizeDelta.y * 0.55f); ((Component)randomizerButton.Icon).gameObject.SetActive(false); randomizerButton.Rainbow = false; ((RawImage)randomizerButton.Background).texture = (Texture)(object)Texture2D.whiteTexture; ((Graphic)randomizerButton.Background).color = new Color(0.13f, 0.16f, 0.19f, 1f); randomizerButton.Ready = () => owner.CanClick(compatible: false); randomizerButton.Handler = handler; Text component2 = new GameObject("Caption", new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(Text) }).GetComponent<Text>(); ((Component)component2).gameObject.layer = template.layer; ((Transform)((Graphic)component2).rectTransform).SetParent((Transform)(object)val, false); ((Graphic)component2).rectTransform.anchorMin = Vector2.zero; ((Graphic)component2).rectTransform.anchorMax = Vector2.one; ((Graphic)component2).rectTransform.offsetMin = new Vector2(12f, 0f); ((Graphic)component2).rectTransform.offsetMax = new Vector2(-12f, 0f); RectTransform rectTransform = ((Graphic)component2).rectTransform; ((Transform)rectTransform).localPosition = ((Transform)rectTransform).localPosition + new Vector3(0f, 0f, -0.02f); component2.font = template.GetComponent<Text>().font; ((Graphic)component2).color = Color.white; component2.alignment = (TextAnchor)4; ((Graphic)component2).raycastTarget = false; randomizerButton.Caption = component2; component2.text = caption; component2.fontSize = 22; component2.supportRichText = false; component2.horizontalOverflow = (HorizontalWrapMode)0; component2.verticalOverflow = (VerticalWrapMode)0; return randomizerButton; } internal void Refresh(FVRPhysicalObject target, bool force = false) { HashSet<FireArmRoundType> hashSet = AmmoCatalog.Types(target); bool flag = (Object)(object)target != (Object)(object)held || !hashSet.SetEquals(types); if (force || flag) { if ((Object)(object)target != (Object)(object)held) { Hide(); } held = target; types = hashSet; variants = AmmoCatalog.Read(types); if (flag) { page = 0; } Redraw(); if ((Object)(object)held == (Object)null || variants.Count == 0) { Hide(); } } } internal List<AmmoCatalog.Variant> EnabledVariants() { Refresh(held, force: true); List<AmmoCatalog.Variant> list = new List<AmmoCatalog.Variant>(); foreach (AmmoCatalog.Variant variant in variants) { if (AmmoSelection.Shared.Includes(variant.Key)) { list.Add(variant); } } return list; } private void SetOpen(bool open) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) ((Component)popup).gameObject.SetActive(open); ((Transform)((Graphic)toggleButton.Icon).rectTransform).localRotation = Quaternion.Euler(0f, 0f, open ? 180f : 0f); } internal void Hide() { SetOpen(open: false); } internal void Update() { if (revision != AmmoSelection.Shared.Revision) { Redraw(); } if (!IsOpen) { return; } string text = "Choose which ammo variants to include."; for (int i = 0; i < rows.Count; i++) { int num = page * 7 + i; if (num < variants.Count && rows[i].Hovered && !string.IsNullOrEmpty(variants[num].Properties)) { text = variants[num].Name + ": " + variants[num].Properties; } } hint.text = text; } private void Toggle(int slot) { int num = page * 7 + slot; if (num >= 0 && num < variants.Count) { AmmoCatalog.Variant variant = variants[num]; AmmoSelection.Shared.Set(variant.Key, !AmmoSelection.Shared.Includes(variant.Key)); Redraw(); } } private void SetAll(bool include) { foreach (AmmoCatalog.Variant variant in variants) { AmmoSelection.Shared.Set(variant.Key, include); } Redraw(); } private void Redraw() { revision = AmmoSelection.Shared.Revision; enabledCount = 0; foreach (AmmoCatalog.Variant variant2 in variants) { if (AmmoSelection.Shared.Includes(variant2.Key)) { enabledCount++; } } int num = Math.Max(1, (variants.Count + 7 - 1) / 7); page = Math.Max(0, Math.Min(page, num - 1)); title.text = ((types.Count == 1 && variants.Count > 0) ? variants[0].Caliber : "Compatible ammo") + " (" + enabledCount + "/" + variants.Count + ")"; hint.text = "Choose which ammo variants to include."; for (int i = 0; i < rows.Count; i++) { int num2 = page * 7 + i; ((Component)rows[i]).gameObject.SetActive(num2 < variants.Count); if (num2 < variants.Count) { AmmoCatalog.Variant variant = variants[num2]; rows[i].Caption.text = (AmmoSelection.Shared.Includes(variant.Key) ? " [x] " : " [ ] ") + ((types.Count > 1) ? (variant.Caliber + " - ") : "") + variant.Name; } } ((Component)previous).gameObject.SetActive(page > 0); ((Component)next).gameObject.SetActive(page + 1 < num); pageText.text = page + 1 + " / " + num; } } internal sealed class AmmoSelection { internal static readonly AmmoSelection Shared = new AmmoSelection(); private readonly HashSet<string> excluded = new HashSet<string>(StringComparer.Ordinal); internal int Revision { get; private set; } internal static string Key(int caliber, int variant) { return caliber + ":" + variant; } internal bool Includes(string key) { return !excluded.Contains(key); } internal void Set(string key, bool include) { if (include ? excluded.Remove(key) : excluded.Add(key)) { int revision = Revision + 1; Revision = revision; } } } internal static class AmmoSpawnerEntries { private static readonly FieldInfo Registry = AccessTools.Field(typeof(IM), "SpawnerIDDic"); private static readonly Dictionary<string, ItemSpawnerID> owned = new Dictionary<string, ItemSpawnerID>(StringComparer.Ordinal); internal static ItemSpawnerID Get(FVRObject source, string caliber, string variant) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Invalid comparison between Unknown and I4 //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)source == (Object)null || string.IsNullOrEmpty(source.ItemID) || (int)source.Category != 4 || IM.OD == null || !IM.OD.ContainsKey(source.ItemID) || (object)Registry == null || (Object)(object)ManagerSingleton<IM>.Instance == (Object)null) { return null; } string text = "Gundomizer.Ammo/" + source.ItemID; Dictionary<string, ItemSpawnerID> dictionary = (Dictionary<string, ItemSpawnerID>)Registry.GetValue(ManagerSingleton<IM>.Instance); ItemSpawnerID value2; if (dictionary.TryGetValue(text, out var value)) { if (!owned.TryGetValue(text, out value2) || (Object)(object)value2 != (Object)(object)value) { return null; } } else { value2 = ScriptableObject.CreateInstance<ItemSpawnerID>(); ((Object)value2).name = text; value2.ItemID = text; value2.Category = (EItemCategory)11; value2.SubCategory = (ESubCategory)0; value2.Secondaries = (ItemSpawnerID[])(object)new ItemSpawnerID[0]; value2.Secondaries_ByStringID = new List<string>(); value2.TutorialBlocks = new List<string>(); value2.IsDisplayedInMainEntry = false; owned[text] = value2; dictionary.Add(text, value2); } value2.MainObject = source; value2.DisplayName = caliber + " — " + variant; return value2; } internal static bool Owns(ItemSpawnerID entry) { if ((Object)(object)entry != (Object)null && owned.TryGetValue(entry.ItemID, out var value)) { return (Object)(object)entry == (Object)(object)value; } return false; } internal static void Clear() { IM instance = ManagerSingleton<IM>.Instance; Dictionary<string, ItemSpawnerID> dictionary = (((Object)(object)instance == (Object)null || (object)Registry == null) ? null : (Registry.GetValue(instance) as Dictionary<string, ItemSpawnerID>)); foreach (KeyValuePair<string, ItemSpawnerID> item in owned) { if (dictionary != null && dictionary.TryGetValue(item.Key, out var value) && (Object)(object)value == (Object)(object)item.Value) { dictionary.Remove(item.Key); } Object.Destroy((Object)(object)item.Value); } owned.Clear(); } } internal static class AssetAccess { private static readonly FieldInfo Loading = AccessTools.Field(typeof(AnvilAsset), "m_loadingState"); private static AnvilCallback<GameObject> outstanding; internal static bool LoadPending { get { if (outstanding != null) { return !((AnvilCallbackBase)outstanding).IsCompleted; } return false; } } internal static AnvilCallback<GameObject> Cached(FVRObject obj) { if (!((Object)(object)obj == (Object)null) && (object)Loading != null) { return Loading.GetValue(obj) as AnvilCallback<GameObject>; } return null; } internal static GameObject Peek(FVRObject obj) { AnvilCallback<GameObject> val = Cached(obj); if (val == null || !((AnvilCallbackBase)val).IsCompleted) { return null; } return val.Result; } internal static bool TryRequest(FVRObject obj, out AnvilCallback<GameObject> request, out bool started) { request = Cached(obj); started = false; if (request != null) { return true; } if (LoadPending) { return false; } request = ((AnvilAsset)obj).GetGameObjectAsync(); started = true; outstanding = request; return true; } } public sealed class ButtonIcon : MaskableGraphic { internal bool Compatible; internal bool Ammo; internal bool Dropdown; protected override void OnPopulateMesh(VertexHelper mesh) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) mesh.Clear(); Rect pixelAdjustedRect = ((Graphic)this).GetPixelAdjustedRect(); float num = Mathf.Min(((Rect)(ref pixelAdjustedRect)).width / 100f, ((Rect)(ref pixelAdjustedRect)).height / 100f); Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(((Rect)(ref pixelAdjustedRect)).center.x - 100f * num * 0.5f, ((Rect)(ref pixelAdjustedRect)).center.y + 50f * num); IconShape[] array = (Ammo ? IconGeometry.Cartridge : (Dropdown ? IconGeometry.Chevron : (Compatible ? IconGeometry.Link : IconGeometry.Dice))); foreach (IconShape iconShape in array) { int currentVertCount = mesh.currentVertCount; Color val2 = (Color)(iconShape.Cutout ? new Color(0.055f, 0.065f, 0.08f, ((Graphic)this).color.a) : ((Graphic)this).color); for (int j = 0; j < iconShape.Points.Length; j += 2) { mesh.AddVert(new Vector3(val.x + iconShape.Points[j] * num, val.y - iconShape.Points[j + 1] * num, 0f), Color32.op_Implicit(val2), Vector2.zero); } for (int k = 1; k < iconShape.Points.Length / 2 - 1; k++) { mesh.AddTriangle(currentVertCount, currentVertCount + k, currentVertCount + k + 1); } } } } public sealed class ButtonSurface : RawImage { internal bool RoundLeft = true; internal bool RoundRight = true; private const int Steps = 6; protected override void OnPopulateMesh(VertexHelper mesh) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) mesh.Clear(); Rect pixelAdjustedRect = ((Graphic)this).GetPixelAdjustedRect(); if (!(((Rect)(ref pixelAdjustedRect)).width <= 2f) && !(((Rect)(ref pixelAdjustedRect)).height <= 2f)) { float num = Mathf.Min(7f, Mathf.Min(((Rect)(ref pixelAdjustedRect)).width, ((Rect)(ref pixelAdjustedRect)).height) * 0.25f); Rect rect = default(Rect); ((Rect)(ref rect))..ctor(((Rect)(ref pixelAdjustedRect)).x + 0.8f, ((Rect)(ref pixelAdjustedRect)).y + 0.8f, ((Rect)(ref pixelAdjustedRect)).width - 1.6f, ((Rect)(ref pixelAdjustedRect)).height - 1.6f); AddVertex(mesh, ((Rect)(ref pixelAdjustedRect)).center, pixelAdjustedRect, edge: false); int num2 = 28; for (int i = 0; i < num2; i++) { AddVertex(mesh, Outline(rect, num - 0.8f, i), pixelAdjustedRect, edge: false); AddVertex(mesh, Outline(pixelAdjustedRect, num, i), pixelAdjustedRect, edge: true); } for (int j = 0; j < num2; j++) { int num3 = 1 + j * 2; int num4 = 1 + (j + 1) % num2 * 2; mesh.AddTriangle(0, num3, num4); mesh.AddTriangle(num3, num3 + 1, num4 + 1); mesh.AddTriangle(num3, num4 + 1, num4); } } } private Vector2 Outline(Rect rect, float radius, int index) { //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) int num = index / 7; bool flag = num < 2; bool flag2 = num == 0 || num == 3; if (!(flag ? RoundRight : RoundLeft)) { radius = 0f; } Vector2 val = new Vector2(flag ? (((Rect)(ref rect)).xMax - radius) : (((Rect)(ref rect)).xMin + radius), flag2 ? (((Rect)(ref rect)).yMax - radius) : (((Rect)(ref rect)).yMin + radius)); float num2 = (90f - (float)num * 90f - (float)(index % 7) * 90f / 6f) * ((float)Math.PI / 180f); return val + new Vector2(Mathf.Cos(num2), Mathf.Sin(num2)) * radius; } private void AddVertex(VertexHelper mesh, Vector2 point, Rect rect, bool edge) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) float num = Mathf.InverseLerp(((Rect)(ref rect)).yMin, ((Rect)(ref rect)).yMax, point.y); float num2 = (edge ? Mathf.Lerp(0.5f, 1.18f, num) : Mathf.Lerp(0.76f, 1f, num)); Color val = default(Color); ((Color)(ref val))..ctor(((Graphic)this).color.r * num2, ((Graphic)this).color.g * num2, ((Graphic)this).color.b * num2, ((Graphic)this).color.a); Rect uvRect = ((RawImage)this).uvRect; float x = ((Rect)(ref uvRect)).x; float num3 = (point.x - ((Rect)(ref rect)).xMin) / ((Rect)(ref rect)).width; uvRect = ((RawImage)this).uvRect; float num4 = x + num3 * ((Rect)(ref uvRect)).width; uvRect = ((RawImage)this).uvRect; float y = ((Rect)(ref uvRect)).y; uvRect = ((RawImage)this).uvRect; Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor(num4, y + num * ((Rect)(ref uvRect)).height); mesh.AddVert(new Vector3(point.x, point.y, 0f), Color32.op_Implicit(val), val2); } } internal static class Compatibility { internal sealed class Query { private readonly FVRPhysicalObject target; private readonly List<FVRPhysicalObject> objects; private readonly List<FVRFireArmAttachmentMount> mounts; private readonly List<FVRFireArmReloadTriggerWell> magazineWells = new List<FVRFireArmReloadTriggerWell>(); private readonly List<FVRFireArmClipTriggerWell> clipWells = new List<FVRFireArmClipTriggerWell>(); private readonly CompatibilityRequirements requirements = new CompatibilityRequirements(); private readonly HashSet<int> mountTypes = new HashSet<int>(); private readonly CompatibleSelection selection; internal readonly string Signature; internal Query(FVRPhysicalObject held, CompatibleSelection selection = null) { //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Expected I4, but got Unknown //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Expected I4, but got Unknown //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Expected I4, but got Unknown //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Expected I4, but got Unknown //IL_0312: Unknown result type (might be due to invalid IL or missing references) //IL_031c: Expected I4, but got Unknown //IL_033a: Unknown result type (might be due to invalid IL or missing references) //IL_0344: Expected I4, but got Unknown this.selection = selection; if ((Object)(object)held == (Object)null) { throw new ArgumentNullException("held"); } target = held; objects = new List<FVRPhysicalObject>(Objects(held)); mounts = new List<FVRFireArmAttachmentMount>(Mounts(held, objects)); requirements.HasMount = mounts.Count > 0; FVRFireArmReloadTriggerWell[] componentsInChildren = ((Component)held).GetComponentsInChildren<FVRFireArmReloadTriggerWell>(true); foreach (FVRFireArmReloadTriggerWell val in componentsInChildren) { if (!((Object)(object)val == (Object)null) && BelongsTo(((Component)val).transform, held)) { magazineWells.Add(val); if (val.UsesTypeOverride) { requirements.MagazineTypes.Add((int)val.TypeOverride); } else if (val.IsAttachableWell && (Object)(object)val.AFireArm != (Object)null) { requirements.MagazineTypes.Add((int)val.AFireArm.MagazineType); } else if ((Object)(object)val.FireArm != (Object)null) { requirements.MagazineTypes.Add((int)val.FireArm.MagazineType); } } } FVRFireArmClipTriggerWell[] componentsInChildren2 = ((Component)held).GetComponentsInChildren<FVRFireArmClipTriggerWell>(true); foreach (FVRFireArmClipTriggerWell val2 in componentsInChildren2) { if (!((Object)(object)val2 == (Object)null) && BelongsTo(((Component)val2).transform, held)) { clipWells.Add(val2); if ((Object)(object)val2.FireArm != (Object)null) { requirements.ClipTypes.Add((int)val2.FireArm.ClipType); } } } foreach (FVRPhysicalObject @object in objects) { if (!((Object)(object)@object.ObjectWrapper != (Object)null) || @object.ObjectWrapper.CompatibleSpeedLoaders == null) { continue; } foreach (FVRObject compatibleSpeedLoader in @object.ObjectWrapper.CompatibleSpeedLoaders) { if ((Object)(object)compatibleSpeedLoader != (Object)null) { requirements.SpeedloaderIds.Add(compatibleSpeedLoader.ItemID); } } } requirements.CanMatchFirearm = held is FVRFireArmMagazine || held is FVRFireArmClip || held is Speedloader || held is FVRFireArmAttachment; StringBuilder stringBuilder = new StringBuilder(); foreach (FVRPhysicalObject object2 in objects) { stringBuilder.Append(((Object)object2).GetInstanceID()).Append(','); } foreach (FVRFireArmAttachmentMount mount in mounts) { mountTypes.Add((int)mount.Type); stringBuilder.Append('|').Append(((Object)mount).GetInstanceID()).Append(':') .Append((int)mount.Type) .Append(':') .Append((mount.AttachmentsList == null) ? (-1) : mount.AttachmentsList.Count); } foreach (int magazineType in requirements.MagazineTypes) { stringBuilder.Append("m").Append(magazineType); } foreach (int clipType in requirements.ClipTypes) { stringBuilder.Append("c").Append(clipType); } foreach (string speedloaderId in requirements.SpeedloaderIds) { stringBuilder.Append("s").Append(speedloaderId).Append(';'); } Signature = stringBuilder.ToString(); } internal List<CompatibilityKind> AvailableKinds() { List<CompatibilityKind> list = new List<CompatibilityKind>(); if (requirements.MagazineTypes.Count > 0) { list.Add(CompatibilityKind.Magazine); } if (mountTypes.Count > 0) { list.Add(CompatibilityKind.Attachment); } if (requirements.ClipTypes.Count > 0) { list.Add(CompatibilityKind.Clip); } if (requirements.SpeedloaderIds.Count > 0) { list.Add(CompatibilityKind.Speedloader); } if (requirements.CanMatchFirearm) { list.Add(CompatibilityKind.Firearm); } return list; } internal List<int> Connectors(CompatibilityKind kind) { List<int> list = new List<int>(kind switch { CompatibilityKind.Clip => requirements.ClipTypes, CompatibilityKind.Magazine => requirements.MagazineTypes, CompatibilityKind.Attachment => mountTypes, _ => new HashSet<int>(), }); list.Sort(); return list; } private bool Included(CompatibilityKind kind, int? connector = null) { if (selection == null) { return true; } if (!selection.Includes(kind, connector)) { return false; } if (connector.HasValue) { return true; } HashSet<int> hashSet = kind switch { CompatibilityKind.Clip => requirements.ClipTypes, CompatibilityKind.Magazine => requirements.MagazineTypes, CompatibilityKind.Attachment => mountTypes, _ => null, }; if (hashSet == null) { return true; } foreach (int item in hashSet) { if (selection.Includes(kind, item)) { return true; } } return false; } internal void Prefilter(List<ItemSpawnerID> candidates) { int num = 0; for (int i = 0; i < candidates.Count; i++) { if (CouldMatch(candidates[i], useIndex: true)) { candidates[num++] = candidates[i]; } } candidates.RemoveRange(num, candidates.Count - num); } internal bool CouldMatch(ItemSpawnerID entry, bool useIndex) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Expected I4, but got Unknown //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Expected I4, but got Unknown //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Expected I4, but got Unknown //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Expected I4, but got Unknown //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Expected I4, but got Unknown //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Expected I4, but got Unknown //IL_01ed: Unknown result type (might be due to invalid IL or missing references) //IL_01fa: Unknown result type (might be due to invalid IL or missing references) //IL_021b: Unknown result type (might be due to invalid IL or missing references) //IL_0225: Expected I4, but got Unknown //IL_020e: Unknown result type (might be due to invalid IL or missing references) //IL_0218: Expected I4, but got Unknown //IL_023c: Unknown result type (might be due to invalid IL or missing references) //IL_0242: Unknown result type (might be due to invalid IL or missing references) //IL_0252: Expected I4, but got Unknown //IL_0252: Expected I4, but got Unknown FVRObject val = (((Object)(object)entry == (Object)null) ? null : entry.MainObject); if ((Object)(object)val == (Object)null) { return false; } FVRPhysicalObject val2 = (useIndex ? ConnectorIndex.Find(val) : null); FVRFireArmAttachment val3 = (FVRFireArmAttachment)(object)((val2 is FVRFireArmAttachment) ? val2 : null); if ((Object)(object)val3 != (Object)null) { if (Included(CompatibilityKind.Attachment, (int)val3.Type)) { return mountTypes.Contains((int)val3.Type); } return false; } FVRFireArmMagazine val4 = (FVRFireArmMagazine)(object)((val2 is FVRFireArmMagazine) ? val2 : null); if ((Object)(object)val4 != (Object)null) { if (Included(CompatibilityKind.Magazine, (int)val4.MagazineType) && !val4.IsIntegrated) { return requirements.MagazineTypes.Contains((int)val4.MagazineType); } return false; } FVRFireArmClip val5 = (FVRFireArmClip)(object)((val2 is FVRFireArmClip) ? val2 : null); if ((Object)(object)val5 != (Object)null) { if (Included(CompatibilityKind.Clip, (int)val5.ClipType)) { return requirements.ClipTypes.Contains((int)val5.ClipType); } return false; } if (val2 is FVRFireArm) { if (Included(CompatibilityKind.Firearm)) { return requirements.CanMatchFirearm; } return false; } ConnectorFacts connectorFacts = ((useIndex && (Object)(object)val2 == (Object)null) ? PersistentConnectorIndex.Find(val) : null); if (connectorFacts != null) { if (connectorFacts.Kind == ConnectorKind.Attachment) { if (Included(CompatibilityKind.Attachment, connectorFacts.Connector)) { return mountTypes.Contains(connectorFacts.Connector); } return false; } if (connectorFacts.Kind == ConnectorKind.Magazine) { if (Included(CompatibilityKind.Magazine, connectorFacts.Connector) && !connectorFacts.Integrated) { return requirements.MagazineTypes.Contains(connectorFacts.Connector); } return false; } if (connectorFacts.Kind == ConnectorKind.Clip) { if (Included(CompatibilityKind.Clip, connectorFacts.Connector)) { return requirements.ClipTypes.Contains(connectorFacts.Connector); } return false; } } CompatibilityKind compatibilityKind = Kind(val); int? connector = ((compatibilityKind == CompatibilityKind.Magazine && (int)val.MagazineType != 0) ? new int?((int)val.MagazineType) : ((compatibilityKind == CompatibilityKind.Clip && (int)val.ClipType != 0) ? new int?((int)val.ClipType) : ((int?)null))); if (Included(compatibilityKind, connector)) { return requirements.CouldMatch(compatibilityKind, (int)val.MagazineType, (int)val.ClipType, val.ItemID); } return false; } internal bool Matches(GameObject candidate) { if ((Object)(object)target == (Object)null || (Object)(object)candidate == (Object)null) { return false; } FVRPhysicalObject component = candidate.GetComponent<FVRPhysicalObject>(); if ((Object)(object)component == (Object)null) { return false; } if (FitsOnto(component)) { return true; } if (Included(CompatibilityKind.Firearm) && requirements.CanMatchFirearm && component is FVRFireArm) { return Capture(component).FitsOnto(target); } return false; } private bool FitsOnto(FVRPhysicalObject candidate) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected I4, but got Unknown //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Expected I4, but got Unknown //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Expected I4, but got Unknown //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0220: Unknown result type (might be due to invalid IL or missing references) //IL_022e: Unknown result type (might be due to invalid IL or missing references) //IL_0234: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Expected I4, but got Unknown //IL_0190: Expected I4, but got Unknown FVRFireArmAttachment val = (FVRFireArmAttachment)(object)((candidate is FVRFireArmAttachment) ? candidate : null); if ((Object)(object)val != (Object)null && Included(CompatibilityKind.Attachment, (int)val.Type)) { if (!val.CanAttach()) { return false; } foreach (FVRFireArmAttachmentMount mount in mounts) { if ((Object)(object)mount != (Object)null && mount.Type == val.Type && mount.isMountableOn(val)) { return true; } } } FVRFireArmMagazine val2 = (FVRFireArmMagazine)(object)((candidate is FVRFireArmMagazine) ? candidate : null); if ((Object)(object)val2 != (Object)null && Included(CompatibilityKind.Magazine, (int)val2.MagazineType)) { if ((Object)(object)((Component)candidate).GetComponentInChildren<FVRFireArmReloadTriggerMag>(true) == (Object)null) { return false; } foreach (FVRFireArmReloadTriggerWell magazineWell in magazineWells) { if ((Object)(object)magazineWell == (Object)null) { continue; } FVRFireArm fireArm = magazineWell.FireArm; AttachableFirearm aFireArm = magazineWell.AFireArm; if (!(magazineWell.IsAttachableWell ? ((Object)(object)aFireArm == (Object)null) : ((Object)(object)fireArm == (Object)null))) { FireArmMagazineType val3 = (magazineWell.UsesTypeOverride ? magazineWell.TypeOverride : (magazineWell.IsAttachableWell ? aFireArm.MagazineType : fireArm.MagazineType)); if (SelectionPolicy.MagazineFits((int)val2.MagazineType, val2.IsIntegrated, val2.IsBeltBox, (int)val3, magazineWell.IsAttachableWell || magazineWell.UsesSecondaryMagSlots, magazineWell.IsBeltBox, (Object)(object)fireArm != (Object)null && fireArm.HasBelt)) { return true; } } } } FVRFireArmClip val4 = (FVRFireArmClip)(object)((candidate is FVRFireArmClip) ? candidate : null); if ((Object)(object)val4 != (Object)null && Included(CompatibilityKind.Clip, (int)val4.ClipType)) { if ((Object)(object)((Component)candidate).GetComponentInChildren<FVRFireArmClipTriggerClip>(true) == (Object)null) { return false; } foreach (FVRFireArmClipTriggerWell clipWell in clipWells) { if ((Object)(object)clipWell != (Object)null && (Object)(object)clipWell.FireArm != (Object)null && (int)val4.ClipType != 0 && clipWell.FireArm.ClipType == val4.ClipType) { return true; } } } Speedloader val5 = (Speedloader)(object)((candidate is Speedloader) ? candidate : null); if ((Object)(object)val5 != (Object)null && Included(CompatibilityKind.Speedloader)) { foreach (FVRPhysicalObject @object in objects) { if ((Object)(object)@object != (Object)null && Contains(((Object)(object)@object.ObjectWrapper == (Object)null) ? null : @object.ObjectWrapper.CompatibleSpeedLoaders, candidate.ObjectWrapper) && LoaderRoundMatches(val5, @object)) { return true; } } } return false; } } internal static FVRPhysicalObject HeldItem(FVRViveHand pointingHand = null) { if ((Object)(object)pointingHand != (Object)null) { if (!((Object)(object)pointingHand.OtherHand == (Object)null)) { return Resolve(pointingHand.OtherHand.CurrentInteractable); } return null; } if ((Object)(object)GM.CurrentMovementManager == (Object)null || GM.CurrentMovementManager.Hands == null) { return null; } FVRPhysicalObject val = null; FVRViveHand[] hands = GM.CurrentMovementManager.Hands; foreach (FVRViveHand val2 in hands) { if ((Object)(object)val2 == (Object)null) { continue; } FVRPhysicalObject val3 = Resolve(val2.CurrentInteractable); if (!((Object)(object)val3 == (Object)null)) { if ((Object)(object)val != (Object)null && (Object)(object)val != (Object)(object)val3) { return null; } val = val3; } } return val; } private static FVRPhysicalObject Resolve(FVRInteractiveObject item) { if ((Object)(object)item == (Object)null) { return null; } return (FVRPhysicalObject)(((object)((item is FVRPhysicalObject) ? item : null)) ?? ((object)((Component)item).GetComponentInParent<FVRPhysicalObject>())); } internal static string Name(FVRPhysicalObject item) { if ((Object)(object)item == (Object)null) { return "none"; } if (!((Object)(object)item.ObjectWrapper != (Object)null) || string.IsNullOrEmpty(item.ObjectWrapper.DisplayName)) { return ((Object)item).name.Replace("(Clone)", "").Trim(); } return item.ObjectWrapper.DisplayName; } private static CompatibilityKind Kind(FVRObject candidate) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Expected I4, but got Unknown if ((Object)(object)candidate == (Object)null) { return CompatibilityKind.Unsupported; } ObjectCategory category = candidate.Category; return (category - 1) switch { 0 => CompatibilityKind.Firearm, 4 => CompatibilityKind.Attachment, 1 => CompatibilityKind.Magazine, 2 => CompatibilityKind.Clip, 5 => CompatibilityKind.Speedloader, _ => CompatibilityKind.Unsupported, }; } internal static Query Capture(FVRPhysicalObject held) { return new Query(held); } internal static Query CaptureFiltered(FVRPhysicalObject held, CompatibleSelection selection) { return new Query(held, selection); } internal static bool Matches(FVRPhysicalObject held, GameObject candidate) { if ((Object)(object)held != (Object)null && (Object)(object)candidate != (Object)null) { return Capture(held).Matches(candidate); } return false; } private static bool LoaderRoundMatches(Speedloader loader, FVRPhysicalObject target) { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) if (loader.Chambers == null || loader.Chambers.Count == 0) { return false; } FVRFireArm val = (FVRFireArm)(object)((target is FVRFireArm) ? target : null); if ((Object)(object)val == (Object)null) { return false; } foreach (SpeedloaderChamber chamber in loader.Chambers) { if ((Object)(object)chamber == (Object)null || chamber.Type != val.RoundType) { return false; } } return true; } private static bool Contains(List<FVRObject> objects, FVRObject item) { if (objects == null || (Object)(object)item == (Object)null) { return false; } foreach (FVRObject @object in objects) { if ((Object)(object)@object != (Object)null && ((Object)(object)@object == (Object)(object)item || @object.ItemID == item.ItemID)) { return true; } } return false; } internal static IEnumerable<FVRPhysicalObject> Objects(FVRPhysicalObject root) { Queue<FVRPhysicalObject> queue = new Queue<FVRPhysicalObject>(); HashSet<FVRPhysicalObject> seen = new HashSet<FVRPhysicalObject>(); queue.Enqueue(root); while (queue.Count != 0) { FVRPhysicalObject obj = queue.Dequeue(); if ((Object)(object)obj == (Object)null || !seen.Add(obj)) { continue; } yield return obj; if (obj.Attachments != null) { foreach (FVRFireArmAttachment attachment in obj.Attachments) { if ((Object)(object)attachment != (Object)null) { queue.Enqueue((FVRPhysicalObject)(object)attachment); } } } if (obj.AttachmentMounts == null) { continue; } foreach (FVRFireArmAttachmentMount attachmentMount in obj.AttachmentMounts) { if (!((Object)(object)attachmentMount != (Object)null) || attachmentMount.AttachmentsList == null) { continue; } foreach (FVRFireArmAttachment attachments in attachmentMount.AttachmentsList) { if ((Object)(object)attachments != (Object)null) { queue.Enqueue((FVRPhysicalObject)(object)attachments); } } } } } private static IEnumerable<FVRFireArmAttachmentMount> Mounts(FVRPhysicalObject root, IEnumerable<FVRPhysicalObject> objects) { Queue<FVRFireArmAttachmentMount> queue = new Queue<FVRFireArmAttachmentMount>(); HashSet<FVRFireArmAttachmentMount> seen = new HashSet<FVRFireArmAttachmentMount>(); foreach (FVRPhysicalObject @object in objects) { if (@object.AttachmentMounts != null) { foreach (FVRFireArmAttachmentMount attachmentMount in @object.AttachmentMounts) { queue.Enqueue(attachmentMount); } } FVRFireArmAttachmentMount[] componentsInChildren = ((Component)@object).GetComponentsInChildren<FVRFireArmAttachmentMount>(true); foreach (FVRFireArmAttachmentMount val in componentsInChildren) { if (BelongsTo(((Component)val).transform, root)) { queue.Enqueue(val); } } } while (queue.Count != 0) { FVRFireArmAttachmentMount val2 = queue.Dequeue(); if ((Object)(object)val2 == (Object)null || !seen.Add(val2)) { continue; } if (val2.SubMounts != null) { foreach (FVRFireArmAttachmentMount subMount in val2.SubMounts) { queue.Enqueue(subMount); } } if (val2.AttachmentsList != null) { foreach (FVRFireArmAttachment attachments in val2.AttachmentsList) { if (!((Object)(object)attachments != (Object)null) || ((FVRPhysicalObject)attachments).AttachmentMounts == null) { continue; } foreach (FVRFireArmAttachmentMount attachmentMount2 in ((FVRPhysicalObject)attachments).AttachmentMounts) { queue.Enqueue(attachmentMount2); } } } Collider component = ((Component)val2).GetComponent<Collider>(); if (((Behaviour)val2).enabled && !((Object)(object)component == (Object)null) && component.enabled && ActiveToRoot(((Component)val2).transform, ((Component)root).transform)) { yield return val2; } } } private static bool ActiveToRoot(Transform current, Transform root) { while ((Object)(object)current != (Object)null) { if (!((Component)current).gameObject.activeSelf) { return false; } if ((Object)(object)current == (Object)(object)root) { return true; } current = current.parent; } return false; } private static bool BelongsTo(Transform current, FVRPhysicalObject root) { FVRPhysicalObject componentInParent = ((Component)current).GetComponentInParent<FVRPhysicalObject>(); if ((Object)(object)componentInParent == (Object)(object)root) { return true; } FVRFireArmAttachment val = (FVRFireArmAttachment)(object)((componentInParent is FVRFireArmAttachment) ? componentInParent : null); if ((Object)(object)val != (Object)null && (Object)(object)val.curMount != (Object)null) { return (Object)(object)val.GetRootObject() == (Object)(object)root; } return false; } } internal enum CompatibilityKind { Unsupported, Firearm, Attachment, Magazine, Clip, Speedloader } internal sealed class CompatibilityRequirements { internal readonly HashSet<int> MagazineTypes = new HashSet<int>(); internal readonly HashSet<int> ClipTypes = new HashSet<int>(); internal readonly HashSet<string> SpeedloaderIds = new HashSet<string>(StringComparer.Ordinal); internal bool HasMount; internal bool CanMatchFirearm; internal bool CouldMatch(CompatibilityKind kind, int magazineType, int clipType, string itemId) { switch (kind) { case CompatibilityKind.Attachment: return HasMount; case CompatibilityKind.Magazine: if (MagazineTypes.Count > 0) { if (magazineType != 0) { return MagazineTypes.Contains(magazineType); } return true; } return false; case CompatibilityKind.Clip: if (ClipTypes.Count > 0) { if (clipType != 0) { return ClipTypes.Contains(clipType); } return true; } return false; case CompatibilityKind.Speedloader: if (itemId != null) { return SpeedloaderIds.Contains(itemId); } return false; case CompatibilityKind.Firearm: return CanMatchFirearm; default: return false; } } } internal sealed class CompatiblePanel { internal const float ToggleWidth = 60f; private const float Width = 1200f; private const float Height = 1050f; private const int PageSize = 4; private readonly RandomizerController owner; private readonly GameObject template; private readonly RectTransform popup; private readonly RandomizerButton toggle; private readonly RandomizerButton section; private readonly RandomizerButton all; private readonly RandomizerButton previous; private readonly RandomizerButton next; private readonly List<RandomizerButton> kinds = new List<RandomizerButton>(); private readonly List<RandomizerButton> rows = new List<RandomizerButton>(); private readonly Text heldLabel; private readonly Text hint; private readonly Text connectorLabel; private readonly Text summary; private readonly Text pageLabel; private readonly List<KeyValuePair<CompatibilityKind, int>> connectors = new List<KeyValuePair<CompatibilityKind, int>>(); private readonly Dictionary<Transform, Vector3> topPositions = new Dictionary<Transform, Vector3>(); private List<CompatibilityKind> available = new List<CompatibilityKind>(); private Compatibility.Query query; private FVRPhysicalObject held; private string signature; private string displayedScope; private int page; private int revision = -1; internal bool IsOpen => ((Component)popup).gameObject.activeSelf; internal bool HasChoices { get; private set; } internal string ScopeDescription { get { if (!CompatibleSelection.Shared.AllItems) { return owner.ScopeDescription; } return "across all items"; } } internal string Tooltip { get { if (!toggle.Hovered) { return null; } return "Choose compatible item types and search scope for " + Compatibility.Name(held); } } internal CompatiblePanel(RandomizerController owner, RectTransform root, GameObject template, RandomizerButton roll, float left, float y) { //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_01e9: Unknown result type (might be due to invalid IL or missing references) //IL_0203: Unknown result type (might be due to invalid IL or missing references) //IL_021d: Unknown result type (might be due to invalid IL or missing references) //IL_0237: Unknown result type (might be due to invalid IL or missing references) //IL_0248: Unknown result type (might be due to invalid IL or missing references) //IL_025c: Unknown result type (might be due to invalid IL or missing references) //IL_0261: Unknown result type (might be due to invalid IL or missing references) //IL_0280: Unknown result type (might be due to invalid IL or missing references) //IL_02dd: Unknown result type (might be due to invalid IL or missing references) //IL_02e7: Unknown result type (might be due to invalid IL or missing references) //IL_02f1: Expected O, but got Unknown //IL_0331: Unknown result type (might be due to invalid IL or missing references) //IL_0337: Unknown result type (might be due to invalid IL or missing references) //IL_0343: Unknown result type (might be due to invalid IL or missing references) //IL_035d: Unknown result type (might be due to invalid IL or missing references) //IL_0376: Unknown result type (might be due to invalid IL or missing references) //IL_037b: Unknown result type (might be due to invalid IL or missing references) //IL_0380: Unknown result type (might be due to invalid IL or missing references) //IL_038f: Unknown result type (might be due to invalid IL or missing references) //IL_03ad: Unknown result type (might be due to invalid IL or missing references) //IL_03d6: Unknown result type (might be due to invalid IL or missing references) //IL_03fb: Unknown result type (might be due to invalid IL or missing references) //IL_0414: Unknown result type (might be due to invalid IL or missing references) //IL_0774: Unknown result type (might be due to invalid IL or missing references) //IL_077b: Expected O, but got Unknown //IL_07d5: Unknown result type (might be due to invalid IL or missing references) CompatiblePanel compatiblePanel = this; this.owner = owner; this.template = template; toggle = owner.CloneButton(template, root, "Compatible choices", compatible: false, left + 30f, y, 60f); toggle.Icon.Dropdown = true; ((Graphic)toggle.Icon).SetVerticesDirty(); toggle.Rainbow = false; toggle.NeedsHeldContext = true; toggle.Ready = () => owner.CanClick(compatible: true); toggle.Handler = delegate { if (compatiblePanel.IsOpen) { compatiblePanel.Hide(); } else { owner.CloseChoices(openingAmmo: false); compatiblePanel.SetOpen(open: true); compatiblePanel.Redraw(); } }; roll.Ready = () => owner.CanClick(compatible: true) && compatiblePanel.HasChoices; roll.Background.RoundRight = false; toggle.Background.RoundLeft = false; RectTransform rectTransform = ((Graphic)roll.Background).rectTransform; rectTransform.offsetMax = new Vector2(0f, rectTransform.offsetMax.y); rectTransform = ((Graphic)toggle.Background).rectTransform; rectTransform.offsetMin = new Vector2(0f, rectTransform.offsetMin.y); Image component = new GameObject("Group separator", new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(Image) }).GetComponent<Image>(); ((Component)component).gameObject.layer = template.layer; ((Transform)((Graphic)component).rectTransform).SetParent(((Component)toggle).transform, false); ((Graphic)component).rectTransform.anchorMin = Vector2.zero; ((Graphic)component).rectTransform.anchorMax = new Vector2(0f, 1f); ((Graphic)component).rectTransform.offsetMin = new Vector2(0f, 4f); ((Graphic)component).rectTransform.offsetMax = new Vector2(0.75f, -4f); RectTransform rectTransform2 = ((Graphic)component).rectTransform; ((Transform)rectTransform2).localPosition = ((Transform)rectTransform2).localPosition + new Vector3(0f, 0f, -0.015f); ((Graphic)component).color = new Color(0.65f, 0.68f, 0.7f, 0.6f); ((Graphic)component).raycastTarget = false; popup = (RectTransform)new GameObject("Gundomizer Compatible Choices", new Type[5] { typeof(RectTransform), typeof(CanvasRenderer), typeof(Image), typeof(BoxCollider), typeof(FVRPointable) }).transform; ((Component)popup).gameObject.layer = template.layer; ((Transform)popup).SetParent((Transform)(object)root, false); RectTransform obj = popup; RectTransform obj2 = popup; Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(0.5f, 0.5f); obj2.anchorMax = val; obj.anchorMin = val; popup.pivot = Vector2.zero; popup.sizeDelta = new Vector2(1200f, 1050f); RectTransform obj3 = popup; Rect rect = ((RectTransform)((Component)roll).transform).rect; ((Transform)obj3).localPosition = new Vector3(left - ((Rect)(ref rect)).width * Mathf.Abs(((Component)roll).transform.localScale.x), y + 95f, -8f); ((Graphic)((Component)popup).GetComponent<Image>()).color = new Color(0.025f, 0.03f, 0.04f, 1f); BoxCollider component2 = ((Component)popup).GetComponent<BoxCollider>(); component2.center = new Vector3(600f, 525f, 2f); component2.size = new Vector3(1200f, 1050f, 1f); ((Component)popup).GetComponent<FVRPointable>().MaxPointingRange = ((FVRPointable)roll).MaxPointingRange; Label("Title", "Compatible choices", 32f, 990f, 1000f, 70f, 46); Button("Close", "X", 1125f, 990f, 90f, delegate { compatiblePanel.Hide(); }); heldLabel = Label("Held", "", 32f, 930f, 1136f, 60f, 34); section = Button("Section", "Current section", 305f, 850f, 545f, delegate { compatiblePanel.SetScope(value: false); }); all = Button("All items", "All items", 895f, 850f, 545f, delegate { compatiblePanel.SetScope(value: true); }); hint = Label("Scope hint", "", 32f, 790f, 1136f, 65f, 30); Label("Include", "Include", 32f, 735f, 1136f, 50f, 34); for (int num = 0; num < 5; num++) { int slot = num; kinds.Add(Button("Kind " + num, "", 305 + num % 2 * 590, 675 - num / 2 * 78, 545f, delegate { compatiblePanel.ToggleKind(slot); })); } connectorLabel = Label("Connectors", "Connector choices", 32f, 430f, 1136f, 50f, 34); for (int num2 = 0; num2 < 4; num2++) { int slot2 = num2; RandomizerButton randomizerButton = Button("Connector " + num2, "", 600f, 360 - num2 * 75, 1136f, delegate { compatiblePanel.ToggleConnector(slot2); }); randomizerButton.Caption.alignment = (TextAnchor)3; rows.Add(randomizerButton); } previous = Button("Previous", "<", 780f, 95f, 140f, delegate { compatiblePanel.page--; compatiblePanel.Redraw(); }); next = Button("Next", ">", 1090f, 95f, 140f, delegate { compatiblePanel.page++; compatiblePanel.Redraw(); }); pageLabel = Label("Page", "", 860f, 95f, 160f, 60f, 32); pageLabel.alignment = (TextAnchor)4; summary = Label("Summary", "", 32f, 38f, 1136f, 62f, 29); foreach (Transform item in (Transform)popup) { Transform val2 = item; if ((Object)(object)val2 != (Object)(object)((Component)summary).transform && (Object)(object)val2 != (Object)(object)((Component)previous).transform && (Object)(object)val2 != (Object)(object)((Component)next).transform && (Object)(object)val2 != (Object)(object)((Component)pageLabel).transform) { topPositions.Add(val2, val2.localPosition); } } Hide(); } internal void Refresh(FVRPhysicalObject target) { Compatibility.Query query = (((Object)(object)target == (Object)null) ? null : Compatibility.Capture(target)); if (!((Object)(object)target == (Object)(object)held) || !(signature == query?.Signature)) { if ((Object)(object)target != (Object)(object)held) { Hide(); } held = target; this.query = query; signature = query?.Signature; page = 0; available = ((this.query == null) ? new List<CompatibilityKind>() : this.query.AvailableKinds()); Redraw(); } } internal void Update() { if (revision != CompatibleSelection.Shared.Revision || displayedScope != ScopeDescription) { Redraw(); } section.Caption.text = (CompatibleSelection.Shared.AllItems ? "[ ] " : "[x] ") + (owner.IsTagMode ? "Current tags" : "Current section"); } internal void Hide() { SetOpen(open: false); } private void SetOpen(bool open) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) ((Component)popup).gameObject.SetActive(open); ((Transform)((Graphic)toggle.Icon).rectTransform).localRotation = Quaternion.Euler(0f, 0f, (float)(open ? 180 : 0)); } private void SetScope(bool value) { CompatibleSelection.Shared.SetScope(value); Redraw(); } private void ToggleKind(int slot) { if (slot < available.Count) { CompatibilityKind kind = available[slot]; CompatibleSelection shared = CompatibleSelection.Shared; shared.Set(kind, null, !shared.Includes(kind)); page = 0; Redraw(); } } private void ToggleConnector(int slot) { int num = page * 4 + slot; if (num < connectors.Count) { KeyValuePair<CompatibilityKind, int> keyValuePair = connectors[num]; CompatibleSelection shared = CompatibleSelection.Shared; shared.Set(keyValuePair.Key, keyValuePair.Value, !shared.Includes(keyValuePair.Key, keyValuePair.Value)); Redraw(); } } private static string KindName(CompatibilityKind kind) { return kind switch { CompatibilityKind.Firearm => "Firearms", CompatibilityKind.Speedloader => "Speedloaders", _ => kind.ToString() + "s", }; } private static string ConnectorName(CompatibilityKind kind, int value) { string text = Enum.GetName(kind switch { CompatibilityKind.Magazine => typeof(FVRFireArmMagazine).GetField("MagazineType").FieldType, CompatibilityKind.Attachment => typeof(FVRFireArmAttachment).GetField("Type").FieldType, _ => typeof(FVRFireArmClip).GetField("ClipType").FieldType, }, value); if (text == null) { return "Custom connector " + value; } if (text.StartsWith("m", StringComparison.Ordinal) && text.Length > 1 && char.IsUpper(text[1])) { text = text.Substring(1); } return Regex.Replace(text.Replace('_', ' '), "([a-z])([A-Z])", "$1 $2"); } private void Redraw() { //IL_0244: Unknown result type (might be due to invalid IL or missing references) //IL_0271: Unknown result type (might be due to invalid IL or missing references) //IL_028c: Unknown result type (might be due to invalid IL or missing references) //IL_02b7: Unknown result type (might be due to invalid IL or missing references) //IL_02bc: Unknown result type (might be due to invalid IL or missing references) //IL_02c2: Unknown result type (might be due to invalid IL or missing references) //IL_02c7: Unknown result type (might be due to invalid IL or missing references) //IL_031e: Unknown result type (might be due to invalid IL or missing references) //IL_03cd: Unknown result type (might be due to invalid IL or missing references) CompatibleSelection shared = CompatibleSelection.Shared; revision = shared.Revision; displayedScope = ScopeDescription; heldLabel.text = "Held: " + Compatibility.Name(held); hint.text = (shared.AllItems ? "All categories, including modular magazines under Firearms." : "Use the spawner's current section or selected tags."); all.Caption.text = (shared.AllItems ? "[x] " : "[ ] ") + "All items"; connectors.Clear(); HasChoices = false; for (int i = 0; i < kinds.Count; i++) { ((Component)kinds[i]).gameObject.SetActive(i < available.Count); if (i >= available.Count) { continue; } CompatibilityKind compatibilityKind = available[i]; bool flag = shared.Includes(compatibilityKind); kinds[i].Caption.text = (flag ? "[x] " : "[ ] ") + KindName(compatibilityKind); if (!flag) { continue; } List<int> list = query.Connectors(compatibilityKind); if (list.Count == 0) { HasChoices = true; } foreach (int item in list) { connectors.Add(new KeyValuePair<CompatibilityKind, int>(compatibilityKind, item)); if (shared.Includes(compatibilityKind, item)) { HasChoices = true; } } } int num = Math.Max(1, (connectors.Count + 4 - 1) / 4); page = Math.Max(0, Math.Min(page, num - 1)); int num2 = Math.Min(4, Math.Max(0, connectors.Count - page * 4)); float num3 = (3 - (available.Count + 1) / 2) * 78 + (4 - num2) * 75; popup.sizeDelta = new Vector2(1200f, 1050f - num3); BoxCollider component = ((Component)popup).GetComponent<BoxCollider>(); component.center = new Vector3(600f, (1050f - num3) / 2f, 2f); component.size = new Vector3(1200f, 1050f - num3, 1f); foreach (KeyValuePair<Transform, Vector3> topPosition in topPositions) { topPosition.Key.localPosition = topPosition.Value - Vector3.up * num3; } float num4 = (float)(675 - (available.Count + 1) / 2 * 78) - num3; ((Transform)((Graphic)connectorLabel).rectTransform).localPosition = new Vector3(32f, num4, -1f); ((Component)connectorLabel).gameObject.SetActive(connectors.Count > 0); for (int j = 0; j < rows.Count; j++) { int num5 = page * 4 + j; ((Component)rows[j]).gameObject.SetActive(num5 < connectors.Count); if (num5 < connectors.Count) { KeyValuePair<CompatibilityKind, int> keyValuePair = connectors[num5]; ((Component)rows[j]).transform.localPosition = new Vector3(600f, num4 - 65f - (float)(j * 75), -1f); rows[j].Caption.text = (shared.Includes(keyValuePair.Key, keyValuePair.Value) ? " [x] " : " [ ] ") + keyValuePair.Key.ToString() + ": " + ConnectorName(keyValuePair.Key, keyValuePair.Value); } } ((Component)previous).gameObject.SetActive(page > 0); ((Component)next).gameObject.SetActive(page + 1 < num); pageLabel.text = ((num > 1) ? (page + 1 + " / " + num) : ""); summary.text = (HasChoices ? ("Next roll: compatible items " + ScopeDescription + ".") : (((Object)(object)held == (Object)null) ? "Hold an item to see its compatible types." : "No types selected or available. Enable a type to roll.")); } private Text Label(string name, string value, float x, float y, float width, float height, int size) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) Text component = new GameObject(name, new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(Text) }).GetComponent<Text>(); ((Component)component).gameObject.layer = template.layer; ((Transform)((Graphic)component).rectTransform).SetParent((Transform)(object)popup, false); RectTransform rectTransform = ((Graphic)component).rectTransform; Vector2 anchorMin = (((Graphic)component).rectTransform.anchorMax = Vector2.zero); rectTransform.anchorMin = anchorMin; ((Graphic)component).rectTransform.pivot = new Vector2(0f, 0.5f); ((Graphic)component).rectTransform.sizeDelta = new Vector2(width, height); ((Transform)((Graphic)component).rectTransform).localPosition = new Vector3(x, y, -1f); component.font = template.GetComponent<Text>().font; component.fontSize = size; component.text = value; component.supportRichText = false; ((Graphic)component).color = Color.white; component.alignment = (TextAnchor)3; ((Graphic)component).raycastTarget = false; component.horizontalOverflow = (HorizontalWrapMode)0; component.verticalOverflow = (VerticalWrapMode)0; return component; } private RandomizerButton Button(string name, string value, float x, float y, float width, Action<FVRViveHand> handler) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_0194: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_01ee: Unknown result type (might be due to invalid IL or missing references) RandomizerButton randomizerButton = owner.CloneButton(template, popup, "Compatible " + name, compatible: false, x, y, width); RectTransform val = (RectTransform)((Component)randomizerButton).transform; Vector2 anchorMin = (val.anchorMax = Vector2.zero); val.anchorMin = anchorMin; ((Transform)val).localPosition = new Vector3(x, y, -1f); BoxCollider component = ((Component)randomizerButton).GetComponent<BoxCollider>(); component.size = new Vector3(component.size.x, component.size.y * 0.55f, 0.25f); val.sizeDelta = new Vector2(val.sizeDelta.x, val.sizeDelta.y * 0.55f); ((Component)randomizerButton.Icon).gameObject.SetActive(false); randomizerButton.Rainbow = false; randomizerButton.Ready = () => owner.CanClick(compatible: false); randomizerButton.Handler = handler; Text component2 = new GameObject("Caption", new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(Text) }).GetComponent<Text>(); ((Component)component2).gameObject.layer = template.layer; ((Transform)((Graphic)component2).rectTransform).SetParent((Transform)(object)val, false); ((Graphic)component2).rectTransform.anchorMin = Vector2.zero; ((Graphic)component2).rectTransform.anchorMax = Vector2.one; ((Graphic)component2).rectTransform.offsetMin = new Vector2(12f, 0f); ((Graphic)component2).rectTransform.offsetMax = new Vector2(-12f, 0f); RectTransform rectTransform = ((Graphic)component2).rectTransform; ((Transform)rectTransform).localPosition = ((Transform)rectTransform).localPosition + new Vector3(0f, 0f, -0.02f); component2.font = template.GetComponent<Text>().font; component2.fontSize = 22; component2.text = value; ((Graphic)component2).color = Color.white; component2.alignment = (TextAnchor)4; component2.supportRichText = false; ((Graphic)component2).raycastTarget = false; component2.horizontalOverflow = (HorizontalWrapMode)0; component2.verticalOverflow = (VerticalWrapMode)0; randomizerButton.Caption = component2; return randomizerButton; } } internal sealed class CompatibleSelection { internal static readonly CompatibleSelection Shared = new CompatibleSelection(); private readonly HashSet<string> excluded = new HashSet<string>(StringComparer.Ordinal); internal bool AllItems { get; private set; } internal int Revision { get; private set; } private static string Key(CompatibilityKind kind, int? connector) { return kind.ToString() + ":" + (connector.HasValue ? connector.Value.ToString() : "*"); } internal bool Includes(CompatibilityKind kind, int? connector = null) { if (!excluded.Contains(Key(kind, null))) { if (connector.HasValue) { return !excluded.Contains(Key(kind, connector)); } return true; } return false; } internal void Set(CompatibilityKind kind, int? connector, bool include) { if (include ? excluded.Remove(Key(kind, connector)) : excluded.Add(Key(kind, connector))) { int revision = Revision + 1; Revision = revision; } } internal void SetScope(bool allItems) { if (AllItems != allItems) { AllItems = allItems; int revision = Revision + 1; Revision = revision; } } internal CompatibleSelection Snapshot() { CompatibleSelection compatibleSelection = new CompatibleSelection { AllItems = AllItems, Revision = Revision }; foreach (string item in excluded) { compatibleSelection.excluded.Add(item); } return compatibleSelection; } } internal static class ConnectorIndex { private sealed class Record { internal WeakReference Source; internal WeakReference Component; internal WeakReference Callback; } internal const int Capacity = 16384; private static readonly Dictionary<int, Record> records = new Dictionary<int, Record>(); private static readonly Queue<int> order = new Queue<int>(); private static bool running; internal static int Sweeps; internal static float MaxSliceMilliseconds; internal static int Count => records.Count; internal static void Observe(FVRObject source, GameObject prefab) { if ((Object)(object)source == (Object)null || (Object)(object)prefab == (Object)null) { return; } int instanceID = ((Object)source).GetInstanceID(); FVRPhysicalObject component = prefab.GetComponent<FVRPhysicalObject>(); if ((Object)(object)component == (Object)null) { return; } PersistentConnectorIndex.Observe(source, component); if (records.TryGetValue(instanceID, out var value)) { value.Source.Target = source; value.Component.Target = component; value.Callback.Target = AssetAccess.Cached(source); return; } if (records.Count >= 16384) { records.Remove(order.Dequeue()); } records.Add(instanceID, new Record { Source = new WeakReference(source), Component = new WeakReference(component), Callback = new WeakReference(AssetAccess.Cached(source)) }); order.Enqueue(instanceID); } internal static FVRPhysicalObject Find(FVRObject source) { if ((Object)(object)source == (Object)null) { return null; } GameObject val = AssetAccess.Peek(source); if ((Object)(object)val != (Object)null) { Observe(source, val); } if (!records.TryGetValue(((Object)source).GetInstanceID(), out var value) || (Object)/*isinst with value type is only supported in some contexts*/ != (Object)(object)source || value.Callback.Target != AssetAccess.Cached(source)) { return null; } object? target = value.Component.Target; FVRPhysicalObject val2 = (FVRPhysicalObject)((target is FVRPhysicalObject) ? target : null); if (!((Object)(object)val2 == (Object)null)) { return val2; } return null; } internal static void Start(MonoBehaviour host) { if (!running) { running = true; host.StartCoroutine(Sweep()); } } private static IEnumerator Sweep() { try { while (true) { Dictionary<string, FVRObject> dictionary = (((Object)(object)ManagerSingleton<IM>.Instance == (Object)null) ? null : IM.OD); if (dictionary != null && !GM.IsAsyncLoading) { Dictionary<string, FVRObject>.ValueCollection.Enumerator entries = dictionary.Values.GetEnumerator(); try { bool more = true; while (more) { float realtimeSinceStartup = Time.realtimeSinceStartup; int num = 0; do { try { more = entries.MoveNext(); } catch (InvalidOperationException) { more = false; } if (!more) { break; } FVRObject current = entries.Current; try { Observe(current, AssetAccess.Peek(current)); } catch (Exception ex2) { Plugin.Log.LogDebug((object)("Index entry unavailable: " + ex2.Message)); } } while (++num < 32 && Time.realtimeSinceStartup - realtimeSinceStartup < 0.00075f); MaxSliceMilliseconds = Mathf.Max(MaxSliceMilliseconds, (Time.realtimeSinceStartup -