Decompiled source of ULTRASKINS GC v4.0.0

ULTRASKINS/Iconic.Zlib.Netstandard.dll

Decompiled 6 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text;
using Ionic.Crc;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v1.3", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("https://github.com/HelloKitty")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("A .NETStandard port of Iconic.Zlib from DotNetZip project.")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("Iconic.Zlib.Netstandard")]
[assembly: AssemblyTitle("Iconic.Zlib.Netstandard")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace Ionic.Zlib
{
	internal enum BlockState
	{
		NeedMore,
		BlockDone,
		FinishStarted,
		FinishDone
	}
	internal enum DeflateFlavor
	{
		Store,
		Fast,
		Slow
	}
	internal sealed class DeflateManager
	{
		internal delegate BlockState CompressFunc(FlushType flush);

		internal class Config
		{
			internal int GoodLength;

			internal int MaxLazy;

			internal int NiceLength;

			internal int MaxChainLength;

			internal DeflateFlavor Flavor;

			private static readonly Config[] Table;

			private Config(int goodLength, int maxLazy, int niceLength, int maxChainLength, DeflateFlavor flavor)
			{
				GoodLength = goodLength;
				MaxLazy = maxLazy;
				NiceLength = niceLength;
				MaxChainLength = maxChainLength;
				Flavor = flavor;
			}

			public static Config Lookup(CompressionLevel level)
			{
				return Table[(int)level];
			}

			static Config()
			{
				Table = new Config[10]
				{
					new Config(0, 0, 0, 0, DeflateFlavor.Store),
					new Config(4, 4, 8, 4, DeflateFlavor.Fast),
					new Config(4, 5, 16, 8, DeflateFlavor.Fast),
					new Config(4, 6, 32, 32, DeflateFlavor.Fast),
					new Config(4, 4, 16, 16, DeflateFlavor.Slow),
					new Config(8, 16, 32, 32, DeflateFlavor.Slow),
					new Config(8, 16, 128, 128, DeflateFlavor.Slow),
					new Config(8, 32, 128, 256, DeflateFlavor.Slow),
					new Config(32, 128, 258, 1024, DeflateFlavor.Slow),
					new Config(32, 258, 258, 4096, DeflateFlavor.Slow)
				};
			}
		}

		private static readonly int MEM_LEVEL_MAX = 9;

		private static readonly int MEM_LEVEL_DEFAULT = 8;

		private CompressFunc DeflateFunction;

		private static readonly string[] _ErrorMessage = new string[10] { "need dictionary", "stream end", "", "file error", "stream error", "data error", "insufficient memory", "buffer error", "incompatible version", "" };

		private static readonly int PRESET_DICT = 32;

		private static readonly int INIT_STATE = 42;

		private static readonly int BUSY_STATE = 113;

		private static readonly int FINISH_STATE = 666;

		private static readonly int Z_DEFLATED = 8;

		private static readonly int STORED_BLOCK = 0;

		private static readonly int STATIC_TREES = 1;

		private static readonly int DYN_TREES = 2;

		private static readonly int Z_BINARY = 0;

		private static readonly int Z_ASCII = 1;

		private static readonly int Z_UNKNOWN = 2;

		private static readonly int Buf_size = 16;

		private static readonly int MIN_MATCH = 3;

		private static readonly int MAX_MATCH = 258;

		private static readonly int MIN_LOOKAHEAD = MAX_MATCH + MIN_MATCH + 1;

		private static readonly int HEAP_SIZE = 2 * InternalConstants.L_CODES + 1;

		private static readonly int END_BLOCK = 256;

		internal ZlibCodec _codec;

		internal int status;

		internal byte[] pending;

		internal int nextPending;

		internal int pendingCount;

		internal sbyte data_type;

		internal int last_flush;

		internal int w_size;

		internal int w_bits;

		internal int w_mask;

		internal byte[] window;

		internal int window_size;

		internal short[] prev;

		internal short[] head;

		internal int ins_h;

		internal int hash_size;

		internal int hash_bits;

		internal int hash_mask;

		internal int hash_shift;

		internal int block_start;

		private Config config;

		internal int match_length;

		internal int prev_match;

		internal int match_available;

		internal int strstart;

		internal int match_start;

		internal int lookahead;

		internal int prev_length;

		internal CompressionLevel compressionLevel;

		internal CompressionStrategy compressionStrategy;

		internal short[] dyn_ltree;

		internal short[] dyn_dtree;

		internal short[] bl_tree;

		internal Tree treeLiterals = new Tree();

		internal Tree treeDistances = new Tree();

		internal Tree treeBitLengths = new Tree();

		internal short[] bl_count = new short[InternalConstants.MAX_BITS + 1];

		internal int[] heap = new int[2 * InternalConstants.L_CODES + 1];

		internal int heap_len;

		internal int heap_max;

		internal sbyte[] depth = new sbyte[2 * InternalConstants.L_CODES + 1];

		internal int _lengthOffset;

		internal int lit_bufsize;

		internal int last_lit;

		internal int _distanceOffset;

		internal int opt_len;

		internal int static_len;

		internal int matches;

		internal int last_eob_len;

		internal short bi_buf;

		internal int bi_valid;

		private bool Rfc1950BytesEmitted;

		internal bool WantRfc1950HeaderBytes { get; set; } = true;


		internal DeflateManager()
		{
			dyn_ltree = new short[HEAP_SIZE * 2];
			dyn_dtree = new short[(2 * InternalConstants.D_CODES + 1) * 2];
			bl_tree = new short[(2 * InternalConstants.BL_CODES + 1) * 2];
		}

		private void _InitializeLazyMatch()
		{
			window_size = 2 * w_size;
			Array.Clear(head, 0, hash_size);
			config = Config.Lookup(compressionLevel);
			SetDeflater();
			strstart = 0;
			block_start = 0;
			lookahead = 0;
			match_length = (prev_length = MIN_MATCH - 1);
			match_available = 0;
			ins_h = 0;
		}

		private void _InitializeTreeData()
		{
			treeLiterals.dyn_tree = dyn_ltree;
			treeLiterals.staticTree = StaticTree.Literals;
			treeDistances.dyn_tree = dyn_dtree;
			treeDistances.staticTree = StaticTree.Distances;
			treeBitLengths.dyn_tree = bl_tree;
			treeBitLengths.staticTree = StaticTree.BitLengths;
			bi_buf = 0;
			bi_valid = 0;
			last_eob_len = 8;
			_InitializeBlocks();
		}

		internal void _InitializeBlocks()
		{
			for (int i = 0; i < InternalConstants.L_CODES; i++)
			{
				dyn_ltree[i * 2] = 0;
			}
			for (int j = 0; j < InternalConstants.D_CODES; j++)
			{
				dyn_dtree[j * 2] = 0;
			}
			for (int k = 0; k < InternalConstants.BL_CODES; k++)
			{
				bl_tree[k * 2] = 0;
			}
			dyn_ltree[END_BLOCK * 2] = 1;
			opt_len = (static_len = 0);
			last_lit = (matches = 0);
		}

		internal void pqdownheap(short[] tree, int k)
		{
			int num = heap[k];
			for (int num2 = k << 1; num2 <= heap_len; num2 <<= 1)
			{
				if (num2 < heap_len && _IsSmaller(tree, heap[num2 + 1], heap[num2], depth))
				{
					num2++;
				}
				if (_IsSmaller(tree, num, heap[num2], depth))
				{
					break;
				}
				heap[k] = heap[num2];
				k = num2;
			}
			heap[k] = num;
		}

		internal static bool _IsSmaller(short[] tree, int n, int m, sbyte[] depth)
		{
			short num = tree[n * 2];
			short num2 = tree[m * 2];
			if (num >= num2)
			{
				if (num == num2)
				{
					return depth[n] <= depth[m];
				}
				return false;
			}
			return true;
		}

		internal void scan_tree(short[] tree, int max_code)
		{
			int num = -1;
			int num2 = tree[1];
			int num3 = 0;
			int num4 = 7;
			int num5 = 4;
			if (num2 == 0)
			{
				num4 = 138;
				num5 = 3;
			}
			tree[(max_code + 1) * 2 + 1] = short.MaxValue;
			for (int i = 0; i <= max_code; i++)
			{
				int num6 = num2;
				num2 = tree[(i + 1) * 2 + 1];
				if (++num3 < num4 && num6 == num2)
				{
					continue;
				}
				if (num3 < num5)
				{
					bl_tree[num6 * 2] = (short)(bl_tree[num6 * 2] + num3);
				}
				else if (num6 != 0)
				{
					if (num6 != num)
					{
						bl_tree[num6 * 2]++;
					}
					bl_tree[InternalConstants.REP_3_6 * 2]++;
				}
				else if (num3 <= 10)
				{
					bl_tree[InternalConstants.REPZ_3_10 * 2]++;
				}
				else
				{
					bl_tree[InternalConstants.REPZ_11_138 * 2]++;
				}
				num3 = 0;
				num = num6;
				if (num2 == 0)
				{
					num4 = 138;
					num5 = 3;
				}
				else if (num6 == num2)
				{
					num4 = 6;
					num5 = 3;
				}
				else
				{
					num4 = 7;
					num5 = 4;
				}
			}
		}

		internal int build_bl_tree()
		{
			scan_tree(dyn_ltree, treeLiterals.max_code);
			scan_tree(dyn_dtree, treeDistances.max_code);
			treeBitLengths.build_tree(this);
			int num = InternalConstants.BL_CODES - 1;
			while (num >= 3 && bl_tree[Tree.bl_order[num] * 2 + 1] == 0)
			{
				num--;
			}
			opt_len += 3 * (num + 1) + 5 + 5 + 4;
			return num;
		}

		internal void send_all_trees(int lcodes, int dcodes, int blcodes)
		{
			send_bits(lcodes - 257, 5);
			send_bits(dcodes - 1, 5);
			send_bits(blcodes - 4, 4);
			for (int i = 0; i < blcodes; i++)
			{
				send_bits(bl_tree[Tree.bl_order[i] * 2 + 1], 3);
			}
			send_tree(dyn_ltree, lcodes - 1);
			send_tree(dyn_dtree, dcodes - 1);
		}

		internal void send_tree(short[] tree, int max_code)
		{
			int num = -1;
			int num2 = tree[1];
			int num3 = 0;
			int num4 = 7;
			int num5 = 4;
			if (num2 == 0)
			{
				num4 = 138;
				num5 = 3;
			}
			for (int i = 0; i <= max_code; i++)
			{
				int num6 = num2;
				num2 = tree[(i + 1) * 2 + 1];
				if (++num3 < num4 && num6 == num2)
				{
					continue;
				}
				if (num3 < num5)
				{
					do
					{
						send_code(num6, bl_tree);
					}
					while (--num3 != 0);
				}
				else if (num6 != 0)
				{
					if (num6 != num)
					{
						send_code(num6, bl_tree);
						num3--;
					}
					send_code(InternalConstants.REP_3_6, bl_tree);
					send_bits(num3 - 3, 2);
				}
				else if (num3 <= 10)
				{
					send_code(InternalConstants.REPZ_3_10, bl_tree);
					send_bits(num3 - 3, 3);
				}
				else
				{
					send_code(InternalConstants.REPZ_11_138, bl_tree);
					send_bits(num3 - 11, 7);
				}
				num3 = 0;
				num = num6;
				if (num2 == 0)
				{
					num4 = 138;
					num5 = 3;
				}
				else if (num6 == num2)
				{
					num4 = 6;
					num5 = 3;
				}
				else
				{
					num4 = 7;
					num5 = 4;
				}
			}
		}

		private void put_bytes(byte[] p, int start, int len)
		{
			Array.Copy(p, start, pending, pendingCount, len);
			pendingCount += len;
		}

		internal void send_code(int c, short[] tree)
		{
			int num = c * 2;
			send_bits(tree[num] & 0xFFFF, tree[num + 1] & 0xFFFF);
		}

		internal void send_bits(int value, int length)
		{
			if (bi_valid > Buf_size - length)
			{
				bi_buf |= (short)((value << bi_valid) & 0xFFFF);
				pending[pendingCount++] = (byte)bi_buf;
				pending[pendingCount++] = (byte)(bi_buf >> 8);
				bi_buf = (short)(value >>> Buf_size - bi_valid);
				bi_valid += length - Buf_size;
			}
			else
			{
				bi_buf |= (short)((value << bi_valid) & 0xFFFF);
				bi_valid += length;
			}
		}

		internal void _tr_align()
		{
			send_bits(STATIC_TREES << 1, 3);
			send_code(END_BLOCK, StaticTree.lengthAndLiteralsTreeCodes);
			bi_flush();
			if (1 + last_eob_len + 10 - bi_valid < 9)
			{
				send_bits(STATIC_TREES << 1, 3);
				send_code(END_BLOCK, StaticTree.lengthAndLiteralsTreeCodes);
				bi_flush();
			}
			last_eob_len = 7;
		}

		internal bool _tr_tally(int dist, int lc)
		{
			pending[_distanceOffset + last_lit * 2] = (byte)((uint)dist >> 8);
			pending[_distanceOffset + last_lit * 2 + 1] = (byte)dist;
			pending[_lengthOffset + last_lit] = (byte)lc;
			last_lit++;
			if (dist == 0)
			{
				dyn_ltree[lc * 2]++;
			}
			else
			{
				matches++;
				dist--;
				dyn_ltree[(Tree.LengthCode[lc] + InternalConstants.LITERALS + 1) * 2]++;
				dyn_dtree[Tree.DistanceCode(dist) * 2]++;
			}
			if ((last_lit & 0x1FFF) == 0 && compressionLevel > CompressionLevel.Level2)
			{
				int num = last_lit << 3;
				int num2 = strstart - block_start;
				for (int i = 0; i < InternalConstants.D_CODES; i++)
				{
					num = (int)(num + dyn_dtree[i * 2] * (5L + (long)Tree.ExtraDistanceBits[i]));
				}
				num >>= 3;
				if (matches < last_lit / 2 && num < num2 / 2)
				{
					return true;
				}
			}
			if (last_lit != lit_bufsize - 1)
			{
				return last_lit == lit_bufsize;
			}
			return true;
		}

		internal void send_compressed_block(short[] ltree, short[] dtree)
		{
			int num = 0;
			if (last_lit != 0)
			{
				do
				{
					int num2 = _distanceOffset + num * 2;
					int num3 = ((pending[num2] << 8) & 0xFF00) | (pending[num2 + 1] & 0xFF);
					int num4 = pending[_lengthOffset + num] & 0xFF;
					num++;
					if (num3 == 0)
					{
						send_code(num4, ltree);
						continue;
					}
					int num5 = Tree.LengthCode[num4];
					send_code(num5 + InternalConstants.LITERALS + 1, ltree);
					int num6 = Tree.ExtraLengthBits[num5];
					if (num6 != 0)
					{
						num4 -= Tree.LengthBase[num5];
						send_bits(num4, num6);
					}
					num3--;
					num5 = Tree.DistanceCode(num3);
					send_code(num5, dtree);
					num6 = Tree.ExtraDistanceBits[num5];
					if (num6 != 0)
					{
						num3 -= Tree.DistanceBase[num5];
						send_bits(num3, num6);
					}
				}
				while (num < last_lit);
			}
			send_code(END_BLOCK, ltree);
			last_eob_len = ltree[END_BLOCK * 2 + 1];
		}

		internal void set_data_type()
		{
			int i = 0;
			int num = 0;
			int num2 = 0;
			for (; i < 7; i++)
			{
				num2 += dyn_ltree[i * 2];
			}
			for (; i < 128; i++)
			{
				num += dyn_ltree[i * 2];
			}
			for (; i < InternalConstants.LITERALS; i++)
			{
				num2 += dyn_ltree[i * 2];
			}
			data_type = (sbyte)((num2 > num >> 2) ? Z_BINARY : Z_ASCII);
		}

		internal void bi_flush()
		{
			if (bi_valid == 16)
			{
				pending[pendingCount++] = (byte)bi_buf;
				pending[pendingCount++] = (byte)(bi_buf >> 8);
				bi_buf = 0;
				bi_valid = 0;
			}
			else if (bi_valid >= 8)
			{
				pending[pendingCount++] = (byte)bi_buf;
				bi_buf >>= 8;
				bi_valid -= 8;
			}
		}

		internal void bi_windup()
		{
			if (bi_valid > 8)
			{
				pending[pendingCount++] = (byte)bi_buf;
				pending[pendingCount++] = (byte)(bi_buf >> 8);
			}
			else if (bi_valid > 0)
			{
				pending[pendingCount++] = (byte)bi_buf;
			}
			bi_buf = 0;
			bi_valid = 0;
		}

		internal void copy_block(int buf, int len, bool header)
		{
			bi_windup();
			last_eob_len = 8;
			if (header)
			{
				pending[pendingCount++] = (byte)len;
				pending[pendingCount++] = (byte)(len >> 8);
				pending[pendingCount++] = (byte)(~len);
				pending[pendingCount++] = (byte)(~len >> 8);
			}
			put_bytes(window, buf, len);
		}

		internal void flush_block_only(bool eof)
		{
			_tr_flush_block((block_start >= 0) ? block_start : (-1), strstart - block_start, eof);
			block_start = strstart;
			_codec.flush_pending();
		}

		internal BlockState DeflateNone(FlushType flush)
		{
			int num = 65535;
			if (num > pending.Length - 5)
			{
				num = pending.Length - 5;
			}
			while (true)
			{
				if (lookahead <= 1)
				{
					_fillWindow();
					if (lookahead == 0 && flush == FlushType.None)
					{
						return BlockState.NeedMore;
					}
					if (lookahead == 0)
					{
						break;
					}
				}
				strstart += lookahead;
				lookahead = 0;
				int num2 = block_start + num;
				if (strstart == 0 || strstart >= num2)
				{
					lookahead = strstart - num2;
					strstart = num2;
					flush_block_only(eof: false);
					if (_codec.AvailableBytesOut == 0)
					{
						return BlockState.NeedMore;
					}
				}
				if (strstart - block_start >= w_size - MIN_LOOKAHEAD)
				{
					flush_block_only(eof: false);
					if (_codec.AvailableBytesOut == 0)
					{
						return BlockState.NeedMore;
					}
				}
			}
			flush_block_only(flush == FlushType.Finish);
			if (_codec.AvailableBytesOut == 0)
			{
				if (flush != FlushType.Finish)
				{
					return BlockState.NeedMore;
				}
				return BlockState.FinishStarted;
			}
			if (flush != FlushType.Finish)
			{
				return BlockState.BlockDone;
			}
			return BlockState.FinishDone;
		}

		internal void _tr_stored_block(int buf, int stored_len, bool eof)
		{
			send_bits((STORED_BLOCK << 1) + (eof ? 1 : 0), 3);
			copy_block(buf, stored_len, header: true);
		}

		internal void _tr_flush_block(int buf, int stored_len, bool eof)
		{
			int num = 0;
			int num2;
			int num3;
			if (compressionLevel > CompressionLevel.None)
			{
				if (data_type == Z_UNKNOWN)
				{
					set_data_type();
				}
				treeLiterals.build_tree(this);
				treeDistances.build_tree(this);
				num = build_bl_tree();
				num2 = opt_len + 3 + 7 >> 3;
				num3 = static_len + 3 + 7 >> 3;
				if (num3 <= num2)
				{
					num2 = num3;
				}
			}
			else
			{
				num2 = (num3 = stored_len + 5);
			}
			if (stored_len + 4 <= num2 && buf != -1)
			{
				_tr_stored_block(buf, stored_len, eof);
			}
			else if (num3 == num2)
			{
				send_bits((STATIC_TREES << 1) + (eof ? 1 : 0), 3);
				send_compressed_block(StaticTree.lengthAndLiteralsTreeCodes, StaticTree.distTreeCodes);
			}
			else
			{
				send_bits((DYN_TREES << 1) + (eof ? 1 : 0), 3);
				send_all_trees(treeLiterals.max_code + 1, treeDistances.max_code + 1, num + 1);
				send_compressed_block(dyn_ltree, dyn_dtree);
			}
			_InitializeBlocks();
			if (eof)
			{
				bi_windup();
			}
		}

		private void _fillWindow()
		{
			do
			{
				int num = window_size - lookahead - strstart;
				int num2;
				if (num == 0 && strstart == 0 && lookahead == 0)
				{
					num = w_size;
				}
				else if (num == -1)
				{
					num--;
				}
				else if (strstart >= w_size + w_size - MIN_LOOKAHEAD)
				{
					Array.Copy(window, w_size, window, 0, w_size);
					match_start -= w_size;
					strstart -= w_size;
					block_start -= w_size;
					num2 = hash_size;
					int num3 = num2;
					do
					{
						int num4 = head[--num3] & 0xFFFF;
						head[num3] = (short)((num4 >= w_size) ? (num4 - w_size) : 0);
					}
					while (--num2 != 0);
					num2 = w_size;
					num3 = num2;
					do
					{
						int num4 = prev[--num3] & 0xFFFF;
						prev[num3] = (short)((num4 >= w_size) ? (num4 - w_size) : 0);
					}
					while (--num2 != 0);
					num += w_size;
				}
				if (_codec.AvailableBytesIn == 0)
				{
					break;
				}
				num2 = _codec.read_buf(window, strstart + lookahead, num);
				lookahead += num2;
				if (lookahead >= MIN_MATCH)
				{
					ins_h = window[strstart] & 0xFF;
					ins_h = ((ins_h << hash_shift) ^ (window[strstart + 1] & 0xFF)) & hash_mask;
				}
			}
			while (lookahead < MIN_LOOKAHEAD && _codec.AvailableBytesIn != 0);
		}

		internal BlockState DeflateFast(FlushType flush)
		{
			int num = 0;
			while (true)
			{
				if (lookahead < MIN_LOOKAHEAD)
				{
					_fillWindow();
					if (lookahead < MIN_LOOKAHEAD && flush == FlushType.None)
					{
						return BlockState.NeedMore;
					}
					if (lookahead == 0)
					{
						break;
					}
				}
				if (lookahead >= MIN_MATCH)
				{
					ins_h = ((ins_h << hash_shift) ^ (window[strstart + (MIN_MATCH - 1)] & 0xFF)) & hash_mask;
					num = head[ins_h] & 0xFFFF;
					prev[strstart & w_mask] = head[ins_h];
					head[ins_h] = (short)strstart;
				}
				if (num != 0L && ((strstart - num) & 0xFFFF) <= w_size - MIN_LOOKAHEAD && compressionStrategy != CompressionStrategy.HuffmanOnly)
				{
					match_length = longest_match(num);
				}
				bool flag;
				if (match_length >= MIN_MATCH)
				{
					flag = _tr_tally(strstart - match_start, match_length - MIN_MATCH);
					lookahead -= match_length;
					if (match_length <= config.MaxLazy && lookahead >= MIN_MATCH)
					{
						match_length--;
						do
						{
							strstart++;
							ins_h = ((ins_h << hash_shift) ^ (window[strstart + (MIN_MATCH - 1)] & 0xFF)) & hash_mask;
							num = head[ins_h] & 0xFFFF;
							prev[strstart & w_mask] = head[ins_h];
							head[ins_h] = (short)strstart;
						}
						while (--match_length != 0);
						strstart++;
					}
					else
					{
						strstart += match_length;
						match_length = 0;
						ins_h = window[strstart] & 0xFF;
						ins_h = ((ins_h << hash_shift) ^ (window[strstart + 1] & 0xFF)) & hash_mask;
					}
				}
				else
				{
					flag = _tr_tally(0, window[strstart] & 0xFF);
					lookahead--;
					strstart++;
				}
				if (flag)
				{
					flush_block_only(eof: false);
					if (_codec.AvailableBytesOut == 0)
					{
						return BlockState.NeedMore;
					}
				}
			}
			flush_block_only(flush == FlushType.Finish);
			if (_codec.AvailableBytesOut == 0)
			{
				if (flush == FlushType.Finish)
				{
					return BlockState.FinishStarted;
				}
				return BlockState.NeedMore;
			}
			if (flush != FlushType.Finish)
			{
				return BlockState.BlockDone;
			}
			return BlockState.FinishDone;
		}

		internal BlockState DeflateSlow(FlushType flush)
		{
			int num = 0;
			while (true)
			{
				if (lookahead < MIN_LOOKAHEAD)
				{
					_fillWindow();
					if (lookahead < MIN_LOOKAHEAD && flush == FlushType.None)
					{
						return BlockState.NeedMore;
					}
					if (lookahead == 0)
					{
						break;
					}
				}
				if (lookahead >= MIN_MATCH)
				{
					ins_h = ((ins_h << hash_shift) ^ (window[strstart + (MIN_MATCH - 1)] & 0xFF)) & hash_mask;
					num = head[ins_h] & 0xFFFF;
					prev[strstart & w_mask] = head[ins_h];
					head[ins_h] = (short)strstart;
				}
				prev_length = match_length;
				prev_match = match_start;
				match_length = MIN_MATCH - 1;
				if (num != 0 && prev_length < config.MaxLazy && ((strstart - num) & 0xFFFF) <= w_size - MIN_LOOKAHEAD)
				{
					if (compressionStrategy != CompressionStrategy.HuffmanOnly)
					{
						match_length = longest_match(num);
					}
					if (match_length <= 5 && (compressionStrategy == CompressionStrategy.Filtered || (match_length == MIN_MATCH && strstart - match_start > 4096)))
					{
						match_length = MIN_MATCH - 1;
					}
				}
				if (prev_length >= MIN_MATCH && match_length <= prev_length)
				{
					int num2 = strstart + lookahead - MIN_MATCH;
					bool flag = _tr_tally(strstart - 1 - prev_match, prev_length - MIN_MATCH);
					lookahead -= prev_length - 1;
					prev_length -= 2;
					do
					{
						if (++strstart <= num2)
						{
							ins_h = ((ins_h << hash_shift) ^ (window[strstart + (MIN_MATCH - 1)] & 0xFF)) & hash_mask;
							num = head[ins_h] & 0xFFFF;
							prev[strstart & w_mask] = head[ins_h];
							head[ins_h] = (short)strstart;
						}
					}
					while (--prev_length != 0);
					match_available = 0;
					match_length = MIN_MATCH - 1;
					strstart++;
					if (flag)
					{
						flush_block_only(eof: false);
						if (_codec.AvailableBytesOut == 0)
						{
							return BlockState.NeedMore;
						}
					}
				}
				else if (match_available != 0)
				{
					if (_tr_tally(0, window[strstart - 1] & 0xFF))
					{
						flush_block_only(eof: false);
					}
					strstart++;
					lookahead--;
					if (_codec.AvailableBytesOut == 0)
					{
						return BlockState.NeedMore;
					}
				}
				else
				{
					match_available = 1;
					strstart++;
					lookahead--;
				}
			}
			if (match_available != 0)
			{
				bool flag = _tr_tally(0, window[strstart - 1] & 0xFF);
				match_available = 0;
			}
			flush_block_only(flush == FlushType.Finish);
			if (_codec.AvailableBytesOut == 0)
			{
				if (flush == FlushType.Finish)
				{
					return BlockState.FinishStarted;
				}
				return BlockState.NeedMore;
			}
			if (flush != FlushType.Finish)
			{
				return BlockState.BlockDone;
			}
			return BlockState.FinishDone;
		}

		internal int longest_match(int cur_match)
		{
			int num = config.MaxChainLength;
			int num2 = strstart;
			int num3 = prev_length;
			int num4 = ((strstart > w_size - MIN_LOOKAHEAD) ? (strstart - (w_size - MIN_LOOKAHEAD)) : 0);
			int niceLength = config.NiceLength;
			int num5 = w_mask;
			int num6 = strstart + MAX_MATCH;
			byte b = window[num2 + num3 - 1];
			byte b2 = window[num2 + num3];
			if (prev_length >= config.GoodLength)
			{
				num >>= 2;
			}
			if (niceLength > lookahead)
			{
				niceLength = lookahead;
			}
			do
			{
				int num7 = cur_match;
				if (window[num7 + num3] != b2 || window[num7 + num3 - 1] != b || window[num7] != window[num2] || window[++num7] != window[num2 + 1])
				{
					continue;
				}
				num2 += 2;
				num7++;
				while (window[++num2] == window[++num7] && window[++num2] == window[++num7] && window[++num2] == window[++num7] && window[++num2] == window[++num7] && window[++num2] == window[++num7] && window[++num2] == window[++num7] && window[++num2] == window[++num7] && window[++num2] == window[++num7] && num2 < num6)
				{
				}
				int num8 = MAX_MATCH - (num6 - num2);
				num2 = num6 - MAX_MATCH;
				if (num8 > num3)
				{
					match_start = cur_match;
					num3 = num8;
					if (num8 >= niceLength)
					{
						break;
					}
					b = window[num2 + num3 - 1];
					b2 = window[num2 + num3];
				}
			}
			while ((cur_match = prev[cur_match & num5] & 0xFFFF) > num4 && --num != 0);
			if (num3 <= lookahead)
			{
				return num3;
			}
			return lookahead;
		}

		internal int Initialize(ZlibCodec codec, CompressionLevel level)
		{
			return Initialize(codec, level, 15);
		}

		internal int Initialize(ZlibCodec codec, CompressionLevel level, int bits)
		{
			return Initialize(codec, level, bits, MEM_LEVEL_DEFAULT, CompressionStrategy.Default);
		}

		internal int Initialize(ZlibCodec codec, CompressionLevel level, int bits, CompressionStrategy compressionStrategy)
		{
			return Initialize(codec, level, bits, MEM_LEVEL_DEFAULT, compressionStrategy);
		}

		internal int Initialize(ZlibCodec codec, CompressionLevel level, int windowBits, int memLevel, CompressionStrategy strategy)
		{
			_codec = codec;
			_codec.Message = null;
			if (windowBits < 9 || windowBits > 15)
			{
				throw new ZlibException("windowBits must be in the range 9..15.");
			}
			if (memLevel < 1 || memLevel > MEM_LEVEL_MAX)
			{
				throw new ZlibException($"memLevel must be in the range 1.. {MEM_LEVEL_MAX}");
			}
			_codec.dstate = this;
			w_bits = windowBits;
			w_size = 1 << w_bits;
			w_mask = w_size - 1;
			hash_bits = memLevel + 7;
			hash_size = 1 << hash_bits;
			hash_mask = hash_size - 1;
			hash_shift = (hash_bits + MIN_MATCH - 1) / MIN_MATCH;
			window = new byte[w_size * 2];
			prev = new short[w_size];
			head = new short[hash_size];
			lit_bufsize = 1 << memLevel + 6;
			pending = new byte[lit_bufsize * 4];
			_distanceOffset = lit_bufsize;
			_lengthOffset = 3 * lit_bufsize;
			compressionLevel = level;
			compressionStrategy = strategy;
			Reset();
			return 0;
		}

		internal void Reset()
		{
			_codec.TotalBytesIn = (_codec.TotalBytesOut = 0L);
			_codec.Message = null;
			pendingCount = 0;
			nextPending = 0;
			Rfc1950BytesEmitted = false;
			status = (WantRfc1950HeaderBytes ? INIT_STATE : BUSY_STATE);
			_codec._Adler32 = Adler.Adler32(0u, null, 0, 0);
			last_flush = 0;
			_InitializeTreeData();
			_InitializeLazyMatch();
		}

		internal int End()
		{
			if (status != INIT_STATE && status != BUSY_STATE && status != FINISH_STATE)
			{
				return -2;
			}
			pending = null;
			head = null;
			prev = null;
			window = null;
			if (status != BUSY_STATE)
			{
				return 0;
			}
			return -3;
		}

		private void SetDeflater()
		{
			switch (config.Flavor)
			{
			case DeflateFlavor.Store:
				DeflateFunction = DeflateNone;
				break;
			case DeflateFlavor.Fast:
				DeflateFunction = DeflateFast;
				break;
			case DeflateFlavor.Slow:
				DeflateFunction = DeflateSlow;
				break;
			}
		}

		internal int SetParams(CompressionLevel level, CompressionStrategy strategy)
		{
			int result = 0;
			if (compressionLevel != level)
			{
				Config config = Config.Lookup(level);
				if (config.Flavor != this.config.Flavor && _codec.TotalBytesIn != 0L)
				{
					result = _codec.Deflate(FlushType.Partial);
				}
				compressionLevel = level;
				this.config = config;
				SetDeflater();
			}
			compressionStrategy = strategy;
			return result;
		}

		internal int SetDictionary(byte[] dictionary)
		{
			int num = dictionary.Length;
			int sourceIndex = 0;
			if (dictionary == null || status != INIT_STATE)
			{
				throw new ZlibException("Stream error.");
			}
			_codec._Adler32 = Adler.Adler32(_codec._Adler32, dictionary, 0, dictionary.Length);
			if (num < MIN_MATCH)
			{
				return 0;
			}
			if (num > w_size - MIN_LOOKAHEAD)
			{
				num = w_size - MIN_LOOKAHEAD;
				sourceIndex = dictionary.Length - num;
			}
			Array.Copy(dictionary, sourceIndex, window, 0, num);
			strstart = num;
			block_start = num;
			ins_h = window[0] & 0xFF;
			ins_h = ((ins_h << hash_shift) ^ (window[1] & 0xFF)) & hash_mask;
			for (int i = 0; i <= num - MIN_MATCH; i++)
			{
				ins_h = ((ins_h << hash_shift) ^ (window[i + (MIN_MATCH - 1)] & 0xFF)) & hash_mask;
				prev[i & w_mask] = head[ins_h];
				head[ins_h] = (short)i;
			}
			return 0;
		}

		internal int Deflate(FlushType flush)
		{
			if (_codec.OutputBuffer == null || (_codec.InputBuffer == null && _codec.AvailableBytesIn != 0) || (status == FINISH_STATE && flush != FlushType.Finish))
			{
				_codec.Message = _ErrorMessage[4];
				throw new ZlibException($"Something is fishy. [{_codec.Message}]");
			}
			if (_codec.AvailableBytesOut == 0)
			{
				_codec.Message = _ErrorMessage[7];
				throw new ZlibException("OutputBuffer is full (AvailableBytesOut == 0)");
			}
			int num = last_flush;
			last_flush = (int)flush;
			if (status == INIT_STATE)
			{
				int num2 = Z_DEFLATED + (w_bits - 8 << 4) << 8;
				int num3 = (int)((compressionLevel - 1) & (CompressionLevel)255) >> 1;
				if (num3 > 3)
				{
					num3 = 3;
				}
				num2 |= num3 << 6;
				if (strstart != 0)
				{
					num2 |= PRESET_DICT;
				}
				num2 += 31 - num2 % 31;
				status = BUSY_STATE;
				pending[pendingCount++] = (byte)(num2 >> 8);
				pending[pendingCount++] = (byte)num2;
				if (strstart != 0)
				{
					pending[pendingCount++] = (byte)((_codec._Adler32 & 0xFF000000u) >> 24);
					pending[pendingCount++] = (byte)((_codec._Adler32 & 0xFF0000) >> 16);
					pending[pendingCount++] = (byte)((_codec._Adler32 & 0xFF00) >> 8);
					pending[pendingCount++] = (byte)(_codec._Adler32 & 0xFFu);
				}
				_codec._Adler32 = Adler.Adler32(0u, null, 0, 0);
			}
			if (pendingCount != 0)
			{
				_codec.flush_pending();
				if (_codec.AvailableBytesOut == 0)
				{
					last_flush = -1;
					return 0;
				}
			}
			else if (_codec.AvailableBytesIn == 0 && (int)flush <= num && flush != FlushType.Finish)
			{
				return 0;
			}
			if (status == FINISH_STATE && _codec.AvailableBytesIn != 0)
			{
				_codec.Message = _ErrorMessage[7];
				throw new ZlibException("status == FINISH_STATE && _codec.AvailableBytesIn != 0");
			}
			if (_codec.AvailableBytesIn != 0 || lookahead != 0 || (flush != 0 && status != FINISH_STATE))
			{
				BlockState blockState = DeflateFunction(flush);
				if (blockState == BlockState.FinishStarted || blockState == BlockState.FinishDone)
				{
					status = FINISH_STATE;
				}
				switch (blockState)
				{
				case BlockState.NeedMore:
				case BlockState.FinishStarted:
					if (_codec.AvailableBytesOut == 0)
					{
						last_flush = -1;
					}
					return 0;
				case BlockState.BlockDone:
					if (flush == FlushType.Partial)
					{
						_tr_align();
					}
					else
					{
						_tr_stored_block(0, 0, eof: false);
						if (flush == FlushType.Full)
						{
							for (int i = 0; i < hash_size; i++)
							{
								head[i] = 0;
							}
						}
					}
					_codec.flush_pending();
					if (_codec.AvailableBytesOut == 0)
					{
						last_flush = -1;
						return 0;
					}
					break;
				}
			}
			if (flush != FlushType.Finish)
			{
				return 0;
			}
			if (!WantRfc1950HeaderBytes || Rfc1950BytesEmitted)
			{
				return 1;
			}
			pending[pendingCount++] = (byte)((_codec._Adler32 & 0xFF000000u) >> 24);
			pending[pendingCount++] = (byte)((_codec._Adler32 & 0xFF0000) >> 16);
			pending[pendingCount++] = (byte)((_codec._Adler32 & 0xFF00) >> 8);
			pending[pendingCount++] = (byte)(_codec._Adler32 & 0xFFu);
			_codec.flush_pending();
			Rfc1950BytesEmitted = true;
			if (pendingCount == 0)
			{
				return 1;
			}
			return 0;
		}
	}
	public class DeflateStream : Stream
	{
		internal ZlibBaseStream _baseStream;

		internal Stream _innerStream;

		private bool _disposed;

		public virtual FlushType FlushMode
		{
			get
			{
				return _baseStream._flushMode;
			}
			set
			{
				if (_disposed)
				{
					throw new ObjectDisposedException("DeflateStream");
				}
				_baseStream._flushMode = value;
			}
		}

		public int BufferSize
		{
			get
			{
				return _baseStream._bufferSize;
			}
			set
			{
				if (_disposed)
				{
					throw new ObjectDisposedException("DeflateStream");
				}
				if (_baseStream._workingBuffer != null)
				{
					throw new ZlibException("The working buffer is already set.");
				}
				if (value < 1024)
				{
					throw new ZlibException($"Don't be silly. {value} bytes?? Use a bigger buffer, at least {1024}.");
				}
				_baseStream._bufferSize = value;
			}
		}

		public CompressionStrategy Strategy
		{
			get
			{
				return _baseStream.Strategy;
			}
			set
			{
				if (_disposed)
				{
					throw new ObjectDisposedException("DeflateStream");
				}
				_baseStream.Strategy = value;
			}
		}

		public virtual long TotalIn => _baseStream._z.TotalBytesIn;

		public virtual long TotalOut => _baseStream._z.TotalBytesOut;

		public override bool CanRead
		{
			get
			{
				if (_disposed)
				{
					throw new ObjectDisposedException("DeflateStream");
				}
				return _baseStream._stream.CanRead;
			}
		}

		public override bool CanSeek => false;

		public override bool CanWrite
		{
			get
			{
				if (_disposed)
				{
					throw new ObjectDisposedException("DeflateStream");
				}
				return _baseStream._stream.CanWrite;
			}
		}

		public override long Length
		{
			get
			{
				throw new NotImplementedException();
			}
		}

		public override long Position
		{
			get
			{
				if (_baseStream._streamMode == ZlibBaseStream.StreamMode.Writer)
				{
					return _baseStream._z.TotalBytesOut;
				}
				if (_baseStream._streamMode == ZlibBaseStream.StreamMode.Reader)
				{
					return _baseStream._z.TotalBytesIn;
				}
				return 0L;
			}
			set
			{
				throw new NotImplementedException();
			}
		}

		public DeflateStream(Stream stream, CompressionMode mode)
			: this(stream, mode, CompressionLevel.Default, leaveOpen: false)
		{
		}

		public DeflateStream(Stream stream, CompressionMode mode, CompressionLevel level)
			: this(stream, mode, level, leaveOpen: false)
		{
		}

		public DeflateStream(Stream stream, CompressionMode mode, bool leaveOpen)
			: this(stream, mode, CompressionLevel.Default, leaveOpen)
		{
		}

		public DeflateStream(Stream stream, CompressionMode mode, CompressionLevel level, bool leaveOpen)
		{
			_innerStream = stream;
			_baseStream = new ZlibBaseStream(stream, mode, level, ZlibStreamFlavor.DEFLATE, leaveOpen);
		}

		protected override void Dispose(bool disposing)
		{
			try
			{
				if (!_disposed)
				{
					if (disposing)
					{
						_baseStream?.Dispose();
					}
					_disposed = true;
				}
			}
			finally
			{
				base.Dispose(disposing);
			}
		}

		public override void Flush()
		{
			if (_disposed)
			{
				throw new ObjectDisposedException("DeflateStream");
			}
			_baseStream.Flush();
		}

		public override int Read(byte[] buffer, int offset, int count)
		{
			if (_disposed)
			{
				throw new ObjectDisposedException("DeflateStream");
			}
			return _baseStream.Read(buffer, offset, count);
		}

		public override long Seek(long offset, SeekOrigin origin)
		{
			throw new NotImplementedException();
		}

		public override void SetLength(long value)
		{
			throw new NotImplementedException();
		}

		public override void Write(byte[] buffer, int offset, int count)
		{
			if (_disposed)
			{
				throw new ObjectDisposedException("DeflateStream");
			}
			_baseStream.Write(buffer, offset, count);
		}

		public static byte[] CompressString(string s)
		{
			using MemoryStream memoryStream = new MemoryStream();
			Stream compressor = new DeflateStream(memoryStream, CompressionMode.Compress, CompressionLevel.BestCompression);
			ZlibBaseStream.CompressString(s, compressor);
			return memoryStream.ToArray();
		}

		public static byte[] CompressBuffer(byte[] b)
		{
			using MemoryStream memoryStream = new MemoryStream();
			Stream compressor = new DeflateStream(memoryStream, CompressionMode.Compress, CompressionLevel.BestCompression);
			ZlibBaseStream.CompressBuffer(b, compressor);
			return memoryStream.ToArray();
		}

		public static string UncompressString(byte[] compressed)
		{
			using MemoryStream stream = new MemoryStream(compressed);
			Stream decompressor = new DeflateStream(stream, CompressionMode.Decompress);
			return ZlibBaseStream.UncompressString(compressed, decompressor);
		}

		public static byte[] UncompressBuffer(byte[] compressed)
		{
			using MemoryStream stream = new MemoryStream(compressed);
			Stream decompressor = new DeflateStream(stream, CompressionMode.Decompress);
			return ZlibBaseStream.UncompressBuffer(compressed, decompressor);
		}
	}
	public class GZipStream : Stream, IDisposable
	{
		public DateTime? LastModified;

		private int _headerByteCount;

		internal ZlibBaseStream _baseStream;

		private bool _disposed;

		private bool _firstReadDone;

		private string _FileName;

		private string _Comment;

		private int _Crc32;

		internal static readonly DateTime _unixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);

		internal static readonly Encoding iso8859dash1 = Encoding.GetEncoding("iso-8859-1");

		public string Comment
		{
			get
			{
				return _Comment;
			}
			set
			{
				if (_disposed)
				{
					throw new ObjectDisposedException("GZipStream");
				}
				_Comment = value;
			}
		}

		public string FileName
		{
			get
			{
				return _FileName;
			}
			set
			{
				if (_disposed)
				{
					throw new ObjectDisposedException("GZipStream");
				}
				_FileName = value;
				if (_FileName != null)
				{
					if (_FileName.IndexOf("/") != -1)
					{
						_FileName = _FileName.Replace("/", "\\");
					}
					if (_FileName.EndsWith("\\"))
					{
						throw new Exception("Illegal filename");
					}
					if (_FileName.IndexOf("\\") != -1)
					{
						_FileName = Path.GetFileName(_FileName);
					}
				}
			}
		}

		public int Crc32 => _Crc32;

		public virtual FlushType FlushMode
		{
			get
			{
				return _baseStream._flushMode;
			}
			set
			{
				if (_disposed)
				{
					throw new ObjectDisposedException("GZipStream");
				}
				_baseStream._flushMode = value;
			}
		}

		public int BufferSize
		{
			get
			{
				return _baseStream._bufferSize;
			}
			set
			{
				if (_disposed)
				{
					throw new ObjectDisposedException("GZipStream");
				}
				if (_baseStream._workingBuffer != null)
				{
					throw new ZlibException("The working buffer is already set.");
				}
				if (value < 1024)
				{
					throw new ZlibException($"Don't be silly. {value} bytes?? Use a bigger buffer, at least {1024}.");
				}
				_baseStream._bufferSize = value;
			}
		}

		public virtual long TotalIn => _baseStream._z.TotalBytesIn;

		public virtual long TotalOut => _baseStream._z.TotalBytesOut;

		public override bool CanRead
		{
			get
			{
				if (_disposed)
				{
					throw new ObjectDisposedException("GZipStream");
				}
				return _baseStream._stream.CanRead;
			}
		}

		public override bool CanSeek => false;

		public override bool CanWrite
		{
			get
			{
				if (_disposed)
				{
					throw new ObjectDisposedException("GZipStream");
				}
				return _baseStream._stream.CanWrite;
			}
		}

		public override long Length
		{
			get
			{
				throw new NotImplementedException();
			}
		}

		public override long Position
		{
			get
			{
				if (_baseStream._streamMode == ZlibBaseStream.StreamMode.Writer)
				{
					return _baseStream._z.TotalBytesOut + _headerByteCount;
				}
				if (_baseStream._streamMode == ZlibBaseStream.StreamMode.Reader)
				{
					return _baseStream._z.TotalBytesIn + _baseStream._gzipHeaderByteCount;
				}
				return 0L;
			}
			set
			{
				throw new NotImplementedException();
			}
		}

		public GZipStream(Stream stream, CompressionMode mode)
			: this(stream, mode, CompressionLevel.Default, leaveOpen: false)
		{
		}

		public GZipStream(Stream stream, CompressionMode mode, CompressionLevel level)
			: this(stream, mode, level, leaveOpen: false)
		{
		}

		public GZipStream(Stream stream, CompressionMode mode, bool leaveOpen)
			: this(stream, mode, CompressionLevel.Default, leaveOpen)
		{
		}

		public GZipStream(Stream stream, CompressionMode mode, CompressionLevel level, bool leaveOpen)
		{
			_baseStream = new ZlibBaseStream(stream, mode, level, ZlibStreamFlavor.GZIP, leaveOpen);
		}

		protected override void Dispose(bool disposing)
		{
			try
			{
				if (!_disposed)
				{
					if (disposing && _baseStream != null)
					{
						_baseStream.Dispose();
						_Crc32 = _baseStream.Crc32;
					}
					_disposed = true;
				}
			}
			finally
			{
				base.Dispose(disposing);
			}
		}

		public override void Flush()
		{
			if (_disposed)
			{
				throw new ObjectDisposedException("GZipStream");
			}
			_baseStream.Flush();
		}

		public override int Read(byte[] buffer, int offset, int count)
		{
			if (_disposed)
			{
				throw new ObjectDisposedException("GZipStream");
			}
			int result = _baseStream.Read(buffer, offset, count);
			if (!_firstReadDone)
			{
				_firstReadDone = true;
				FileName = _baseStream._GzipFileName;
				Comment = _baseStream._GzipComment;
			}
			return result;
		}

		public override long Seek(long offset, SeekOrigin origin)
		{
			throw new NotImplementedException();
		}

		public override void SetLength(long value)
		{
			throw new NotImplementedException();
		}

		public override void Write(byte[] buffer, int offset, int count)
		{
			if (_disposed)
			{
				throw new ObjectDisposedException("GZipStream");
			}
			if (_baseStream._streamMode == ZlibBaseStream.StreamMode.Undefined)
			{
				if (!_baseStream._wantCompress)
				{
					throw new InvalidOperationException();
				}
				_headerByteCount = EmitHeader();
			}
			_baseStream.Write(buffer, offset, count);
		}

		private int EmitHeader()
		{
			byte[] array = ((Comment == null) ? null : iso8859dash1.GetBytes(Comment));
			byte[] array2 = ((FileName == null) ? null : iso8859dash1.GetBytes(FileName));
			int num = ((Comment != null) ? (array.Length + 1) : 0);
			int num2 = ((FileName != null) ? (array2.Length + 1) : 0);
			byte[] array3 = new byte[10 + num + num2];
			int num3 = 0;
			array3[num3++] = 31;
			array3[num3++] = 139;
			array3[num3++] = 8;
			byte b = 0;
			if (Comment != null)
			{
				b = (byte)(b ^ 0x10u);
			}
			if (FileName != null)
			{
				b = (byte)(b ^ 8u);
			}
			array3[num3++] = b;
			if (!LastModified.HasValue)
			{
				LastModified = DateTime.Now;
			}
			Array.Copy(BitConverter.GetBytes((int)(LastModified.Value - _unixEpoch).TotalSeconds), 0, array3, num3, 4);
			num3 += 4;
			array3[num3++] = 0;
			array3[num3++] = byte.MaxValue;
			if (num2 != 0)
			{
				Array.Copy(array2, 0, array3, num3, num2 - 1);
				num3 += num2 - 1;
				array3[num3++] = 0;
			}
			if (num != 0)
			{
				Array.Copy(array, 0, array3, num3, num - 1);
				num3 += num - 1;
				array3[num3++] = 0;
			}
			_baseStream._stream.Write(array3, 0, array3.Length);
			return array3.Length;
		}

		public static byte[] CompressString(string s)
		{
			using MemoryStream memoryStream = new MemoryStream();
			Stream compressor = new GZipStream(memoryStream, CompressionMode.Compress, CompressionLevel.BestCompression);
			ZlibBaseStream.CompressString(s, compressor);
			return memoryStream.ToArray();
		}

		public static byte[] CompressBuffer(byte[] b)
		{
			using MemoryStream memoryStream = new MemoryStream();
			Stream compressor = new GZipStream(memoryStream, CompressionMode.Compress, CompressionLevel.BestCompression);
			ZlibBaseStream.CompressBuffer(b, compressor);
			return memoryStream.ToArray();
		}

		public static string UncompressString(byte[] compressed)
		{
			using MemoryStream stream = new MemoryStream(compressed);
			Stream decompressor = new GZipStream(stream, CompressionMode.Decompress);
			return ZlibBaseStream.UncompressString(compressed, decompressor);
		}

		public static byte[] UncompressBuffer(byte[] compressed)
		{
			using MemoryStream stream = new MemoryStream(compressed);
			Stream decompressor = new GZipStream(stream, CompressionMode.Decompress);
			return ZlibBaseStream.UncompressBuffer(compressed, decompressor);
		}
	}
	internal sealed class InflateBlocks
	{
		private enum InflateBlockMode
		{
			TYPE,
			LENS,
			STORED,
			TABLE,
			BTREE,
			DTREE,
			CODES,
			DRY,
			DONE,
			BAD
		}

		private const int MANY = 1440;

		internal static readonly int[] border = new int[19]
		{
			16, 17, 18, 0, 8, 7, 9, 6, 10, 5,
			11, 4, 12, 3, 13, 2, 14, 1, 15
		};

		private InflateBlockMode mode;

		internal int left;

		internal int table;

		internal int index;

		internal int[] blens;

		internal int[] bb = new int[1];

		internal int[] tb = new int[1];

		internal InflateCodes codes = new InflateCodes();

		internal int last;

		internal ZlibCodec _codec;

		internal int bitk;

		internal int bitb;

		internal int[] hufts;

		internal byte[] window;

		internal int end;

		internal int readAt;

		internal int writeAt;

		internal object checkfn;

		internal uint check;

		internal InfTree inftree = new InfTree();

		internal InflateBlocks(ZlibCodec codec, object checkfn, int w)
		{
			_codec = codec;
			hufts = new int[4320];
			window = new byte[w];
			end = w;
			this.checkfn = checkfn;
			mode = InflateBlockMode.TYPE;
			Reset();
		}

		internal uint Reset()
		{
			uint result = check;
			mode = InflateBlockMode.TYPE;
			bitk = 0;
			bitb = 0;
			readAt = (writeAt = 0);
			if (checkfn != null)
			{
				_codec._Adler32 = (check = Adler.Adler32(0u, null, 0, 0));
			}
			return result;
		}

		internal int Process(int r)
		{
			int num = _codec.NextIn;
			int num2 = _codec.AvailableBytesIn;
			int num3 = bitb;
			int i = bitk;
			int num4 = writeAt;
			int num5 = ((num4 < readAt) ? (readAt - num4 - 1) : (end - num4));
			while (true)
			{
				switch (mode)
				{
				case InflateBlockMode.TYPE:
				{
					for (; i < 3; i += 8)
					{
						if (num2 != 0)
						{
							r = 0;
							num2--;
							num3 |= (_codec.InputBuffer[num++] & 0xFF) << i;
							continue;
						}
						bitb = num3;
						bitk = i;
						_codec.AvailableBytesIn = num2;
						_codec.TotalBytesIn += num - _codec.NextIn;
						_codec.NextIn = num;
						writeAt = num4;
						return Flush(r);
					}
					int num6 = num3 & 7;
					last = num6 & 1;
					switch ((uint)(num6 >>> 1))
					{
					case 0u:
						num3 >>= 3;
						i -= 3;
						num6 = i & 7;
						num3 >>= num6;
						i -= num6;
						mode = InflateBlockMode.LENS;
						break;
					case 1u:
					{
						int[] array = new int[1];
						int[] array2 = new int[1];
						int[][] array3 = new int[1][];
						int[][] array4 = new int[1][];
						InfTree.inflate_trees_fixed(array, array2, array3, array4, _codec);
						codes.Init(array[0], array2[0], array3[0], 0, array4[0], 0);
						num3 >>= 3;
						i -= 3;
						mode = InflateBlockMode.CODES;
						break;
					}
					case 2u:
						num3 >>= 3;
						i -= 3;
						mode = InflateBlockMode.TABLE;
						break;
					case 3u:
						num3 >>= 3;
						i -= 3;
						mode = InflateBlockMode.BAD;
						_codec.Message = "invalid block type";
						r = -3;
						bitb = num3;
						bitk = i;
						_codec.AvailableBytesIn = num2;
						_codec.TotalBytesIn += num - _codec.NextIn;
						_codec.NextIn = num;
						writeAt = num4;
						return Flush(r);
					}
					break;
				}
				case InflateBlockMode.LENS:
					for (; i < 32; i += 8)
					{
						if (num2 != 0)
						{
							r = 0;
							num2--;
							num3 |= (_codec.InputBuffer[num++] & 0xFF) << i;
							continue;
						}
						bitb = num3;
						bitk = i;
						_codec.AvailableBytesIn = num2;
						_codec.TotalBytesIn += num - _codec.NextIn;
						_codec.NextIn = num;
						writeAt = num4;
						return Flush(r);
					}
					if (((~num3 >> 16) & 0xFFFF) != (num3 & 0xFFFF))
					{
						mode = InflateBlockMode.BAD;
						_codec.Message = "invalid stored block lengths";
						r = -3;
						bitb = num3;
						bitk = i;
						_codec.AvailableBytesIn = num2;
						_codec.TotalBytesIn += num - _codec.NextIn;
						_codec.NextIn = num;
						writeAt = num4;
						return Flush(r);
					}
					left = num3 & 0xFFFF;
					num3 = (i = 0);
					mode = ((left != 0) ? InflateBlockMode.STORED : ((last != 0) ? InflateBlockMode.DRY : InflateBlockMode.TYPE));
					break;
				case InflateBlockMode.STORED:
				{
					if (num2 == 0)
					{
						bitb = num3;
						bitk = i;
						_codec.AvailableBytesIn = num2;
						_codec.TotalBytesIn += num - _codec.NextIn;
						_codec.NextIn = num;
						writeAt = num4;
						return Flush(r);
					}
					if (num5 == 0)
					{
						if (num4 == end && readAt != 0)
						{
							num4 = 0;
							num5 = ((num4 < readAt) ? (readAt - num4 - 1) : (end - num4));
						}
						if (num5 == 0)
						{
							writeAt = num4;
							r = Flush(r);
							num4 = writeAt;
							num5 = ((num4 < readAt) ? (readAt - num4 - 1) : (end - num4));
							if (num4 == end && readAt != 0)
							{
								num4 = 0;
								num5 = ((num4 < readAt) ? (readAt - num4 - 1) : (end - num4));
							}
							if (num5 == 0)
							{
								bitb = num3;
								bitk = i;
								_codec.AvailableBytesIn = num2;
								_codec.TotalBytesIn += num - _codec.NextIn;
								_codec.NextIn = num;
								writeAt = num4;
								return Flush(r);
							}
						}
					}
					r = 0;
					int num6 = left;
					if (num6 > num2)
					{
						num6 = num2;
					}
					if (num6 > num5)
					{
						num6 = num5;
					}
					Array.Copy(_codec.InputBuffer, num, window, num4, num6);
					num += num6;
					num2 -= num6;
					num4 += num6;
					num5 -= num6;
					if ((left -= num6) == 0)
					{
						mode = ((last != 0) ? InflateBlockMode.DRY : InflateBlockMode.TYPE);
					}
					break;
				}
				case InflateBlockMode.TABLE:
				{
					for (; i < 14; i += 8)
					{
						if (num2 != 0)
						{
							r = 0;
							num2--;
							num3 |= (_codec.InputBuffer[num++] & 0xFF) << i;
							continue;
						}
						bitb = num3;
						bitk = i;
						_codec.AvailableBytesIn = num2;
						_codec.TotalBytesIn += num - _codec.NextIn;
						_codec.NextIn = num;
						writeAt = num4;
						return Flush(r);
					}
					int num6 = (table = num3 & 0x3FFF);
					if ((num6 & 0x1F) > 29 || ((num6 >> 5) & 0x1F) > 29)
					{
						mode = InflateBlockMode.BAD;
						_codec.Message = "too many length or distance symbols";
						r = -3;
						bitb = num3;
						bitk = i;
						_codec.AvailableBytesIn = num2;
						_codec.TotalBytesIn += num - _codec.NextIn;
						_codec.NextIn = num;
						writeAt = num4;
						return Flush(r);
					}
					num6 = 258 + (num6 & 0x1F) + ((num6 >> 5) & 0x1F);
					if (blens == null || blens.Length < num6)
					{
						blens = new int[num6];
					}
					else
					{
						Array.Clear(blens, 0, num6);
					}
					num3 >>= 14;
					i -= 14;
					index = 0;
					mode = InflateBlockMode.BTREE;
					goto case InflateBlockMode.BTREE;
				}
				case InflateBlockMode.BTREE:
				{
					while (index < 4 + (table >> 10))
					{
						for (; i < 3; i += 8)
						{
							if (num2 != 0)
							{
								r = 0;
								num2--;
								num3 |= (_codec.InputBuffer[num++] & 0xFF) << i;
								continue;
							}
							bitb = num3;
							bitk = i;
							_codec.AvailableBytesIn = num2;
							_codec.TotalBytesIn += num - _codec.NextIn;
							_codec.NextIn = num;
							writeAt = num4;
							return Flush(r);
						}
						blens[border[index++]] = num3 & 7;
						num3 >>= 3;
						i -= 3;
					}
					while (index < 19)
					{
						blens[border[index++]] = 0;
					}
					bb[0] = 7;
					int num6 = inftree.inflate_trees_bits(blens, bb, tb, hufts, _codec);
					if (num6 != 0)
					{
						r = num6;
						if (r == -3)
						{
							blens = null;
							mode = InflateBlockMode.BAD;
						}
						bitb = num3;
						bitk = i;
						_codec.AvailableBytesIn = num2;
						_codec.TotalBytesIn += num - _codec.NextIn;
						_codec.NextIn = num;
						writeAt = num4;
						return Flush(r);
					}
					index = 0;
					mode = InflateBlockMode.DTREE;
					goto case InflateBlockMode.DTREE;
				}
				case InflateBlockMode.DTREE:
				{
					int num6;
					while (true)
					{
						num6 = table;
						if (index >= 258 + (num6 & 0x1F) + ((num6 >> 5) & 0x1F))
						{
							break;
						}
						for (num6 = bb[0]; i < num6; i += 8)
						{
							if (num2 != 0)
							{
								r = 0;
								num2--;
								num3 |= (_codec.InputBuffer[num++] & 0xFF) << i;
								continue;
							}
							bitb = num3;
							bitk = i;
							_codec.AvailableBytesIn = num2;
							_codec.TotalBytesIn += num - _codec.NextIn;
							_codec.NextIn = num;
							writeAt = num4;
							return Flush(r);
						}
						num6 = hufts[(tb[0] + (num3 & InternalInflateConstants.InflateMask[num6])) * 3 + 1];
						int num7 = hufts[(tb[0] + (num3 & InternalInflateConstants.InflateMask[num6])) * 3 + 2];
						if (num7 < 16)
						{
							num3 >>= num6;
							i -= num6;
							blens[index++] = num7;
							continue;
						}
						int num8 = ((num7 == 18) ? 7 : (num7 - 14));
						int num9 = ((num7 == 18) ? 11 : 3);
						for (; i < num6 + num8; i += 8)
						{
							if (num2 != 0)
							{
								r = 0;
								num2--;
								num3 |= (_codec.InputBuffer[num++] & 0xFF) << i;
								continue;
							}
							bitb = num3;
							bitk = i;
							_codec.AvailableBytesIn = num2;
							_codec.TotalBytesIn += num - _codec.NextIn;
							_codec.NextIn = num;
							writeAt = num4;
							return Flush(r);
						}
						num3 >>= num6;
						i -= num6;
						num9 += num3 & InternalInflateConstants.InflateMask[num8];
						num3 >>= num8;
						i -= num8;
						num8 = index;
						num6 = table;
						if (num8 + num9 > 258 + (num6 & 0x1F) + ((num6 >> 5) & 0x1F) || (num7 == 16 && num8 < 1))
						{
							blens = null;
							mode = InflateBlockMode.BAD;
							_codec.Message = "invalid bit length repeat";
							r = -3;
							bitb = num3;
							bitk = i;
							_codec.AvailableBytesIn = num2;
							_codec.TotalBytesIn += num - _codec.NextIn;
							_codec.NextIn = num;
							writeAt = num4;
							return Flush(r);
						}
						num7 = ((num7 == 16) ? blens[num8 - 1] : 0);
						do
						{
							blens[num8++] = num7;
						}
						while (--num9 != 0);
						index = num8;
					}
					tb[0] = -1;
					int[] array5 = new int[1] { 9 };
					int[] array6 = new int[1] { 6 };
					int[] array7 = new int[1];
					int[] array8 = new int[1];
					num6 = table;
					num6 = inftree.inflate_trees_dynamic(257 + (num6 & 0x1F), 1 + ((num6 >> 5) & 0x1F), blens, array5, array6, array7, array8, hufts, _codec);
					if (num6 != 0)
					{
						if (num6 == -3)
						{
							blens = null;
							mode = InflateBlockMode.BAD;
						}
						r = num6;
						bitb = num3;
						bitk = i;
						_codec.AvailableBytesIn = num2;
						_codec.TotalBytesIn += num - _codec.NextIn;
						_codec.NextIn = num;
						writeAt = num4;
						return Flush(r);
					}
					codes.Init(array5[0], array6[0], hufts, array7[0], hufts, array8[0]);
					mode = InflateBlockMode.CODES;
					goto case InflateBlockMode.CODES;
				}
				case InflateBlockMode.CODES:
					bitb = num3;
					bitk = i;
					_codec.AvailableBytesIn = num2;
					_codec.TotalBytesIn += num - _codec.NextIn;
					_codec.NextIn = num;
					writeAt = num4;
					r = codes.Process(this, r);
					if (r != 1)
					{
						return Flush(r);
					}
					r = 0;
					num = _codec.NextIn;
					num2 = _codec.AvailableBytesIn;
					num3 = bitb;
					i = bitk;
					num4 = writeAt;
					num5 = ((num4 < readAt) ? (readAt - num4 - 1) : (end - num4));
					if (last == 0)
					{
						mode = InflateBlockMode.TYPE;
						break;
					}
					mode = InflateBlockMode.DRY;
					goto case InflateBlockMode.DRY;
				case InflateBlockMode.DRY:
					writeAt = num4;
					r = Flush(r);
					num4 = writeAt;
					num5 = ((num4 < readAt) ? (readAt - num4 - 1) : (end - num4));
					if (readAt != writeAt)
					{
						bitb = num3;
						bitk = i;
						_codec.AvailableBytesIn = num2;
						_codec.TotalBytesIn += num - _codec.NextIn;
						_codec.NextIn = num;
						writeAt = num4;
						return Flush(r);
					}
					mode = InflateBlockMode.DONE;
					goto case InflateBlockMode.DONE;
				case InflateBlockMode.DONE:
					r = 1;
					bitb = num3;
					bitk = i;
					_codec.AvailableBytesIn = num2;
					_codec.TotalBytesIn += num - _codec.NextIn;
					_codec.NextIn = num;
					writeAt = num4;
					return Flush(r);
				case InflateBlockMode.BAD:
					r = -3;
					bitb = num3;
					bitk = i;
					_codec.AvailableBytesIn = num2;
					_codec.TotalBytesIn += num - _codec.NextIn;
					_codec.NextIn = num;
					writeAt = num4;
					return Flush(r);
				default:
					r = -2;
					bitb = num3;
					bitk = i;
					_codec.AvailableBytesIn = num2;
					_codec.TotalBytesIn += num - _codec.NextIn;
					_codec.NextIn = num;
					writeAt = num4;
					return Flush(r);
				}
			}
		}

		internal void Free()
		{
			Reset();
			window = null;
			hufts = null;
		}

		internal void SetDictionary(byte[] d, int start, int n)
		{
			Array.Copy(d, start, window, 0, n);
			readAt = (writeAt = n);
		}

		internal int SyncPoint()
		{
			if (mode != InflateBlockMode.LENS)
			{
				return 0;
			}
			return 1;
		}

		internal int Flush(int r)
		{
			for (int i = 0; i < 2; i++)
			{
				int num = ((i != 0) ? (writeAt - readAt) : (((readAt <= writeAt) ? writeAt : end) - readAt));
				if (num == 0)
				{
					if (r == -5)
					{
						r = 0;
					}
					return r;
				}
				if (num > _codec.AvailableBytesOut)
				{
					num = _codec.AvailableBytesOut;
				}
				if (num != 0 && r == -5)
				{
					r = 0;
				}
				_codec.AvailableBytesOut -= num;
				_codec.TotalBytesOut += num;
				if (checkfn != null)
				{
					_codec._Adler32 = (check = Adler.Adler32(check, window, readAt, num));
				}
				Array.Copy(window, readAt, _codec.OutputBuffer, _codec.NextOut, num);
				_codec.NextOut += num;
				readAt += num;
				if (readAt == end && i == 0)
				{
					readAt = 0;
					if (writeAt == end)
					{
						writeAt = 0;
					}
				}
				else
				{
					i++;
				}
			}
			return r;
		}
	}
	internal static class InternalInflateConstants
	{
		internal static readonly int[] InflateMask = new int[17]
		{
			0, 1, 3, 7, 15, 31, 63, 127, 255, 511,
			1023, 2047, 4095, 8191, 16383, 32767, 65535
		};
	}
	internal sealed class InflateCodes
	{
		private const int START = 0;

		private const int LEN = 1;

		private const int LENEXT = 2;

		private const int DIST = 3;

		private const int DISTEXT = 4;

		private const int COPY = 5;

		private const int LIT = 6;

		private const int WASH = 7;

		private const int END = 8;

		private const int BADCODE = 9;

		internal int mode;

		internal int len;

		internal int[] tree;

		internal int tree_index;

		internal int need;

		internal int lit;

		internal int bitsToGet;

		internal int dist;

		internal byte lbits;

		internal byte dbits;

		internal int[] ltree;

		internal int ltree_index;

		internal int[] dtree;

		internal int dtree_index;

		internal InflateCodes()
		{
		}

		internal void Init(int bl, int bd, int[] tl, int tl_index, int[] td, int td_index)
		{
			mode = 0;
			lbits = (byte)bl;
			dbits = (byte)bd;
			ltree = tl;
			ltree_index = tl_index;
			dtree = td;
			dtree_index = td_index;
			tree = null;
		}

		internal int Process(InflateBlocks blocks, int r)
		{
			int num = 0;
			int num2 = 0;
			int num3 = 0;
			ZlibCodec codec = blocks._codec;
			num3 = codec.NextIn;
			int num4 = codec.AvailableBytesIn;
			num = blocks.bitb;
			num2 = blocks.bitk;
			int num5 = blocks.writeAt;
			int num6 = ((num5 < blocks.readAt) ? (blocks.readAt - num5 - 1) : (blocks.end - num5));
			while (true)
			{
				switch (mode)
				{
				case 0:
					if (num6 >= 258 && num4 >= 10)
					{
						blocks.bitb = num;
						blocks.bitk = num2;
						codec.AvailableBytesIn = num4;
						codec.TotalBytesIn += num3 - codec.NextIn;
						codec.NextIn = num3;
						blocks.writeAt = num5;
						r = InflateFast(lbits, dbits, ltree, ltree_index, dtree, dtree_index, blocks, codec);
						num3 = codec.NextIn;
						num4 = codec.AvailableBytesIn;
						num = blocks.bitb;
						num2 = blocks.bitk;
						num5 = blocks.writeAt;
						num6 = ((num5 < blocks.readAt) ? (blocks.readAt - num5 - 1) : (blocks.end - num5));
						if (r != 0)
						{
							mode = ((r == 1) ? 7 : 9);
							break;
						}
					}
					need = lbits;
					tree = ltree;
					tree_index = ltree_index;
					mode = 1;
					goto case 1;
				case 1:
				{
					int num7;
					for (num7 = need; num2 < num7; num2 += 8)
					{
						if (num4 != 0)
						{
							r = 0;
							num4--;
							num |= (codec.InputBuffer[num3++] & 0xFF) << num2;
							continue;
						}
						blocks.bitb = num;
						blocks.bitk = num2;
						codec.AvailableBytesIn = num4;
						codec.TotalBytesIn += num3 - codec.NextIn;
						codec.NextIn = num3;
						blocks.writeAt = num5;
						return blocks.Flush(r);
					}
					int num8 = (tree_index + (num & InternalInflateConstants.InflateMask[num7])) * 3;
					num >>= tree[num8 + 1];
					num2 -= tree[num8 + 1];
					int num9 = tree[num8];
					if (num9 == 0)
					{
						lit = tree[num8 + 2];
						mode = 6;
						break;
					}
					if (((uint)num9 & 0x10u) != 0)
					{
						bitsToGet = num9 & 0xF;
						len = tree[num8 + 2];
						mode = 2;
						break;
					}
					if ((num9 & 0x40) == 0)
					{
						need = num9;
						tree_index = num8 / 3 + tree[num8 + 2];
						break;
					}
					if (((uint)num9 & 0x20u) != 0)
					{
						mode = 7;
						break;
					}
					mode = 9;
					codec.Message = "invalid literal/length code";
					r = -3;
					blocks.bitb = num;
					blocks.bitk = num2;
					codec.AvailableBytesIn = num4;
					codec.TotalBytesIn += num3 - codec.NextIn;
					codec.NextIn = num3;
					blocks.writeAt = num5;
					return blocks.Flush(r);
				}
				case 2:
				{
					int num7;
					for (num7 = bitsToGet; num2 < num7; num2 += 8)
					{
						if (num4 != 0)
						{
							r = 0;
							num4--;
							num |= (codec.InputBuffer[num3++] & 0xFF) << num2;
							continue;
						}
						blocks.bitb = num;
						blocks.bitk = num2;
						codec.AvailableBytesIn = num4;
						codec.TotalBytesIn += num3 - codec.NextIn;
						codec.NextIn = num3;
						blocks.writeAt = num5;
						return blocks.Flush(r);
					}
					len += num & InternalInflateConstants.InflateMask[num7];
					num >>= num7;
					num2 -= num7;
					need = dbits;
					tree = dtree;
					tree_index = dtree_index;
					mode = 3;
					goto case 3;
				}
				case 3:
				{
					int num7;
					for (num7 = need; num2 < num7; num2 += 8)
					{
						if (num4 != 0)
						{
							r = 0;
							num4--;
							num |= (codec.InputBuffer[num3++] & 0xFF) << num2;
							continue;
						}
						blocks.bitb = num;
						blocks.bitk = num2;
						codec.AvailableBytesIn = num4;
						codec.TotalBytesIn += num3 - codec.NextIn;
						codec.NextIn = num3;
						blocks.writeAt = num5;
						return blocks.Flush(r);
					}
					int num8 = (tree_index + (num & InternalInflateConstants.InflateMask[num7])) * 3;
					num >>= tree[num8 + 1];
					num2 -= tree[num8 + 1];
					int num9 = tree[num8];
					if (((uint)num9 & 0x10u) != 0)
					{
						bitsToGet = num9 & 0xF;
						dist = tree[num8 + 2];
						mode = 4;
						break;
					}
					if ((num9 & 0x40) == 0)
					{
						need = num9;
						tree_index = num8 / 3 + tree[num8 + 2];
						break;
					}
					mode = 9;
					codec.Message = "invalid distance code";
					r = -3;
					blocks.bitb = num;
					blocks.bitk = num2;
					codec.AvailableBytesIn = num4;
					codec.TotalBytesIn += num3 - codec.NextIn;
					codec.NextIn = num3;
					blocks.writeAt = num5;
					return blocks.Flush(r);
				}
				case 4:
				{
					int num7;
					for (num7 = bitsToGet; num2 < num7; num2 += 8)
					{
						if (num4 != 0)
						{
							r = 0;
							num4--;
							num |= (codec.InputBuffer[num3++] & 0xFF) << num2;
							continue;
						}
						blocks.bitb = num;
						blocks.bitk = num2;
						codec.AvailableBytesIn = num4;
						codec.TotalBytesIn += num3 - codec.NextIn;
						codec.NextIn = num3;
						blocks.writeAt = num5;
						return blocks.Flush(r);
					}
					dist += num & InternalInflateConstants.InflateMask[num7];
					num >>= num7;
					num2 -= num7;
					mode = 5;
					goto case 5;
				}
				case 5:
				{
					int i;
					for (i = num5 - dist; i < 0; i += blocks.end)
					{
					}
					while (len != 0)
					{
						if (num6 == 0)
						{
							if (num5 == blocks.end && blocks.readAt != 0)
							{
								num5 = 0;
								num6 = ((num5 < blocks.readAt) ? (blocks.readAt - num5 - 1) : (blocks.end - num5));
							}
							if (num6 == 0)
							{
								blocks.writeAt = num5;
								r = blocks.Flush(r);
								num5 = blocks.writeAt;
								num6 = ((num5 < blocks.readAt) ? (blocks.readAt - num5 - 1) : (blocks.end - num5));
								if (num5 == blocks.end && blocks.readAt != 0)
								{
									num5 = 0;
									num6 = ((num5 < blocks.readAt) ? (blocks.readAt - num5 - 1) : (blocks.end - num5));
								}
								if (num6 == 0)
								{
									blocks.bitb = num;
									blocks.bitk = num2;
									codec.AvailableBytesIn = num4;
									codec.TotalBytesIn += num3 - codec.NextIn;
									codec.NextIn = num3;
									blocks.writeAt = num5;
									return blocks.Flush(r);
								}
							}
						}
						blocks.window[num5++] = blocks.window[i++];
						num6--;
						if (i == blocks.end)
						{
							i = 0;
						}
						len--;
					}
					mode = 0;
					break;
				}
				case 6:
					if (num6 == 0)
					{
						if (num5 == blocks.end && blocks.readAt != 0)
						{
							num5 = 0;
							num6 = ((num5 < blocks.readAt) ? (blocks.readAt - num5 - 1) : (blocks.end - num5));
						}
						if (num6 == 0)
						{
							blocks.writeAt = num5;
							r = blocks.Flush(r);
							num5 = blocks.writeAt;
							num6 = ((num5 < blocks.readAt) ? (blocks.readAt - num5 - 1) : (blocks.end - num5));
							if (num5 == blocks.end && blocks.readAt != 0)
							{
								num5 = 0;
								num6 = ((num5 < blocks.readAt) ? (blocks.readAt - num5 - 1) : (blocks.end - num5));
							}
							if (num6 == 0)
							{
								blocks.bitb = num;
								blocks.bitk = num2;
								codec.AvailableBytesIn = num4;
								codec.TotalBytesIn += num3 - codec.NextIn;
								codec.NextIn = num3;
								blocks.writeAt = num5;
								return blocks.Flush(r);
							}
						}
					}
					r = 0;
					blocks.window[num5++] = (byte)lit;
					num6--;
					mode = 0;
					break;
				case 7:
					if (num2 > 7)
					{
						num2 -= 8;
						num4++;
						num3--;
					}
					blocks.writeAt = num5;
					r = blocks.Flush(r);
					num5 = blocks.writeAt;
					num6 = ((num5 < blocks.readAt) ? (blocks.readAt - num5 - 1) : (blocks.end - num5));
					if (blocks.readAt != blocks.writeAt)
					{
						blocks.bitb = num;
						blocks.bitk = num2;
						codec.AvailableBytesIn = num4;
						codec.TotalBytesIn += num3 - codec.NextIn;
						codec.NextIn = num3;
						blocks.writeAt = num5;
						return blocks.Flush(r);
					}
					mode = 8;
					goto case 8;
				case 8:
					r = 1;
					blocks.bitb = num;
					blocks.bitk = num2;
					codec.AvailableBytesIn = num4;
					codec.TotalBytesIn += num3 - codec.NextIn;
					codec.NextIn = num3;
					blocks.writeAt = num5;
					return blocks.Flush(r);
				case 9:
					r = -3;
					blocks.bitb = num;
					blocks.bitk = num2;
					codec.AvailableBytesIn = num4;
					codec.TotalBytesIn += num3 - codec.NextIn;
					codec.NextIn = num3;
					blocks.writeAt = num5;
					return blocks.Flush(r);
				default:
					r = -2;
					blocks.bitb = num;
					blocks.bitk = num2;
					codec.AvailableBytesIn = num4;
					codec.TotalBytesIn += num3 - codec.NextIn;
					codec.NextIn = num3;
					blocks.writeAt = num5;
					return blocks.Flush(r);
				}
			}
		}

		internal int InflateFast(int bl, int bd, int[] tl, int tl_index, int[] td, int td_index, InflateBlocks s, ZlibCodec z)
		{
			int nextIn = z.NextIn;
			int num = z.AvailableBytesIn;
			int num2 = s.bitb;
			int num3 = s.bitk;
			int num4 = s.writeAt;
			int num5 = ((num4 < s.readAt) ? (s.readAt - num4 - 1) : (s.end - num4));
			int num6 = InternalInflateConstants.InflateMask[bl];
			int num7 = InternalInflateConstants.InflateMask[bd];
			int num12;
			while (true)
			{
				if (num3 < 20)
				{
					num--;
					num2 |= (z.InputBuffer[nextIn++] & 0xFF) << num3;
					num3 += 8;
					continue;
				}
				int num8 = num2 & num6;
				int[] array = tl;
				int num9 = tl_index;
				int num10 = (num9 + num8) * 3;
				int num11;
				if ((num11 = array[num10]) == 0)
				{
					num2 >>= array[num10 + 1];
					num3 -= array[num10 + 1];
					s.window[num4++] = (byte)array[num10 + 2];
					num5--;
				}
				else
				{
					while (true)
					{
						num2 >>= array[num10 + 1];
						num3 -= array[num10 + 1];
						if (((uint)num11 & 0x10u) != 0)
						{
							num11 &= 0xF;
							num12 = array[num10 + 2] + (num2 & InternalInflateConstants.InflateMask[num11]);
							num2 >>= num11;
							for (num3 -= num11; num3 < 15; num3 += 8)
							{
								num--;
								num2 |= (z.InputBuffer[nextIn++] & 0xFF) << num3;
							}
							num8 = num2 & num7;
							array = td;
							num9 = td_index;
							num10 = (num9 + num8) * 3;
							num11 = array[num10];
							while (true)
							{
								num2 >>= array[num10 + 1];
								num3 -= array[num10 + 1];
								if (((uint)num11 & 0x10u) != 0)
								{
									break;
								}
								if ((num11 & 0x40) == 0)
								{
									num8 += array[num10 + 2];
									num8 += num2 & InternalInflateConstants.InflateMask[num11];
									num10 = (num9 + num8) * 3;
									num11 = array[num10];
									continue;
								}
								z.Message = "invalid distance code";
								num12 = z.AvailableBytesIn - num;
								num12 = ((num3 >> 3 < num12) ? (num3 >> 3) : num12);
								num += num12;
								nextIn -= num12;
								num3 -= num12 << 3;
								s.bitb = num2;
								s.bitk = num3;
								z.AvailableBytesIn = num;
								z.TotalBytesIn += nextIn - z.NextIn;
								z.NextIn = nextIn;
								s.writeAt = num4;
								return -3;
							}
							for (num11 &= 0xF; num3 < num11; num3 += 8)
							{
								num--;
								num2 |= (z.InputBuffer[nextIn++] & 0xFF) << num3;
							}
							int num13 = array[num10 + 2] + (num2 & InternalInflateConstants.InflateMask[num11]);
							num2 >>= num11;
							num3 -= num11;
							num5 -= num12;
							int num14;
							if (num4 >= num13)
							{
								num14 = num4 - num13;
								if (num4 - num14 > 0 && 2 > num4 - num14)
								{
									s.window[num4++] = s.window[num14++];
									s.window[num4++] = s.window[num14++];
									num12 -= 2;
								}
								else
								{
									Array.Copy(s.window, num14, s.window, num4, 2);
									num4 += 2;
									num14 += 2;
									num12 -= 2;
								}
							}
							else
							{
								num14 = num4 - num13;
								do
								{
									num14 += s.end;
								}
								while (num14 < 0);
								num11 = s.end - num14;
								if (num12 > num11)
								{
									num12 -= num11;
									if (num4 - num14 > 0 && num11 > num4 - num14)
									{
										do
										{
											s.window[num4++] = s.window[num14++];
										}
										while (--num11 != 0);
									}
									else
									{
										Array.Copy(s.window, num14, s.window, num4, num11);
										num4 += num11;
										num14 += num11;
										num11 = 0;
									}
									num14 = 0;
								}
							}
							if (num4 - num14 > 0 && num12 > num4 - num14)
							{
								do
								{
									s.window[num4++] = s.window[num14++];
								}
								while (--num12 != 0);
								break;
							}
							Array.Copy(s.window, num14, s.window, num4, num12);
							num4 += num12;
							num14 += num12;
							num12 = 0;
							break;
						}
						if ((num11 & 0x40) == 0)
						{
							num8 += array[num10 + 2];
							num8 += num2 & InternalInflateConstants.InflateMask[num11];
							num10 = (num9 + num8) * 3;
							if ((num11 = array[num10]) == 0)
							{
								num2 >>= array[num10 + 1];
								num3 -= array[num10 + 1];
								s.window[num4++] = (byte)array[num10 + 2];
								num5--;
								break;
							}
							continue;
						}
						if (((uint)num11 & 0x20u) != 0)
						{
							num12 = z.AvailableBytesIn - num;
							num12 = ((num3 >> 3 < num12) ? (num3 >> 3) : num12);
							num += num12;
							nextIn -= num12;
							num3 -= num12 << 3;
							s.bitb = num2;
							s.bitk = num3;
							z.AvailableBytesIn = num;
							z.TotalBytesIn += nextIn - z.NextIn;
							z.NextIn = nextIn;
							s.writeAt = num4;
							return 1;
						}
						z.Message = "invalid literal/length code";
						num12 = z.AvailableBytesIn - num;
						num12 = ((num3 >> 3 < num12) ? (num3 >> 3) : num12);
						num += num12;
						nextIn -= num12;
						num3 -= num12 << 3;
						s.bitb = num2;
						s.bitk = num3;
						z.AvailableBytesIn = num;
						z.TotalBytesIn += nextIn - z.NextIn;
						z.NextIn = nextIn;
						s.writeAt = num4;
						return -3;
					}
				}
				if (num5 < 258 || num < 10)
				{
					break;
				}
			}
			num12 = z.AvailableBytesIn - num;
			num12 = ((num3 >> 3 < num12) ? (num3 >> 3) : num12);
			num += num12;
			nextIn -= num12;
			num3 -= num12 << 3;
			s.bitb = num2;
			s.bitk = num3;
			z.AvailableBytesIn = num;
			z.TotalBytesIn += nextIn - z.NextIn;
			z.NextIn = nextIn;
			s.writeAt = num4;
			return 0;
		}
	}
	internal sealed class InflateManager
	{
		private enum InflateManagerMode
		{
			METHOD,
			FLAG,
			DICT4,
			DICT3,
			DICT2,
			DICT1,
			DICT0,
			BLOCKS,
			CHECK4,
			CHECK3,
			CHECK2,
			CHECK1,
			DONE,
			BAD
		}

		private const int PRESET_DICT = 32;

		private const int Z_DEFLATED = 8;

		private InflateManagerMode mode;

		internal ZlibCodec _codec;

		internal int method;

		internal uint computedCheck;

		internal uint expectedCheck;

		internal int marker;

		private bool _handleRfc1950HeaderBytes = true;

		internal int wbits;

		internal InflateBlocks blocks;

		private static readonly byte[] mark = new byte[4] { 0, 0, 255, 255 };

		internal bool HandleRfc1950HeaderBytes
		{
			get
			{
				return _handleRfc1950HeaderBytes;
			}
			set
			{
				_handleRfc1950HeaderBytes = value;
			}
		}

		public InflateManager()
		{
		}

		public InflateManager(bool expectRfc1950HeaderBytes)
		{
			_handleRfc1950HeaderBytes = expectRfc1950HeaderBytes;
		}

		internal int Reset()
		{
			_codec.TotalBytesIn = (_codec.TotalBytesOut = 0L);
			_codec.Message = null;
			mode = ((!HandleRfc1950HeaderBytes) ? InflateManagerMode.BLOCKS : InflateManagerMode.METHOD);
			blocks.Reset();
			return 0;
		}

		internal int End()
		{
			if (blocks != null)
			{
				blocks.Free();
			}
			blocks = null;
			return 0;
		}

		internal int Initialize(ZlibCodec codec, int w)
		{
			_codec = codec;
			_codec.Message = null;
			blocks = null;
			if (w < 8 || w > 15)
			{
				End();
				throw new ZlibException("Bad window size.");
			}
			wbits = w;
			blocks = new InflateBlocks(codec, HandleRfc1950HeaderBytes ? this : null, 1 << w);
			Reset();
			return 0;
		}

		internal int Inflate(FlushType flush)
		{
			if (_codec.InputBuffer == null)
			{
				throw new ZlibException("InputBuffer is null. ");
			}
			int num = 0;
			int num2 = -5;
			while (true)
			{
				switch (mode)
				{
				case InflateManagerMode.METHOD:
					if (_codec.AvailableBytesIn == 0)
					{
						return num2;
					}
					num2 = num;
					_codec.AvailableBytesIn--;
					_codec.TotalBytesIn++;
					if (((method = _codec.InputBuffer[_codec.NextIn++]) & 0xF) != 8)
					{
						mode = InflateManagerMode.BAD;
						_codec.Message = $"unknown compression method (0x{method:X2})";
						marker = 5;
					}
					else if ((method >> 4) + 8 > wbits)
					{
						mode = InflateManagerMode.BAD;
						_codec.Message = $"invalid window size ({(method >> 4) + 8})";
						marker = 5;
					}
					else
					{
						mode = InflateManagerMode.FLAG;
					}
					break;
				case InflateManagerMode.FLAG:
				{
					if (_codec.AvailableBytesIn == 0)
					{
						return num2;
					}
					num2 = num;
					_codec.AvailableBytesIn--;
					_codec.TotalBytesIn++;
					int num3 = _codec.InputBuffer[_codec.NextIn++] & 0xFF;
					if (((method << 8) + num3) % 31 != 0)
					{
						mode = InflateManagerMode.BAD;
						_codec.Message = "incorrect header check";
						marker = 5;
					}
					else
					{
						mode = (((num3 & 0x20) == 0) ? InflateManagerMode.BLOCKS : InflateManagerMode.DICT4);
					}
					break;
				}
				case InflateManagerMode.DICT4:
					if (_codec.AvailableBytesIn == 0)
					{
						return num2;
					}
					num2 = num;
					_codec.AvailableBytesIn--;
					_codec.TotalBytesIn++;
					expectedCheck = (uint)((_codec.InputBuffer[_codec.NextIn++] << 24) & 0xFF000000u);
					mode = InflateManagerMode.DICT3;
					break;
				case InflateManagerMode.DICT3:
					if (_codec.AvailableBytesIn == 0)
					{
						return num2;
					}
					num2 = num;
					_codec.AvailableBytesIn--;
					_codec.TotalBytesIn++;
					expectedCheck += (uint)((_codec.InputBuffer[_codec.NextIn++] << 16) & 0xFF0000);
					mode = InflateManagerMode.DICT2;
					break;
				case InflateManagerMode.DICT2:
					if (_codec.AvailableBytesIn == 0)
					{
						return num2;
					}
					num2 = num;
					_codec.AvailableBytesIn--;
					_codec.TotalBytesIn++;
					expectedCheck += (uint)((_codec.InputBuffer[_codec.NextIn++] << 8) & 0xFF00);
					mode = InflateManagerMode.DICT1;
					break;
				case InflateManagerMode.DICT1:
					if (_codec.AvailableBytesIn == 0)
					{
						return num2;
					}
					num2 = num;
					_codec.AvailableBytesIn--;
					_codec.TotalBytesIn++;
					expectedCheck += (uint)(_codec.InputBuffer[_codec.NextIn++] & 0xFF);
					_codec._Adler32 = expectedCheck;
					mode = InflateManagerMode.DICT0;
					return 2;
				case InflateManagerMode.DICT0:
					mode = InflateManagerMode.BAD;
					_codec.Message = "need dictionary";
					marker = 0;
					return -2;
				case InflateManagerMode.BLOCKS:
					num2 = blocks.Process(num2);
					switch (num2)
					{
					case -3:
						mode = InflateManagerMode.BAD;
						marker = 0;
						goto end_IL_0025;
					case 0:
						num2 = num;
						break;
					}
					if (num2 != 1)
					{
						return num2;
					}
					num2 = num;
					computedCheck = blocks.Reset();
					if (!HandleRfc1950HeaderBytes)
					{
						mode = InflateManagerMode.DONE;
						return 1;
					}
					mode = InflateManagerMode.CHECK4;
					break;
				case InflateManagerMode.CHECK4:
					if (_codec.AvailableBytesIn == 0)
					{
						return num2;
					}
					num2 = num;
					_codec.AvailableBytesIn--;
					_codec.TotalBytesIn++;
					expectedCheck = (uint)((_codec.InputBuffer[_codec.NextIn++] << 24) & 0xFF000000u);
					mode = InflateManagerMode.CHECK3;
					break;
				case InflateManagerMode.CHECK3:
					if (_codec.AvailableBytesIn == 0)
					{
						return num2;
					}
					num2 = num;
					_codec.AvailableBytesIn--;
					_codec.TotalBytesIn++;
					expectedCheck += (uint)((_codec.InputBuffer[_codec.NextIn++] << 16) & 0xFF0000);
					mode = InflateManagerMode.CHECK2;
					break;
				case InflateManagerMode.CHECK2:
					if (_codec.AvailableBytesIn == 0)
					{
						return num2;
					}
					num2 = num;
					_codec.AvailableBytesIn--;
					_codec.TotalBytesIn++;
					expectedCheck += (uint)((_codec.InputBuffer[_codec.NextIn++] << 8) & 0xFF00);
					mode = InflateManagerMode.CHECK1;
					break;
				case InflateManagerMode.CHECK1:
					if (_codec.AvailableBytesIn == 0)
					{
						return num2;
					}
					num2 = num;
					_codec.AvailableBytesIn--;
					_codec.TotalBytesIn++;
					expectedCheck += (uint)(_codec.InputBuffer[_codec.NextIn++] & 0xFF);
					if (computedCheck != expectedCheck)
					{
						mode = InflateManagerMode.BAD;
						_codec.Message = "incorrect data check";
						marker = 5;
						break;
					}
					mode = InflateManagerMode.DONE;
					return 1;
				case InflateManagerMode.DONE:
					return 1;
				case InflateManagerMode.BAD:
					throw new ZlibException($"Bad state ({_codec.Message})");
				default:
					{
						throw new ZlibException("Stream error.");
					}
					end_IL_0025:
					break;
				}
			}
		}

		internal int SetDictionary(byte[] dictionary)
		{
			int start = 0;
			int num = dictionary.Length;
			if (mode != InflateManagerMode.DICT0)
			{
				throw new ZlibException("Stream error.");
			}
			if (Adler.Adler32(1u, dictionary, 0, dictionary.Length) != _codec._Adler32)
			{
				return -3;
			}
			_codec._Adler32 = Adler.Adler32(0u, null, 0, 0);
			if (num >= 1 << wbits)
			{
				num = (1 << wbits) - 1;
				start = dictionary.Length - num;
			}
			blocks.SetDictionary(dictionary, start, num);
			mode = InflateManagerMode.BLOCKS;
			return 0;
		}

		internal int Sync()
		{
			if (mode != InflateManagerMode.BAD)
			{
				mode = InflateManagerMode.BAD;
				marker = 0;
			}
			int num;
			if ((num = _codec.AvailableBytesIn) == 0)
			{
				return -5;
			}
			int num2 = _codec.NextIn;
			int num3 = marker;
			while (num != 0 && num3 < 4)
			{
				num3 = ((_codec.InputBuffer[num2] != mark[num3]) ? ((_codec.InputBuffer[num2] == 0) ? (4 - num3) : 0) : (num3 + 1));
				num2++;
				num--;
			}
			_codec.TotalBytesIn += num2 - _codec.NextIn;
			_codec.NextIn = num2;
			_codec.AvailableBytesIn = num;
			marker = num3;
			if (num3 != 4)
			{
				return -3;
			}
			long totalBytesIn = _codec.TotalBytesIn;
			long totalBytesOut = _codec.TotalBytesOut;
			Reset();
			_codec.TotalBytesIn = totalBytesIn;
			_codec.TotalBytesOut = totalBytesOut;
			mode = InflateManagerMode.BLOCKS;
			return 0;
		}

		internal int SyncPoint(ZlibCodec z)
		{
			return blocks.SyncPoint();
		}
	}
	internal sealed class InfTree
	{
		private const int MANY = 1440;

		private const int Z_OK = 0;

		private const int Z_STREAM_END = 1;

		private const int Z_NEED_DICT = 2;

		private const int Z_ERRNO = -1;

		private const int Z_STREAM_ERROR = -2;

		private const int Z_DATA_ERROR = -3;

		private const int Z_MEM_ERROR = -4;

		private const int Z_BUF_ERROR = -5;

		private const int Z_VERSION_ERROR = -6;

		internal const int fixed_bl = 9;

		internal const int fixed_bd = 5;

		internal static readonly int[] fixed_tl = new int[1536]
		{
			96, 7, 256, 0, 8, 80, 0, 8, 16, 84,
			8, 115, 82, 7, 31, 0, 8, 112, 0, 8,
			48, 0, 9, 192, 80, 7, 10, 0, 8, 96,
			0, 8, 32, 0, 9, 160, 0, 8, 0, 0,
			8, 128, 0, 8, 64, 0, 9, 224, 80, 7,
			6, 0, 8, 88, 0, 8, 24, 0, 9, 144,
			83, 7, 59, 0, 8, 120, 0, 8, 56, 0,
			9, 208, 81, 7, 17, 0, 8, 104, 0, 8,
			40, 0, 9, 176, 0, 8, 8, 0, 8, 136,
			0, 8, 72, 0, 9, 240, 80, 7, 4, 0,
			8, 84, 0, 8, 20, 85, 8, 227, 83, 7,
			43, 0, 8, 116, 0, 8, 52, 0, 9, 200,
			81, 7, 13, 0, 8, 100, 0, 8, 36, 0,
			9, 168, 0, 8, 4, 0, 8, 132, 0, 8,
			68, 0, 9, 232, 80, 7, 8, 0, 8, 92,
			0, 8, 28, 0, 9, 152, 84, 7, 83, 0,
			8, 124, 0, 8, 60, 0, 9, 216, 82, 7,
			23, 0, 8, 108, 0, 8, 44, 0, 9, 184,
			0, 8, 12, 0, 8, 140, 0, 8, 76, 0,
			9, 248, 80, 7, 3, 0, 8, 82, 0, 8,
			18, 85, 8, 163, 83, 7, 35, 0, 8, 114,
			0, 8, 50, 0, 9, 196, 81, 7, 11, 0,
			8, 98, 0, 8, 34, 0, 9, 164, 0, 8,
			2, 0, 8, 130, 0, 8, 66, 0, 9, 228,
			80, 7, 7, 0, 8, 90, 0, 8, 26, 0,
			9, 148, 84, 7, 67, 0, 8, 122, 0, 8,
			58, 0, 9, 212, 82, 7, 19, 0, 8, 106,
			0, 8, 42, 0, 9, 180, 0, 8, 10, 0,
			8, 138, 0, 8, 74, 0, 9, 244, 80, 7,
			5, 0, 8, 86, 0, 8, 22, 192, 8, 0,
			83, 7, 51, 0, 8, 118, 0, 8, 54, 0,
			9, 204, 81, 7, 15, 0, 8, 102, 0, 8,
			38, 0, 9, 172, 0, 8, 6, 0, 8, 134,
			0, 8, 70, 0, 9, 236, 80, 7, 9, 0,
			8, 94, 0, 8, 30, 0, 9, 156, 84, 7,
			99, 0, 8, 126, 0, 8, 62, 0, 9, 220,
			82, 7, 27, 0, 8, 110, 0, 8, 46, 0,
			9, 188, 0, 8, 14, 0, 8, 142, 0, 8,
			78, 0, 9, 252, 96, 7, 256, 0, 8, 81,
			0, 8, 17, 85, 8, 131, 82, 7, 31, 0,
			8, 113, 0, 8, 49, 0, 9, 194, 80, 7,
			10, 0, 8, 97, 0, 8, 33, 0, 9, 162,
			0, 8, 1, 0, 8, 129, 0, 8, 65, 0,
			9, 226, 80, 7, 6, 0, 8, 89, 0, 8,
			25, 0, 9, 146, 83, 7, 59, 0, 8, 121,
			0, 8, 57, 0, 9, 210, 81, 7, 17, 0,
			8, 105, 0, 8, 41, 0, 9, 178, 0, 8,
			9, 0, 8, 137, 0, 8, 73, 0, 9, 242,
			80, 7, 4, 0, 8, 85, 0, 8, 21, 80,
			8, 258, 83, 7, 43, 0, 8, 117, 0, 8,
			53, 0, 9, 202, 81, 7, 13, 0, 8, 101,
			0, 8, 37, 0, 9, 170, 0, 8, 5, 0,
			8, 133, 0, 8, 69, 0, 9, 234, 80, 7,
			8, 0, 8, 93, 0, 8, 29, 0, 9, 154,
			84, 7, 83, 0, 8, 125, 0, 8, 61, 0,
			9, 218, 82, 7, 23, 0, 8, 109, 0, 8,
			45, 0, 9, 186, 0, 8, 13, 0, 8, 141,
			0, 8, 77, 0, 9, 250, 80, 7, 3, 0,
			8, 83, 0, 8, 19, 85, 8, 195, 83, 7,
			35, 0, 8, 115, 0, 8, 51, 0, 9, 198,
			81, 7, 11, 0, 8, 99, 0, 8, 35, 0,
			9, 166, 0, 8, 3, 0, 8, 131, 0, 8,
			67, 0, 9, 230, 80, 7, 7, 0, 8, 91,
			0, 8, 27, 0, 9, 150, 84, 7, 67, 0,
			8, 123, 0, 8, 59, 0, 9, 214, 82, 7,
			19, 0, 8, 107, 0, 8, 43, 0, 9, 182,
			0, 8, 11, 0, 8, 139, 0, 8, 75, 0,
			9, 246, 80, 7, 5, 0, 8, 87, 0, 8,
			23, 192, 8, 0, 83, 7, 51, 0, 8, 119,
			0, 8, 55, 0, 9, 206, 81, 7, 15, 0,
			8, 103, 0, 8, 39, 0, 9, 174, 0, 8,
			7, 0, 8, 135, 0, 8, 71, 0, 9, 238,
			80, 7, 9, 0, 8, 95, 0, 8, 31, 0,
			9, 158, 84, 7, 99, 0, 8, 127, 0, 8,
			63, 0, 9, 222, 82, 7, 27, 0, 8, 111,
			0, 8, 47, 0, 9, 190, 0, 8, 15, 0,
			8, 143, 0, 8, 79, 0, 9, 254, 96, 7,
			256, 0, 8, 80, 0, 8, 16, 84, 8, 115,
			82, 7, 31, 0, 8, 112, 0, 8, 48, 0,
			9, 193, 80, 7, 10, 0, 8, 96, 0, 8,
			32, 0, 9, 161, 0, 8, 0, 0, 8, 128,
			0, 8, 64, 0, 9, 225, 80, 7, 6, 0,
			8, 88, 0, 8, 24, 0, 9, 145, 83, 7,
			59, 0, 8, 120, 0, 8, 56, 0, 9, 209,
			81, 7, 17, 0, 8, 104, 0, 8, 40, 0,
			9, 177, 0, 8, 8, 0, 8, 136, 0, 8,
			72, 0, 9, 241, 80, 7, 4, 0, 8, 84,
			0, 8, 20, 85, 8, 227, 83, 7, 43, 0,
			8, 116, 0, 8, 52, 0, 9, 201, 81, 7,
			13, 0, 8, 100, 0, 8, 36, 0, 9, 169,
			0, 8, 4, 0, 8, 132, 0, 8, 68, 0,
			9, 233, 80, 7, 8, 0, 8, 92, 0, 8,
			28, 0, 9, 153, 84, 7, 83, 0, 8, 124,
			0, 8, 60, 0, 9, 217, 82, 7, 23, 0,
			8, 108, 0, 8, 44, 0, 9, 185, 0, 8,
			12, 0, 8, 140, 0, 8, 76, 0, 9, 249,
			80, 7, 3, 0, 8, 82, 0, 8, 18, 85,
			8, 163, 83, 7, 35, 0, 8, 114, 0, 8,
			50, 0, 9, 197, 81, 7, 11, 0, 8, 98,
			0, 8, 34, 0, 9, 165, 0, 8, 2, 0,
			8, 130, 0, 8, 66, 0, 9, 229, 80, 7,
			7, 0, 8, 90, 0, 8, 26, 0, 9, 149,
			84, 7, 67, 0, 8, 122, 0, 8, 58, 0,
			9, 213, 82, 7, 19, 0, 8, 106, 0, 8,
			42, 0, 9, 181, 0, 8, 10, 0, 8, 138,
			0, 8, 74, 0, 9, 245, 80, 7, 5, 0,
			8, 86, 0, 8, 22, 192, 8, 0, 83, 7,
			51, 0, 8, 118, 0, 8, 54, 0, 9, 205,
			81, 7, 15, 0, 8, 102, 0, 8, 38, 0,
			9, 173, 0, 8, 6, 0, 8, 134, 0, 8,
			70, 0, 9, 237, 80, 7, 9, 0, 8, 94,
			0, 8, 30, 0, 9, 157, 84, 7, 99, 0,
			8, 126, 0, 8, 62, 0, 9, 221, 82, 7,
			27, 0, 8, 110, 0, 8, 46, 0, 9, 189,
			0, 8, 14, 0, 8, 142, 0, 8, 78, 0,
			9, 253, 96, 7, 256, 0, 8, 81, 0, 8,
			17, 85, 8, 131, 82, 7, 31, 0, 8, 113,
			0, 8, 49, 0, 9, 195, 80, 7, 10, 0,
			8, 97, 0, 8, 33, 0, 9, 163, 0, 8,
			1, 0, 8, 129, 0, 8, 65, 0, 9, 227,
			80, 7, 6, 0, 8, 89, 0, 8, 25, 0,
			9, 147, 83, 7, 59, 0, 8, 121, 0, 8,
			57, 0, 9, 211, 81, 7, 17, 0, 8, 105,
			0, 8, 41, 0, 9, 179, 0, 8, 9, 0,
			8, 137, 0, 8, 73, 0, 9, 243, 80, 7,
			4, 0, 8, 85, 0, 8, 21, 80, 8, 258,
			83, 7, 43, 0, 8, 117, 0, 8, 53, 0,
			9, 203, 81, 7, 13, 0, 8, 101, 0, 8,
			37, 0, 9, 171, 0, 8, 5, 0, 8, 133,
			0, 8, 69, 0, 9, 235, 80, 7, 8, 0,
			8, 93, 0, 8, 29, 0, 9, 155, 84, 7,
			83, 0, 8, 125, 0, 8, 61, 0, 9, 219,
			82, 7, 23, 0, 8, 109, 0, 8, 45, 0,
			9, 187, 0, 8, 13, 0, 8, 141, 0, 8,
			77, 0, 9, 251, 80, 7, 3, 0, 8, 83,
			0, 8, 19, 85, 8, 195, 83, 7, 35, 0,
			8, 115, 0, 8, 51, 0, 9, 199, 81, 7,
			11, 0, 8, 99, 0, 8, 35, 0, 9, 167,
			0, 8, 3, 0, 8, 131, 0, 8, 67, 0,
			9, 231, 80, 7, 7, 0, 8, 91, 0, 8,
			27, 0, 9, 151, 84, 7, 67, 0, 8, 123,
			0, 8, 59, 0, 9, 215, 82, 7, 19, 0,
			8, 107, 0, 8, 43, 0, 9, 183, 0, 8,
			11, 0, 8, 139, 0, 8, 75, 0, 9, 247,
			80, 7, 5, 0, 8, 87, 0, 8, 23, 192,
			8, 0, 83, 7, 51, 0, 8, 119, 0, 8,
			55, 0, 9, 207, 81, 7, 15, 0, 8, 103,
			0, 8, 39, 0, 9, 175, 0, 8, 7, 0,
			8, 135, 0, 8, 71, 0, 9, 239, 80, 7,
			9, 0, 8, 95, 0, 8, 31, 0, 9, 159,
			84, 7, 99, 0, 8, 127, 0, 8, 63, 0,
			9, 223, 82, 7, 27, 0, 8, 111, 0, 8,
			47, 0, 9, 191, 0, 8, 15, 0, 8, 143,
			0, 8, 79, 0, 9, 255
		};

		internal static readonly int[] fixed_td = new int[96]
		{
			80, 5, 1, 87, 5, 257, 83, 5, 17, 91,
			5, 4097, 81, 5, 5, 89, 5, 1025, 85, 5,
			65, 93, 5, 16385, 80, 5, 3, 88, 5, 513,
			84, 5, 33, 92, 5, 8193, 82, 5, 9, 90,
			5, 2049, 86, 5, 129, 192, 5, 24577, 80, 5,
			2, 87, 5, 385, 83, 5, 25, 91, 5, 6145,
			81, 5, 7, 89, 5, 1537, 85, 5, 97, 93,
			5, 24577, 80, 5, 4, 88, 5, 769, 84, 5,
			49, 92, 5, 12289, 82, 5, 13, 90, 5, 3073,
			86, 5, 193, 192, 5, 24577
		};

		internal static readonly int[] cplens = new int[31]
		{
			3, 4, 5, 6, 7, 8, 9, 10, 11, 13,
			15, 17, 19, 23, 27, 31, 35, 43, 51, 59,
			67, 83, 99, 115, 131, 163, 195, 227, 258, 0,
			0
		};

		internal static readonly int[] cplext = new int[31]
		{
			0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
			1, 1, 2, 2, 2, 2, 3, 3, 3, 3,
			4, 4, 4, 4, 5, 5, 5, 5, 0, 112,
			112
		};

		internal static readonly int[] cpdist = new int[30]
		{
			1, 2, 3, 4, 5, 7, 9, 13, 17, 25,
			33, 49, 65, 97, 129, 193, 257, 385, 513, 769,
			1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577
		};

		internal static readonly int[] cpdext = new int[30]
		{
			0, 0, 0, 0, 1, 1, 2, 2, 3, 3,
			4, 4, 5, 5, 6, 6, 7, 7, 8, 8,
			9, 9, 10, 10, 11, 11, 12, 12, 13, 13
		};

		internal const int BMAX = 15;

		internal int[] hn;

		internal int[] v;

		internal int[] c;

		internal int[] r;

		internal int[] u;

		internal int[] x;

		private int huft_build(int[] b, int bindex, int n, int s, int[] d, int[] e, int[] t, int[] m, int[] hp, int[] hn, int[] v)
		{
			int num = 0;
			int num2 = n;
			do
			{
				c[b[bindex + num]]++;
				num++;
				num2--;
			}
			while (num2 != 0);
			if (c[0] == n)
			{
				t[0] = -1;
				m[0] = 0;
				return 0;
			}
			int num3 = m[0];
			int i;
			for (i = 1; i <= 15 && c[i] == 0; i++)
			{
			}
			int j = i;
			if (num3 < i)
			{
				num3 = i;
			}
			num2 = 15;
			while (num2 != 0 && c[num2] == 0)
			{
				num2--;
			}
			int num4 = num2;
			if (num3 > num2)
			{
				num3 = num2;
			}
			m[0] = num3;
			int num5 = 1 << i;
			while (i < num2)
			{
				if ((num5 -= c[i]) < 0)
				{
					return -3;
				}
				i++;
				num5 <<= 1;
			}
			if ((num5 -= c[num2]) < 0)
			{
				return -3;
			}
			c[num2] += num5;
			i = (x[1] = 0);
			num = 1;
			int num6 = 2;
			while (--num2 != 0)
			{
				i = (x[num6] = i + c[num]);
				num6++;
				num++;
			}
			num2 = 0;
			num = 0;
			do
			{
				if ((i = b[bindex + num]) != 0)
				{
					v[x[i]++] = num2;
				}
				num++;
			}
			while (++num2 < n);
			n = x[num4];
			num2 = (x[0] = 0);
			num = 0;
			int num7 = -1;
			int num8 = -num3;
			u[0] = 0;
			int num9 = 0;
			int num10 = 0;
			for (; j <= num4; j++)
			{
				int num11 = c[j];
				while (num11-- != 0)
				{
					int num12;
					while (j > num8 + num3)
					{
						num7++;
						num8 += num3;
						num10 = num4 - num8;
						num10 = ((num10 > num3) ? num3 : num10);
						if ((num12 = 1 << (i = j - num8)) > num11 + 1)
						{
							num12 -= num11 + 1;
							num6 = j;
							if (i < num10)
							{
								while (++i < num10 && (num12 <<= 1) > c[++num6])
								{
									num12 -= c[num6];
								}
							}
						}
						num10 = 1 << i;
						if (hn[0] + num10 > 1440)
						{
							return -3;
						}
						num9 = (u[num7] = hn[0]);
						hn[0] += num10;
						if (num7 != 0)
						{
							x[num7] = num2;
							r[0] = (sbyte)i;
							r[1] = (sbyte)num3;
							i = SharedUtils.URShift(num2, num8 - num3);
							r[2] = num9 - u[num7 - 1] - i;
							Array.Copy(r, 0, hp, (u[num7 - 1] + i) * 3, 3);
						}
						else
						{
							t[0] = num9;
						}
					}
					r[1] = (sbyte)(j - num8);
					if (num >= n)
					{
						r[0] = 192;
					}
					else if (v[num] < s)
					{
						r[0] = (sbyte)((v[num] >= 256) ? 96 : 0);
						r[2] = v[num++];
					}
					else
					{
						r[0] = (sbyte)(e[v[num] - s] + 16 + 64);
						r[2] = d[v[num++] - s];
					}
					num12 = 1 << j - num8;
					for (i = SharedUtils.URShift(num2, num8); i < num10; i += num12)
					{
						Array.Copy(r, 0, hp, (num9 + i) * 3, 3);
					}
					i = 1 << j - 1;
					while ((num2 & i) != 0)
					{
						num2 ^= i;
						i = SharedUtils.URShift(i, 1);
					}
					num2 ^= i;
					int num13 = (1 << num8) - 1;
					while ((num2 & num13) != x[num7])
					{
						num7--;
						num8 -= num3;
						num13 = (1 << num8) - 1;
					}
				}
			}
			if (num5 == 0 || num4 == 1)
			{
				return 0;
			}
			return -5;
		}

		internal int inflate_trees_bits(int[] c, int[] bb, int[] tb, int[] hp, ZlibCodec z)
		{
			initWorkArea(19);
			hn[0] = 0;
			int num = huft_build(c, 0, 19, 19, null, null, tb, bb, hp, hn, v);
			if (num == -3)
			{
				z.Message = "oversubscribed dynamic bit lengths tree";
			}
			else if (num == -5 || bb[0] == 0)
			{
				z.Message = "incomplete dynamic bit lengths tree";
				num = -3;
			}
			return num;
		}

		internal int inflate_trees_dynamic(int nl, int nd, int[] c, int[] bl, int[] bd, int[] tl, int[] td, int[] hp, ZlibCodec z)
		{
			initWorkArea(288);
			hn[0] = 0;
			int num = huft_build(c, 0, nl, 257, cplens, cplext, tl, bl, hp, hn, v);
			if (num != 0 || bl[0] == 0)
			{
				switch (num)
				{
				case -3:
					z.Message = "oversubscribed literal/length tree";
					break;
				default:
					z.Message = "incomplete literal/length tree";
					num = -3;
					break;
				case -4:
					break;
				}
				return num;
			}
			initWorkArea(288);
			num = huft_build(c, nl, nd, 0, cpdist, cpdext, td, bd, hp, hn, v);
			if (num != 0 || (bd[0] == 0 && nl > 257))
			{
				switch (num)
				{
				case -3:
					z.Message = "oversubscribed distance tree";
					break;
				case -5:
					z.Message = "incomplete distance tree";
					num = -3;
					break;
				default:
					z.Message = "empty distance tree with lengths";
					num = -3;
					break;
				case -4:
					break;
				}
				return num;
			}
			return 0;
		}

		internal static int inflate_trees_fixed(int[] bl, int[] bd, int[][] tl, int[][] td, ZlibCodec z)
		{
			bl[0] = 9;
			bd[0] = 5;
			tl[0] = fixed_tl;
			td[0] = fixed_td;
			return 0;
		}

		private void initWorkArea(int vsize)
		{
			if (hn == null)
			{
				hn = new int[1];
				v = new int[vsize];
				c = new int[16];
				r = new int[3];
				u = new int[15];
				x = new int[16];
				return;
			}
			if (v.Length < vsize)
			{
				v = new int[vsize];
			}
			Array.Clear(v, 0, vsize);
			Array.Clear(c, 0, 16);
			r[0] = 0;
			r[1] = 0;
			r[2] = 0;
			Array.Clear(u, 0, 15);
			Array.Clear(x, 0, 16);
		}
	}
	internal sealed class Tree
	{
		private static readonly int HEAP_SIZE = 2 * InternalConstants.L_CODES + 1;

		internal static readonly int[] ExtraLengthBits = new int[29]
		{
			0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
			1, 1, 2, 2, 2, 2, 3, 3, 3, 3,
			4, 4, 4, 4, 5, 5, 5, 5, 0
		};

		internal static readonly int[] ExtraDistanceBits = new int[30]
		{
			0, 0, 0, 0, 1, 1, 2, 2, 3, 3,
			4, 4, 5, 5, 6, 6, 7, 7, 8, 8,
			9, 9, 10, 10, 11, 11, 12, 12, 13, 13
		};

		internal static readonly int[] extra_blbits = new int[19]
		{
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 2, 3, 7
		};

		internal static readonly sbyte[] bl_order = new sbyte[19]
		{
			16, 17, 18, 0, 8, 7, 9, 6, 10, 5,
			11, 4, 12, 3, 13, 2, 14, 1, 15
		};

		internal const int Buf_size = 16;

		private static readonly sbyte[] _dist_code = new sbyte[512]
		{
			0, 1, 2, 3, 4, 4, 5, 5, 6, 6,
			6, 6, 7, 7, 7, 7, 8, 8, 8, 8,
			8, 8, 8, 8, 9, 9, 9, 9, 9, 9,
			9, 9, 10, 10, 10, 10, 10, 10, 10, 10,
			10, 10, 10, 10, 10, 10, 10, 10, 11, 11,
			11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
			11, 11, 11, 11, 12, 12, 12, 12, 12, 12,
			12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
			12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
			12, 12, 12, 12, 12, 12, 13, 13, 13, 13,
			13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
			13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
			13, 13, 13, 13, 13, 13, 13, 13, 14, 14,
			14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
			14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
			14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
			14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
			14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
			14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
			14, 14, 15, 15, 15, 15, 15, 15, 15, 15,
			15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
			15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
			15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
			15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
			15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
			15, 15, 15, 15, 15, 15, 0, 0, 16, 17,
			18, 18, 19, 19, 20, 20, 20, 20, 21, 21,
			21, 21, 22, 22, 22, 22, 22, 22, 22, 22,
			23, 23, 23, 23, 23, 23, 23, 23, 24, 24,
			24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
			24, 24, 24, 24, 25, 25, 25, 25, 25, 25,
			25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
			26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
			26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
			26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
			26, 26, 27, 27, 27, 27, 27, 27, 27, 27,
			27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
			27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
			27, 27, 27, 27, 28, 28, 28, 28, 28, 28,
			28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
			28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
			28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
			28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
			28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
			28, 28, 28, 28, 28, 28, 28, 28, 29, 29,
			29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
			29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
			29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
			29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
			29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
			29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
			29, 29
		};

		internal static readonly sbyte[] LengthCode = new sbyte[256]
		{
			0, 1, 2, 3, 4, 5, 6, 7, 8, 8,
			9, 9, 10, 10, 11, 11, 12, 12, 12, 12,
			13, 13, 13, 13, 14, 14, 14, 14, 15, 15,
			15, 15, 16, 16, 16, 16, 16, 16, 16, 16,
			17, 17, 17, 17, 17, 17, 17, 17, 18, 18,
			18, 18, 18, 18, 18, 18, 19, 19, 19, 19,
			19, 19, 19, 19, 20, 20, 20, 20, 20, 20,
			20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
			21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
			21, 21, 21, 21, 21, 21, 22, 22, 22, 22,
			22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
			22, 22, 23, 23, 23, 23, 23, 23, 23, 23,
			23, 23, 23, 23, 23, 23, 23, 23, 24, 24,
			24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
			24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
			24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
			25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
			25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
			25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
			25, 25, 26, 26, 26, 26, 26, 26, 26, 26,
			26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
			26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
			26, 26, 26, 26, 27, 27, 27, 27, 27, 27,
			27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
			27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
			27, 27, 27, 27, 27, 28
		};

		internal static readonly int[] LengthBase = new int[29]
		{
			0, 1, 2, 3, 4, 5, 6, 7, 8, 10,
			12, 14, 16, 20, 24, 28, 32, 40, 48, 56,
			64, 80, 96, 112, 128, 160, 192, 224, 0
		};

		internal static readonly int[] DistanceBase = new int[30]
		{
			0, 1, 2, 3, 4, 6, 8, 12, 16, 24,
			32, 48, 64, 96, 128, 192, 256, 384, 512, 768,
			1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576
		};

		internal short[] dyn_tree;

		internal int max_code;

		internal StaticTree staticTree;

		internal static int DistanceCode(int dist)
		{
			if (dist >= 256)
			{
				return _dist_code[256 + SharedUtils.URShift(dist, 7)];
			}
			return _dist_code[dist];
		}

		internal void gen_bitlen(DeflateManager s)
		{
			short[] array = dyn_tree;
			short[] treeCodes = staticTree.treeCodes;
			int[] extraBits = staticTree.extraBits;
			int extraBase = staticTree.extraBase;
			int maxLength = staticTree.maxLength;
			int num = 0;
			for (int i = 0; i <= InternalConstants.MAX_BITS; i++)
			{
				s.bl_count[i] = 0;
			}
			array[s.heap[s.heap_max] * 2 + 1] = 0;
			int j;
			for (j = s.heap_max + 1; j < HEAP_SIZE; j++)
			{
				int num2 = s.heap[j];
				int i = array[array[num2 * 2 + 1] * 2 + 1] + 1;
				if (i > maxLength)
				{
					i = maxLength;
					num++;
				}
				array[num2 * 2 + 1] = (short)i;
				if (num2 <= max_code)
				{
					s.bl_count[i]++;
					int num3 = 0;
					if (num2 >= extraBase)
					{
						num3 = extraBits[num2 - extraBase];
					}
					short num4 = array[num2 * 2];
					s.opt_len += num4 * (i + num3);
					if (treeCodes != null)
					{
						s.static_len += num4 * (treeCodes[num2 * 2 + 1] + num3);
					}
				}
			}
			if (num == 0)
			{
				return;
			}
			do
			{
				int i = maxLength - 1;
				while (s.bl_count[i] == 0)
				{
					i--;
				}
				s.bl_count[i]--;
				s.bl_count[i + 1] = (short)(s.bl_count[i + 1] + 2);
				s.bl_count[maxLength]--;
				num -= 2;
			}
			while (num > 0);
			for (int i = maxLength; i != 0; i--)
			{
				int num2 = s.bl_count[i];
				while (num2 != 0)
				{
					int num5 = s.heap[--j];
					if (num5 <= max_code)
					{
						if (array[num5 * 2 + 1] != i)
						{
							s.opt_len = (int)(s.opt_len + ((long)i - (long)array[num5 * 2 + 1]) * array[num5 * 2]);
							array[num5 * 2 + 1] = (short)i;
						}
						num2--;
					}
				}
			}
		}

		internal void build_tree(DeflateManager s)
		{
			short[] array = dyn_tree;
			short[] treeCodes = staticTree.treeCodes;
			int elems = staticTree.elems;
			int num = -1;
			s.heap_len = 0;
			s.heap_max = HEAP_SIZE;
			for (int i = 0; i < elems; i++)
			{
				if (array[i * 2] != 0)
				{
					num = (s.heap[++s.heap_len] = i);
					s.depth[i] = 0;
				}
				else
				{
					array[i * 2 + 1] = 0;
				}
			}
			int num2;
			while (s.heap_len < 2)
			{
				num2 = (s.heap[++s.heap_len] = ((num < 2) ? (++num) : 0));
				array[num2 * 2] = 1;
				s.depth[num2] = 0;
				s.opt_len--;
				if (treeCodes != null)
				{
					s.static_len -= treeCodes[num2 * 2 + 1];
				}
			}
			max_code = num;
			for (int i = s.heap_len / 2; i >= 1; i--)
			{
				s.pqdownheap(array, i);
			}
			num2 = elems;
			do
			{
				int i = s.heap[1];
				s.heap[1] = s.heap[s.heap_len--];
				s.pqdownheap(array, 1);
				int num3 = s.heap[1];
				s.heap[--s.heap_max] = i;
				s.heap[--s.heap_max] = num3;
				array[num2 * 2] = (short)(array[i * 2] + array[num3 * 2]);
				s.depth[num2] = (sbyte)(Math.Max((byte)s.depth[i], (byte)s.depth[num3]) + 1);
				array[i * 2 + 1] = (array[num3 * 2 + 1] = (short)num2);
				s.heap[1] = num2++;
				s.pqdownheap(ar

ULTRASKINS/System.IO.dll

Decompiled 6 months ago
using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("System.IO")]
[assembly: AssemblyDescription("System.IO")]
[assembly: AssemblyDefaultAlias("System.IO")]
[assembly: AssemblyCompany("Microsoft Corporation")]
[assembly: AssemblyProduct("Microsoft® .NET Framework")]
[assembly: AssemblyCopyright("© Microsoft Corporation.  All rights reserved.")]
[assembly: AssemblyFileVersion("4.6.24705.01")]
[assembly: AssemblyInformationalVersion("4.6.24705.01. Commit Hash: 4d1af962ca0fede10beb01d197367c2f90e92c97")]
[assembly: CLSCompliant(true)]
[assembly: AssemblyMetadata(".NETFrameworkAssembly", "")]
[assembly: AssemblyMetadata("Serviceable", "True")]
[assembly: AssemblyVersion("4.1.1.0")]
[assembly: TypeForwardedTo(typeof(BinaryReader))]
[assembly: TypeForwardedTo(typeof(BinaryWriter))]
[assembly: TypeForwardedTo(typeof(BufferedStream))]
[assembly: TypeForwardedTo(typeof(EndOfStreamException))]
[assembly: TypeForwardedTo(typeof(FileNotFoundException))]
[assembly: TypeForwardedTo(typeof(InvalidDataException))]
[assembly: TypeForwardedTo(typeof(IOException))]
[assembly: TypeForwardedTo(typeof(MemoryStream))]
[assembly: TypeForwardedTo(typeof(SeekOrigin))]
[assembly: TypeForwardedTo(typeof(Stream))]
[assembly: TypeForwardedTo(typeof(StreamReader))]
[assembly: TypeForwardedTo(typeof(StreamWriter))]
[assembly: TypeForwardedTo(typeof(StringReader))]
[assembly: TypeForwardedTo(typeof(StringWriter))]
[assembly: TypeForwardedTo(typeof(TextReader))]
[assembly: TypeForwardedTo(typeof(TextWriter))]

ULTRASKINS/System.Runtime.Extensions.dll

Decompiled 6 months ago
using System;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using FxResources.System.Runtime.Extensions;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: NeutralResourcesLanguage("en-US")]
[assembly: AssemblyTitle("System.Runtime.Extensions")]
[assembly: AssemblyDescription("System.Runtime.Extensions")]
[assembly: AssemblyDefaultAlias("System.Runtime.Extensions")]
[assembly: AssemblyCompany("Microsoft Corporation")]
[assembly: AssemblyProduct("Microsoft® .NET Framework")]
[assembly: AssemblyCopyright("© Microsoft Corporation. All rights reserved.")]
[assembly: AssemblyFileVersion("4.6.27406.03")]
[assembly: AssemblyInformationalVersion("4.6.27406.03. Commit Hash: 26264e3fd68356ff1a98375161b67b4426d02774")]
[assembly: CLSCompliant(true)]
[assembly: AssemblyMetadata(".NETFrameworkAssembly", "")]
[assembly: AssemblyMetadata("Serviceable", "True")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("4.1.1.1")]
[assembly: TypeForwardedTo(typeof(BitConverter))]
[assembly: TypeForwardedTo(typeof(Convert))]
[assembly: TypeForwardedTo(typeof(Stopwatch))]
[assembly: TypeForwardedTo(typeof(Environment))]
[assembly: TypeForwardedTo(typeof(Path))]
[assembly: TypeForwardedTo(typeof(Math))]
[assembly: TypeForwardedTo(typeof(MidpointRounding))]
[assembly: TypeForwardedTo(typeof(WebUtility))]
[assembly: TypeForwardedTo(typeof(Progress<>))]
[assembly: TypeForwardedTo(typeof(Random))]
[assembly: TypeForwardedTo(typeof(FrameworkName))]
[assembly: TypeForwardedTo(typeof(StringComparer))]
[assembly: TypeForwardedTo(typeof(UriBuilder))]
[module: UnverifiableCode]
namespace FxResources.System.Runtime.Extensions
{
	internal static class SR
	{
	}
}
namespace System
{
	internal static class SR
	{
		private static ResourceManager s_resourceManager;

		private const string s_resourcesName = "FxResources.System.Runtime.Extensions.SR";

		private static ResourceManager ResourceManager
		{
			get
			{
				if (s_resourceManager == null)
				{
					s_resourceManager = new ResourceManager(ResourceType);
				}
				return s_resourceManager;
			}
		}

		internal static string Argument_AddingDuplicate => GetResourceString("Argument_AddingDuplicate", null);

		internal static string Argument_FrameworkNameMissingVersion => GetResourceString("Argument_FrameworkNameMissingVersion", null);

		internal static string Argument_FrameworkNameInvalid => GetResourceString("Argument_FrameworkNameInvalid", null);

		internal static string Argument_FrameworkNameInvalidVersion => GetResourceString("Argument_FrameworkNameInvalidVersion", null);

		internal static string Argument_FrameworkNameTooShort => GetResourceString("Argument_FrameworkNameTooShort", null);

		internal static string net_emptystringcall => GetResourceString("net_emptystringcall", null);

		internal static string Arg_ArrayPlusOffTooSmall => GetResourceString("Arg_ArrayPlusOffTooSmall", null);

		internal static string ArgumentOutOfRange_Index => GetResourceString("ArgumentOutOfRange_Index", null);

		internal static string ArgumentOutOfRange_GenericPositive => GetResourceString("ArgumentOutOfRange_GenericPositive", null);

		internal static string ArgumentOutOfRange_StartIndex => GetResourceString("ArgumentOutOfRange_StartIndex", null);

		internal static string ArgumentOutOfRange_LengthTooLarge => GetResourceString("ArgumentOutOfRange_LengthTooLarge", null);

		internal static string ArgumentOutOfRange_NeedNonNegNum => GetResourceString("ArgumentOutOfRange_NeedNonNegNum", null);

		internal static string ArgumentOutOfRange_FileLengthTooBig => GetResourceString("ArgumentOutOfRange_FileLengthTooBig", null);

		internal static string Arg_InvalidSearchPattern => GetResourceString("Arg_InvalidSearchPattern", null);

		internal static string Arg_PathGlobalRoot => GetResourceString("Arg_PathGlobalRoot", null);

		internal static string Arg_PathIllegal => GetResourceString("Arg_PathIllegal", null);

		internal static string Arg_PathIllegalUNC => GetResourceString("Arg_PathIllegalUNC", null);

		internal static string Arg_Path2IsRooted => GetResourceString("Arg_Path2IsRooted", null);

		internal static string Argument_InvalidPathChars => GetResourceString("Argument_InvalidPathChars", null);

		internal static string Argument_PathEmpty => GetResourceString("Argument_PathEmpty", null);

		internal static string Argument_MinMaxValue => GetResourceString("Argument_MinMaxValue", null);

		internal static string Argument_PathFormatNotSupported => GetResourceString("Argument_PathFormatNotSupported", null);

		internal static string Argument_PathUriFormatNotSupported => GetResourceString("Argument_PathUriFormatNotSupported", null);

		internal static string ArgumentOutOfRange_MustBePositive => GetResourceString("ArgumentOutOfRange_MustBePositive", null);

		internal static string IO_PathTooLong => GetResourceString("IO_PathTooLong", null);

		internal static string IO_FileNotFound => GetResourceString("IO_FileNotFound", null);

		internal static string UnauthorizedAccess_IODenied_NoPathName => GetResourceString("UnauthorizedAccess_IODenied_NoPathName", null);

		internal static string UnauthorizedAccess_IODenied_Path => GetResourceString("UnauthorizedAccess_IODenied_Path", null);

		internal static string IO_SharingViolation_NoFileName => GetResourceString("IO_SharingViolation_NoFileName", null);

		internal static string IO_FileNotFound_FileName => GetResourceString("IO_FileNotFound_FileName", null);

		internal static string IO_PathNotFound_NoPathName => GetResourceString("IO_PathNotFound_NoPathName", null);

		internal static string IO_PathNotFound_Path => GetResourceString("IO_PathNotFound_Path", null);

		internal static string IO_AlreadyExists_Name => GetResourceString("IO_AlreadyExists_Name", null);

		internal static string IO_SharingViolation_File => GetResourceString("IO_SharingViolation_File", null);

		internal static string IO_FileExists_Name => GetResourceString("IO_FileExists_Name", null);

		internal static string InvalidOperation_Cryptography => GetResourceString("InvalidOperation_Cryptography", null);

		internal static string UnknownError_Num => GetResourceString("UnknownError_Num", null);

		internal static Type ResourceType => typeof(SR);

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static bool UsingResourceKeys()
		{
			return false;
		}

		internal static string GetResourceString(string resourceKey, string defaultString)
		{
			string text = null;
			try
			{
				text = ResourceManager.GetString(resourceKey);
			}
			catch (MissingManifestResourceException)
			{
			}
			if (defaultString != null && resourceKey.Equals(text, StringComparison.Ordinal))
			{
				return defaultString;
			}
			return text;
		}

		internal static string Format(string resourceFormat, params object[] args)
		{
			if (args != null)
			{
				if (UsingResourceKeys())
				{
					return resourceFormat + string.Join(", ", args);
				}
				return string.Format(resourceFormat, args);
			}
			return resourceFormat;
		}

		internal static string Format(string resourceFormat, object p1)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1);
			}
			return string.Format(resourceFormat, p1);
		}

		internal static string Format(string resourceFormat, object p1, object p2)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1, p2);
			}
			return string.Format(resourceFormat, p1, p2);
		}

		internal static string Format(string resourceFormat, object p1, object p2, object p3)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1, p2, p3);
			}
			return string.Format(resourceFormat, p1, p2, p3);
		}
	}
}

ULTRASKINS/UltraSkins.dll

Decompiled 6 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using HarmonyLib;
using Ionic.Zlib;
using Microsoft.CodeAnalysis;
using PluginConfig.API;
using PluginConfig.API.Fields;
using PluginConfig.API.Functionals;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("UltraSkins")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("UltraSkins")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+a9b655e661e2d5d5437e7bac14305570c0773b23")]
[assembly: AssemblyProduct("UltraSkins")]
[assembly: AssemblyTitle("UltraSkins")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace UltraSkins
{
	public class PageButton : MonoBehaviour
	{
		public GameObject Activator;

		public ULTRASKINHand UKSH;

		public PageEventHandler pageEventHandler;

		public int moveamount;

		private void Update()
		{
			if ((Object)(object)Activator != (Object)null && Activator.activeSelf)
			{
				Activator.SetActive(false);
				pageEventHandler.pageNumber += moveamount;
				pageEventHandler.UpdatePage();
			}
		}
	}
	public class PageEventHandler : MonoBehaviour
	{
		public ULTRASKINHand UKSH;

		public float pageNumber = 0f;

		public float pagesamount;

		public void UpdatePage()
		{
			if (pageNumber < 0f)
			{
				pageNumber = 0f;
			}
			else if (pageNumber > pagesamount)
			{
				pageNumber = pagesamount;
			}
			for (int i = 0; i < ((Component)this).transform.childCount; i++)
			{
				((Component)((Component)this).transform.GetChild(i)).gameObject.SetActive(false);
			}
			((Component)((Component)this).transform.GetChild((int)Mathf.Round(pageNumber))).gameObject.SetActive(true);
		}
	}
	public class SkinEventHandler : MonoBehaviour
	{
		public class StringSerializer
		{
			public void SerializeStringToFile(string data, string filePath)
			{
				using FileStream serializationStream = new FileStream(filePath, FileMode.Create);
				BinaryFormatter binaryFormatter = new BinaryFormatter();
				binaryFormatter.Serialize(serializationStream, data);
			}

			public string DeserializeStringFromFile(string filePath)
			{
				using FileStream serializationStream = new FileStream(filePath, FileMode.Open);
				BinaryFormatter binaryFormatter = new BinaryFormatter();
				return (string)binaryFormatter.Deserialize(serializationStream);
			}
		}

		public GameObject Activator;

		public string path;

		public string pname;

		public ULTRASKINHand UKSH;

		private void Update()
		{
			if (!((Object)(object)Activator != (Object)null) || !Activator.activeSelf)
			{
				return;
			}
			Activator.SetActive(false);
			string text = UKSH.ReloadTextures(firsttime: false, path);
			string modFolderPath = GetModFolderPath();
			TextureOverWatch[] componentsInChildren = GameObject.FindWithTag("MainCamera").GetComponentsInChildren<TextureOverWatch>(true);
			TextureOverWatch[] array = componentsInChildren;
			foreach (TextureOverWatch textureOverWatch in array)
			{
				if (Object.op_Implicit((Object)(object)textureOverWatch) && Object.op_Implicit((Object)(object)((Component)textureOverWatch).gameObject))
				{
					((Behaviour)textureOverWatch).enabled = true;
				}
			}
			MonoSingleton<HudMessageReceiver>.Instance.SendHudMessage(text, "", "", 0, false);
		}

		public string GetModFolderPath()
		{
			string text = Assembly.GetExecutingAssembly().Location.ToString();
			string directoryName = Path.GetDirectoryName(text);
			string data = Path.Combine(directoryName + "\\OG-SKINS");
			StringSerializer stringSerializer = new StringSerializer();
			string filePath = Path.Combine(directoryName + "\\data.USGC");
			if (!File.Exists(Path.Combine(directoryName + "\\data.USGC")))
			{
				stringSerializer.SerializeStringToFile(data, filePath);
			}
			if (!File.Exists(Path.Combine(directoryName + "\\OG-SKINS")) && File.Exists(Path.Combine(directoryName + "\\OG-SKINS.GCskin")))
			{
				ExtractSkin(Path.Combine(directoryName + "\\OG-SKINS.GCskin"));
			}
			return stringSerializer.DeserializeStringFromFile(filePath);
		}

		public static void ExtractSkin(string skinFilePath)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			string extractFolder = Path.Combine(Path.GetDirectoryName(skinFilePath), Path.GetFileNameWithoutExtension(skinFilePath));
			try
			{
				Directory.CreateDirectory(extractFolder);
				using FileStream fileStream = File.OpenRead(skinFilePath);
				ZlibStream val = new ZlibStream((Stream)fileStream, (CompressionMode)1);
				try
				{
					ExtractFromZlibStream(val, extractFolder);
				}
				finally
				{
					((IDisposable)val)?.Dispose();
				}
			}
			catch (Exception)
			{
			}
		}

		private static void ExtractFromZlibStream(ZlibStream zlibStream, string extractFolder)
		{
			try
			{
				byte[] array = new byte[4096];
				Directory.CreateDirectory(extractFolder);
				int num = 0;
				string text;
				while ((text = ReadLineFromZlibStream(zlibStream)) != null)
				{
					text = text.Trim();
					string fileName = Path.GetFileName(text);
					fileName = ReplaceInvalidFileNameChars(fileName);
					string text2 = Path.Combine(extractFolder, fileName);
					try
					{
						byte[] array2 = new byte[4];
						((Stream)(object)zlibStream).Read(array2, 0, array2.Length);
						int num2 = BitConverter.ToInt32(array2, 0);
						if (!fileName.Contains(".png"))
						{
							break;
						}
						using (FileStream fileStream = File.Create(text2))
						{
							long num3 = num2;
							while (num3 > 0)
							{
								int count = (int)Math.Min(num3, array.Length);
								int num4 = ((Stream)(object)zlibStream).Read(array, 0, count);
								if (num4 == 0)
								{
									throw new Exception("Unexpected end of stream.");
								}
								fileStream.Write(array, 0, num4);
								num3 -= num4;
							}
						}
						num++;
					}
					catch (Exception)
					{
					}
				}
			}
			catch (Exception)
			{
			}
		}

		private static string ReplaceInvalidFileNameChars(string fileName)
		{
			char[] invalidFileNameChars = Path.GetInvalidFileNameChars();
			foreach (char c in invalidFileNameChars)
			{
				fileName = fileName.Replace(c.ToString(), "_");
			}
			return fileName;
		}

		private static string ReadLineFromZlibStream(ZlibStream zlibStream)
		{
			try
			{
				MemoryStream memoryStream = new MemoryStream();
				int num;
				while ((num = ((Stream)(object)zlibStream).ReadByte()) != -1 && num != 10)
				{
					memoryStream.WriteByte((byte)num);
				}
				return Encoding.UTF8.GetString(memoryStream.ToArray());
			}
			catch
			{
				return null;
			}
		}
	}
	public class TextureOverWatch : MonoBehaviour
	{
		public Material[] cachedMaterials;

		public Renderer renderer;

		public bool forceswap;

		private string swapType = "weapon";

		private void OnEnable()
		{
			if (Object.op_Implicit((Object)(object)((Component)this).GetComponentInParent<Nail>()) || Object.op_Implicit((Object)(object)((Component)this).GetComponent<Coin>()))
			{
				swapType = "projectile";
			}
			if (Object.op_Implicit((Object)(object)((Component)this).GetComponentInParent<Grenade>()))
			{
				swapType = (((Component)this).GetComponentInParent<Grenade>().rocket ? "rocket" : "grenade");
			}
			if (!Object.op_Implicit((Object)(object)renderer))
			{
				renderer = ((Component)this).GetComponent<Renderer>();
			}
			if (renderer.materials != cachedMaterials)
			{
				UpdateMaterials();
			}
		}

		public void UpdateMaterials()
		{
			if (Object.op_Implicit((Object)(object)renderer) && renderer.materials != cachedMaterials)
			{
				Material[] materials = renderer.materials;
				for (int i = 0; i < materials.Length; i++)
				{
					ULTRASKINHand.PerformTheSwap(materials[i], forceswap, ((Component)((Component)this).transform).GetComponent<TextureOverWatch>(), swapType);
				}
				cachedMaterials = renderer.materials;
			}
			((Behaviour)((Component)((Component)this).transform).GetComponent<TextureOverWatch>()).enabled = false;
		}
	}
	[BepInPlugin("ultrakill.UltraSkins.bobthecorn", "UltraSkins", "3.1.1")]
	[BepInDependency("com.eternalUnion.pluginConfigurator", "1.7.0")]
	public class ULTRASKINHand : BaseUnityPlugin
	{
		[HarmonyPatch]
		public class HarmonyGunPatcher
		{
			[HarmonyPatch(typeof(GunControl), "SwitchWeapon", new Type[]
			{
				typeof(int),
				typeof(List<GameObject>),
				typeof(bool),
				typeof(bool),
				typeof(bool),
				typeof(bool)
			})]
			[HarmonyPostfix]
			public static void SwitchWeaponPost(GunControl __instance, int target, List<GameObject> slot, bool lastUsedSlot = false, bool useRetainedVariation = false, bool scrolled = false, bool isNextVarBind = false)
			{
				TextureOverWatch[] componentsInChildren = __instance.currentWeapon.GetComponentsInChildren<TextureOverWatch>(true);
				ReloadTextureOverWatch(componentsInChildren);
			}

			[HarmonyPatch(typeof(GunControl), "YesWeapon")]
			[HarmonyPostfix]
			public static void WeaponYesPost(GunControl __instance)
			{
				if (!__instance.noWeapons)
				{
					TextureOverWatch[] componentsInChildren = __instance.currentWeapon.GetComponentsInChildren<TextureOverWatch>(true);
					ReloadTextureOverWatch(componentsInChildren);
				}
			}

			[HarmonyPatch(typeof(GunControl), "UpdateWeaponList", new Type[] { typeof(bool) })]
			[HarmonyPostfix]
			public static void UpdateWeaponListPost(GunControl __instance, bool firstTime = false)
			{
				InitOWGameObjects(firsttime: true);
				TextureOverWatch[] componentsInChildren = ((Component)MonoSingleton<CameraController>.Instance).gameObject.GetComponentsInChildren<TextureOverWatch>(true);
				ReloadTextureOverWatch(componentsInChildren);
			}

			[HarmonyPatch(typeof(FistControl), "YesFist")]
			[HarmonyPostfix]
			public static void YesFistPost(FistControl __instance)
			{
				if (Object.op_Implicit((Object)(object)__instance.currentArmObject))
				{
					TextureOverWatch[] componentsInChildren = __instance.currentArmObject.GetComponentsInChildren<TextureOverWatch>(true);
					ReloadTextureOverWatch(componentsInChildren);
				}
			}

			[HarmonyPatch(typeof(FistControl), "ArmChange", new Type[] { typeof(int) })]
			[HarmonyPostfix]
			public static void SwitchFistPost(FistControl __instance, int orderNum)
			{
				TextureOverWatch[] componentsInChildren = __instance.currentArmObject.GetComponentsInChildren<TextureOverWatch>(true);
				ReloadTextureOverWatch(componentsInChildren);
			}

			[HarmonyPatch(typeof(FistControl), "ResetFists")]
			[HarmonyPostfix]
			public static void ResetFistsPost(FistControl __instance)
			{
				InitOWGameObjects();
				TextureOverWatch[] componentsInChildren = __instance.currentArmObject.GetComponentsInChildren<TextureOverWatch>(true);
				ReloadTextureOverWatch(componentsInChildren);
			}

			[HarmonyPatch(typeof(DualWieldPickup), "PickedUp")]
			[HarmonyPostfix]
			public static void DPickedupPost(DualWieldPickup __instance)
			{
				//IL_0018: Unknown result type (might be due to invalid IL or missing references)
				//IL_001e: Invalid comparison between Unknown and I4
				if (!Object.op_Implicit((Object)(object)MonoSingleton<GunControl>.Instance) || (int)MonoSingleton<PlayerTracker>.Instance.playerType == 1)
				{
					return;
				}
				DualWield[] componentsInChildren = ((Component)MonoSingleton<GunControl>.Instance).GetComponentsInChildren<DualWield>(true);
				DualWield[] array = componentsInChildren;
				foreach (DualWield val in array)
				{
					if (!Object.op_Implicit((Object)(object)val))
					{
						continue;
					}
					Renderer[] componentsInChildren2 = ((Component)val).GetComponentsInChildren<Renderer>(true);
					Renderer[] array2 = componentsInChildren2;
					foreach (Renderer val2 in array2)
					{
						if (Object.op_Implicit((Object)(object)val2) && ((Component)val2).gameObject.layer == 13 && !Object.op_Implicit((Object)(object)((Component)val2).gameObject.GetComponent<ParticleSystemRenderer>()) && !Object.op_Implicit((Object)(object)((Component)val2).gameObject.GetComponent<CanvasRenderer>()) && !Object.op_Implicit((Object)(object)((Component)val2).gameObject.GetComponent<TextureOverWatch>()))
						{
							TextureOverWatch textureOverWatch = ((Component)val2).gameObject.AddComponent<TextureOverWatch>();
						}
					}
				}
			}

			[HarmonyPatch(typeof(DualWield), "UpdateWeapon")]
			[HarmonyPostfix]
			public static void DUpdateWPost(DualWield __instance)
			{
				TextureOverWatch[] componentsInChildren = ((Component)__instance).GetComponentsInChildren<TextureOverWatch>(true);
				ReloadTextureOverWatch(componentsInChildren);
			}

			[HarmonyPatch(typeof(PlayerTracker), "ChangeToFPS")]
			[HarmonyPostfix]
			public static void ChangeToFPSPost(PlayerTracker __instance)
			{
				TextureOverWatch[] componentsInChildren = GameObject.FindGameObjectWithTag("GunControl").GetComponent<GunControl>().currentWeapon.GetComponentsInChildren<TextureOverWatch>(true);
				ReloadTextureOverWatch(componentsInChildren);
				TextureOverWatch[] componentsInChildren2 = GameObject.FindGameObjectWithTag("MainCamera").GetComponentInChildren<FistControl>().currentArmObject.GetComponentsInChildren<TextureOverWatch>(true);
				ReloadTextureOverWatch(componentsInChildren2);
			}

			public static void ReloadTextureOverWatch(TextureOverWatch[] TOWS)
			{
				foreach (TextureOverWatch textureOverWatch in TOWS)
				{
					((Behaviour)textureOverWatch).enabled = true;
				}
			}
		}

		[HarmonyPatch]
		public class HarmonyProjectilePatcher
		{
			[HarmonyPatch(typeof(Nail), "Start")]
			[HarmonyPostfix]
			public static void NailPost(Nail __instance)
			{
				if (__instance.sawblade)
				{
					AddTOWs(((Component)__instance).gameObject, toself: false, tochildren: true);
				}
			}

			[HarmonyPatch(typeof(Magnet), "Start")]
			[HarmonyPostfix]
			public static void MagnetPost(Magnet __instance)
			{
				AddTOWs(((Component)((Component)__instance).transform.parent).gameObject, toself: false, tochildren: true);
			}

			[HarmonyPatch(typeof(Grenade), "Start")]
			[HarmonyPostfix]
			public static void GrenadePost(Grenade __instance)
			{
				AddTOWs(((Component)__instance).gameObject, toself: false, tochildren: true);
			}

			[HarmonyPatch(typeof(Coin), "Start")]
			[HarmonyPostfix]
			public static void coinPost(Coin __instance)
			{
				AddTOWs(((Component)__instance).gameObject);
			}

			public static void ReloadTextureOverWatch(TextureOverWatch[] TOWS)
			{
				foreach (TextureOverWatch textureOverWatch in TOWS)
				{
					((Behaviour)textureOverWatch).enabled = true;
				}
			}

			public static void AddTOWs(GameObject gameobject, bool toself = true, bool tochildren = false, bool toparent = false, bool refresh = false)
			{
				if (toself)
				{
					if (!Object.op_Implicit((Object)(object)gameobject.GetComponent<TextureOverWatch>()))
					{
						gameobject.AddComponent<TextureOverWatch>();
					}
					else
					{
						((Behaviour)gameobject.GetComponent<TextureOverWatch>()).enabled = refresh;
					}
				}
				if (toparent)
				{
					Renderer[] componentsInParent = gameobject.GetComponentsInParent<Renderer>();
					Renderer[] array = componentsInParent;
					foreach (Renderer val in array)
					{
						if ((Object)(object)val != (Object)null && ((object)val).GetType() != typeof(ParticleSystemRenderer) && ((object)val).GetType() != typeof(CanvasRenderer) && ((object)val).GetType() != typeof(LineRenderer))
						{
							if (!Object.op_Implicit((Object)(object)((Component)val).GetComponent<TextureOverWatch>()))
							{
								((Component)val).gameObject.AddComponent<TextureOverWatch>();
							}
							else
							{
								((Behaviour)((Component)val).GetComponent<TextureOverWatch>()).enabled = refresh;
							}
						}
					}
				}
				if (!tochildren)
				{
					return;
				}
				Renderer[] componentsInChildren = gameobject.GetComponentsInChildren<Renderer>();
				Renderer[] array2 = componentsInChildren;
				foreach (Renderer val2 in array2)
				{
					if ((Object)(object)val2 != (Object)null && ((object)val2).GetType() != typeof(ParticleSystemRenderer) && ((object)val2).GetType() != typeof(CanvasRenderer) && ((object)val2).GetType() != typeof(LineRenderer))
					{
						if (!Object.op_Implicit((Object)(object)((Component)val2).GetComponent<TextureOverWatch>()))
						{
							((Component)val2).gameObject.AddComponent<TextureOverWatch>();
						}
						else
						{
							((Behaviour)((Component)val2).GetComponent<TextureOverWatch>()).enabled = refresh;
						}
					}
				}
			}
		}

		public PluginConfigurator config;

		public const string PLUGIN_NAME = "UltraSkins";

		public const string PLUGIN_GUID = "ultrakill.UltraSkins.bobthecorn";

		public const string PLUGIN_VERSION = "3.1.1";

		private string modFolderPath;

		private static string _modPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location));

		private static string _skinPath = Path.Combine(_modPath, "Custom");

		private List<Sprite> _default;

		private List<Sprite> _edited;

		public string pluginPath;

		public string folderupdater;

		public static Dictionary<string, Texture> autoSwapCache = new Dictionary<string, Texture>();

		public string[] directories;

		public string serializedSet = "";

		public bool swapped = false;

		private Harmony UKSHarmony;

		private AssetBundle bundle0;

		private static Shader CCE;

		private static Shader DE;

		private static Cubemap cubemap;

		public List<string> Paths
		{
			get
			{
				string[] files = Directory.GetFiles(_skinPath);
				for (int i = 0; i < files.Length; i++)
				{
					files[i] = files[i].Split(Path.DirectorySeparatorChar).Last();
				}
				return files.ToList();
			}
		}

		private void Awake()
		{
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Expected O, but got Unknown
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Expected O, but got Unknown
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Expected O, but got Unknown
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Expected O, but got Unknown
			Debugger.Break();
			config = PluginConfigurator.Create("Ultraskins", "ultrakill.ultraskins.bobthecorn");
			pluginPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
			string[] array = Directory.GetDirectories(pluginPath);
			Dictionary<string, ButtonField> dictionary = new Dictionary<string, ButtonField>();
			ConfigPanel skinfolders = new ConfigPanel(config.rootPanel, "skinfolders", "skinfolders");
			string[] array2 = array;
			foreach (string text in array2)
			{
				string text2 = (folderupdater = Path.GetFileName(text));
				ButtonField button = new ButtonField(skinfolders, text2, text2);
				dictionary[text] = button;
				button.onClick += (OnClick)delegate
				{
					refreshskins(skinfolders, ((ConfigField)button).guid);
				};
			}
			SceneManager.sceneLoaded += SceneManagerOnsceneLoaded;
			config.SetIconWithURL("https://github.com/bobthecorn2000/ULTRASKINS-GC/blob/main/UltraSkins/icon.png?raw=true");
			BoolField val = new BoolField(config.rootPanel, "Debug Mode", "DebugMode", false);
			OnModLoaded();
		}

		public void OnModLoaded()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Expected O, but got Unknown
			UKSHarmony = new Harmony("Gcorn.UltraSkins");
			UKSHarmony.PatchAll(typeof(HarmonyGunPatcher));
			UKSHarmony.PatchAll(typeof(HarmonyProjectilePatcher));
			UKSHarmony.PatchAll();
			try
			{
				SkinEventHandler skinEventHandler = new SkinEventHandler();
				string text = skinEventHandler.GetModFolderPath();
			}
			catch (Exception ex)
			{
				ButtonField val = new ButtonField(config.rootPanel, ex.ToString(), ex.ToString());
			}
		}

		private void refreshskins(ConfigPanel folderpage, string clickedButton)
		{
			Debug.Log((object)("pannel close:" + clickedButton));
			SkinEventHandler.StringSerializer stringSerializer = new SkinEventHandler.StringSerializer();
			string path = Assembly.GetExecutingAssembly().Location.ToString();
			string directoryName = Path.GetDirectoryName(path);
			string text = Path.Combine(directoryName + "\\" + clickedButton);
			Debug.Log((object)("folderis: " + text));
			stringSerializer.SerializeStringToFile(text, Path.Combine(directoryName + "\\data.USGC"));
			ReloadTextures(firsttime: true, text);
			folderpage.ClosePanel();
		}

		private void refreshskins()
		{
			SkinEventHandler.StringSerializer stringSerializer = new SkinEventHandler.StringSerializer();
			string path = Assembly.GetExecutingAssembly().Location.ToString();
			string directoryName = Path.GetDirectoryName(path);
			string path2 = stringSerializer.DeserializeStringFromFile(Path.Combine(directoryName + "\\data.USGC"));
			ReloadTextures(firsttime: true, path2);
		}

		private void Start()
		{
		}

		private void SceneManagerOnsceneLoaded(Scene scene, LoadSceneMode mode)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: 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)
			swapped = false;
			if ((Object)(object)CCE == (Object)null)
			{
				CCE = Addressables.LoadAssetAsync<Shader>((object)"Assets/Shaders/Special/ULTRAKILL-vertexlit-customcolors-emissive.shader").WaitForCompletion();
			}
			if ((Object)(object)DE == (Object)null)
			{
				DE = Addressables.LoadAssetAsync<Shader>((object)"Assets/Shaders/Main/ULTRAKILL-vertexlit-emissive.shader").WaitForCompletion();
			}
			if ((Object)(object)cubemap == (Object)null)
			{
				cubemap = Addressables.LoadAssetAsync<Cubemap>((object)"Assets/Textures/studio_06.exr").WaitForCompletion();
			}
			refreshskins();
		}

		public static Texture ResolveTheTextureProperty(Material mat, string property, string propertyfallback = "_MainTex")
		{
			//IL_0038: 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)
			if ((Object)(object)mat != (Object)null && (Object)(object)mat.mainTexture == (Object)null)
			{
				return null;
			}
			if ((Object)(object)DE == (Object)null)
			{
				DE = Addressables.LoadAssetAsync<Shader>((object)"Assets/Shaders/Main/ULTRAKILL-vertexlit-emissive.shader").WaitForCompletion();
			}
			string text = "";
			if (Object.op_Implicit((Object)(object)mat) && !((Object)mat.mainTexture).name.StartsWith("TNR_") && property != "_Cube")
			{
				switch (property)
				{
				case "_MainTex":
					text = ((Object)mat.mainTexture).name;
					break;
				case "_EmissiveTex":
				{
					string name = ((Object)mat.mainTexture).name;
					string text2 = name;
					text = ((text2 == "T_NailgunNew_NoGlow") ? "T_Nailgun_New_Glow" : ((!(text2 == "T_RocketLauncher_Desaturated")) ? (((Object)mat.mainTexture).name + "_Emissive") : "T_RocketLauncher_Emissive"));
					break;
				}
				case "_IDTex":
					text = ((Object)mat.mainTexture).name switch
					{
						"T_RocketLauncher_Desaturated" => "T_RocketLauncher_ID", 
						"T_NailgunNew_NoGlow" => "T_NailgunNew_ID", 
						"Railgun_Main_AlphaGlow" => "T_Railgun_ID", 
						_ => ((Object)mat.mainTexture).name + "_ID", 
					};
					break;
				case "ROCKIT":
					text = ((((Object)mat).name.Contains("Swapped_AltarUnlitRed") && !((Object)mat.mainTexture).name.StartsWith("T_")) ? "skull2rocketbonus" : (((Object)mat.mainTexture).name.Contains("T_Sakuya") ? "" : "skull2rocket"));
					break;
				case "THROWITBACK":
					text = "skull2 compressed";
					break;
				default:
					text = "";
					break;
				}
				if (text != "" && autoSwapCache.ContainsKey(text))
				{
					return autoSwapCache[text];
				}
			}
			return mat.GetTexture(propertyfallback);
		}

		public static void PerformTheSwap(Material mat, bool forceswap = false, TextureOverWatch TOW = null, string swapType = "weapon")
		{
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Expected O, but got Unknown
			//IL_01c3: 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_01eb: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)mat) || !(!((Object)mat).name.StartsWith("Swapped_") || forceswap))
			{
				return;
			}
			if (!((Object)mat).name.StartsWith("Swapped_"))
			{
				((Object)mat).name = "Swapped_" + ((Object)mat).name;
			}
			if (((Object)mat.shader).name == "psx/vertexlit/vertexlit-customcolors" && Object.op_Implicit((Object)(object)CCE))
			{
				mat.shader = CCE;
			}
			else if (((Object)mat.shader).name == "psx/vertexlit/vertexlit")
			{
				mat.shader = DE;
			}
			forceswap = false;
			Texture val = new Texture();
			switch (swapType)
			{
			case "weapon":
			{
				string[] texturePropertyNames = mat.GetTexturePropertyNames();
				string[] array = texturePropertyNames;
				Color val2 = default(Color);
				foreach (string text in array)
				{
					Debug.Log((object)("Attempting to swap " + text + " of " + ((Object)mat).name.ToString()));
					val = ResolveTheTextureProperty(mat, text, text);
					if (Object.op_Implicit((Object)(object)val) && (Object)(object)val != (Object)null && mat.HasProperty(text) && (Object)(object)mat.GetTexture(text) != (Object)(object)val)
					{
						Debug.Log((object)("swapping " + text + " of " + ((Object)mat).name.ToString()));
						mat.SetTexture(text, val);
					}
					if ((Object)(object)TOW != (Object)null && mat.HasProperty("_EmissiveColor"))
					{
						Debug.Log((object)("swapping " + text + " of " + ((Object)mat).name.ToString()));
						Color varationColor = GetVarationColor(TOW);
						((Color)(ref val2))..ctor(255f, 255f, 255f, 255f);
						mat.SetColor("_EmissiveColor", varationColor);
					}
				}
				break;
			}
			case "projectile":
				val = ResolveTheTextureProperty(mat, "_MainTex");
				if (Object.op_Implicit((Object)(object)val) && (Object)(object)val != (Object)null && mat.HasProperty("_MainTex") && (Object)(object)mat.GetTexture("_MainTex") != (Object)(object)val)
				{
					mat.SetTexture("_MainTex", val);
				}
				break;
			case "grenade":
				val = ResolveTheTextureProperty(mat, "THROWITBACK");
				if (Object.op_Implicit((Object)(object)val) && (Object)(object)val != (Object)null && mat.HasProperty("_MainTex") && (Object)(object)mat.GetTexture("_MainTex") != (Object)(object)val)
				{
					mat.SetTexture("_MainTex", val);
				}
				break;
			case "rocket":
				val = ResolveTheTextureProperty(mat, "ROCKIT");
				if (Object.op_Implicit((Object)(object)val) && (Object)(object)val != (Object)null && mat.HasProperty("_MainTex") && (Object)(object)mat.GetTexture("_MainTex") != (Object)(object)val)
				{
					mat.SetTexture("_MainTex", val);
				}
				break;
			}
		}

		public static Color GetVarationColor(TextureOverWatch TOW)
		{
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: 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_01e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: 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_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Invalid comparison between Unknown and I4
			Color result = default(Color);
			((Color)(ref result))..ctor(0f, 0f, 0f, 0f);
			if (Object.op_Implicit((Object)(object)((Component)TOW).GetComponentInParent<WeaponIcon>()))
			{
				WeaponIcon componentInParent = ((Component)TOW).GetComponentInParent<WeaponIcon>();
				Type type = ((object)componentInParent).GetType();
				PropertyInfo property = type.GetProperty("variationColor", BindingFlags.Instance | BindingFlags.NonPublic);
				int num = (int)property.GetValue(componentInParent);
				((Color)(ref result))..ctor(MonoSingleton<ColorBlindSettings>.Instance.variationColors[num].r, MonoSingleton<ColorBlindSettings>.Instance.variationColors[num].g, MonoSingleton<ColorBlindSettings>.Instance.variationColors[num].b, 1f);
			}
			else if (Object.op_Implicit((Object)(object)((Component)TOW).GetComponentInParent<Punch>()))
			{
				Punch componentInParent2 = ((Component)TOW).GetComponentInParent<Punch>();
				FistType type2 = componentInParent2.type;
				FistType val = type2;
				if ((int)val != 0)
				{
					if ((int)val == 1)
					{
						((Color)(ref result))..ctor(MonoSingleton<ColorBlindSettings>.Instance.variationColors[2].r, MonoSingleton<ColorBlindSettings>.Instance.variationColors[2].g, MonoSingleton<ColorBlindSettings>.Instance.variationColors[2].b, 1f);
					}
				}
				else
				{
					((Color)(ref result))..ctor(MonoSingleton<ColorBlindSettings>.Instance.variationColors[0].r, MonoSingleton<ColorBlindSettings>.Instance.variationColors[0].g, MonoSingleton<ColorBlindSettings>.Instance.variationColors[0].b, 1f);
				}
			}
			else if (Object.op_Implicit((Object)(object)((Component)TOW).GetComponentInParent<HookArm>()))
			{
				((Color)(ref result))..ctor(MonoSingleton<ColorBlindSettings>.Instance.variationColors[1].r, MonoSingleton<ColorBlindSettings>.Instance.variationColors[1].g, MonoSingleton<ColorBlindSettings>.Instance.variationColors[1].b, 1f);
			}
			return result;
		}

		private void Update(SkinEventHandler skinEventHandler)
		{
			modFolderPath = skinEventHandler.GetModFolderPath();
			if (!swapped)
			{
				if (Directory.Exists(modFolderPath))
				{
					serializedSet = modFolderPath;
				}
				ReloadTextures(firsttime: false, modFolderPath);
				swapped = true;
			}
		}

		public static bool CheckTextureInCache(string name)
		{
			if (autoSwapCache.ContainsKey(name))
			{
				return true;
			}
			return false;
		}

		public string ReloadTextures(bool firsttime = false, string path = "")
		{
			if (firsttime && serializedSet != "")
			{
				path = serializedSet;
			}
			else if (firsttime && serializedSet == "")
			{
				path = path;
			}
			if (path == "")
			{
				path = path;
			}
			InitOWGameObjects(firsttime);
			return LoadTextures(path);
		}

		public static void InitOWGameObjects(bool firsttime = false)
		{
			GameObject val = GameObject.FindGameObjectWithTag("MainCamera");
			Renderer[] componentsInChildren = val.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val2 in componentsInChildren)
			{
				if (((Component)val2).gameObject.layer == 13 && !Object.op_Implicit((Object)(object)((Component)val2).gameObject.GetComponent<ParticleSystemRenderer>()) && !Object.op_Implicit((Object)(object)((Component)val2).gameObject.GetComponent<TrailRenderer>()) && !Object.op_Implicit((Object)(object)((Component)val2).gameObject.GetComponent<LineRenderer>()))
				{
					if (Object.op_Implicit((Object)(object)((Component)val2).GetComponent<TextureOverWatch>()) && !firsttime)
					{
						TextureOverWatch component = ((Component)val2).GetComponent<TextureOverWatch>();
						((Behaviour)component).enabled = true;
						component.forceswap = true;
					}
					else if (!Object.op_Implicit((Object)(object)((Component)val2).GetComponent<TextureOverWatch>()))
					{
						((Behaviour)((Component)val2).gameObject.AddComponent<TextureOverWatch>()).enabled = true;
					}
				}
			}
		}

		public string LoadTextures(string fpath = "")
		{
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Expected O, but got Unknown
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Expected O, but got Unknown
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Expected O, but got Unknown
			Debug.Log((object)fpath.ToString());
			autoSwapCache.Clear();
			bool flag = false;
			DirectoryInfo directoryInfo = new DirectoryInfo(fpath);
			if (!directoryInfo.Exists)
			{
				return "failed";
			}
			FileInfo[] files = directoryInfo.GetFiles("*.png");
			if (files.Length != 0)
			{
				FileInfo[] array = files;
				foreach (FileInfo fileInfo in array)
				{
					if (fileInfo.Exists)
					{
						byte[] array2 = File.ReadAllBytes(fileInfo.FullName);
						string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(fileInfo.FullName);
						Texture2D val = new Texture2D(2, 2);
						((Object)val).name = fileNameWithoutExtension;
						((Texture)val).filterMode = (FilterMode)0;
						ImageConversion.LoadImage(val, array2);
						val.Apply();
						if (fileInfo.Name == "Railgun_Main_AlphaGlow.png")
						{
							Texture2D val2 = new Texture2D(2, 2);
							byte[] array3 = File.ReadAllBytes(Path.Combine(fileInfo.DirectoryName, "Railgun_Main_Emissive.png"));
							((Texture)val2).filterMode = (FilterMode)0;
							ImageConversion.LoadImage(val2, array3);
							val2.Apply();
							Color[] pixels = val.GetPixels();
							Color[] pixels2 = val2.GetPixels();
							for (int j = 0; j < pixels.Length; j++)
							{
								pixels[j].a = pixels2[j].r;
							}
							val.SetPixels(pixels);
							val.Apply();
						}
						Texture val3 = new Texture();
						val3 = (Texture)(object)val;
						autoSwapCache.Add(fileNameWithoutExtension, val3);
					}
					else
					{
						flag = true;
					}
				}
				if (!flag)
				{
					return "Successfully loaded all Textures from " + Path.GetFileName(fpath) + "!";
				}
			}
			return "Failed to load all textures from " + Path.GetFileName(fpath) + ".\nPlease ensure all of the Texture Files names are Correct, refer to the README file for the correct names and more info.";
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "UltraSkins";

		public const string PLUGIN_NAME = "UltraSkins";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}

ULTRASKINS/USutils.dll

Decompiled 6 months ago
using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using Ionic.Zlib;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(/*Could not decode attribute arguments.*/)]
[assembly: TargetFramework(".NETCoreApp,Version=v8.0", FrameworkDisplayName = ".NET 8.0")]
[assembly: AssemblyCompany("USutils")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+9b4e1f79e0da2bf83ac796a79be7e9a359c4f4e8")]
[assembly: AssemblyProduct("USutils")]
[assembly: AssemblyTitle("USutils")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace UltraSkinsPacker;

public class Skinpacker
{
	private static Stream zipFileStream;

	private static void Main(string[] args)
	{
		//IL_006f: Unknown result type (might be due to invalid IL or missing references)
		if (args.Length == 0)
		{
			Console.WriteLine("Drag a folder onto this executable to compress it, or a GCskin file to extract it.");
			return;
		}
		string text = args[0];
		if (Directory.Exists(text))
		{
			CompressFolder(text);
		}
		else if (File.Exists(text) && text.EndsWith(".GCskin", (StringComparison)5))
		{
			ExtractSkin(text);
		}
		else
		{
			Console.WriteLine("Invalid input. Drag a folder to compress or a GCskin file to extract.");
		}
		Console.WriteLine("Operation complete. Press any key to exit.");
		Console.ReadKey();
	}

	private static void CompressFolder(string folderPath)
	{
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: Expected O, but got Unknown
		string text = folderPath + ".GCskin";
		try
		{
			FileStream val = File.Create(text);
			try
			{
				ZlibStream val2 = new ZlibStream((Stream)(object)val, (CompressionMode)0);
				try
				{
					CompressDirectory(folderPath, val2);
				}
				finally
				{
					((global::System.IDisposable)val2)?.Dispose();
				}
			}
			finally
			{
				((global::System.IDisposable)val)?.Dispose();
			}
			Console.WriteLine("Folder '" + folderPath + "' compressed successfully.");
		}
		catch (global::System.Exception ex)
		{
			Console.WriteLine("Error compressing folder: " + ex.Message);
		}
	}

	private static void CompressDirectory(string directoryPath, ZlibStream zlibStream)
	{
		string[] files = Directory.GetFiles(directoryPath);
		string[] array = files;
		foreach (string text in array)
		{
			Console.WriteLine("compressing: " + text);
			CompressFile(text, zlibStream);
		}
		string[] directories = Directory.GetDirectories(directoryPath);
		string[] array2 = directories;
		foreach (string directoryPath2 in array2)
		{
			CompressDirectory(directoryPath2, zlibStream);
		}
	}

	private static void CompressFile(string filePath, ZlibStream zlibStream)
	{
		//IL_0031: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			string relativePath = Path.GetRelativePath(Directory.GetCurrentDirectory(), filePath);
			byte[] bytes = Encoding.UTF8.GetBytes(relativePath + Environment.NewLine);
			((Stream)zlibStream).Write(bytes, 0, bytes.Length);
			byte[] bytes2 = BitConverter.GetBytes((int)new FileInfo(filePath).Length);
			((Stream)zlibStream).Write(bytes2, 0, bytes2.Length);
			FileStream val = File.OpenRead(filePath);
			try
			{
				byte[] array = new byte[4096];
				int num;
				while ((num = ((Stream)val).Read(array, 0, array.Length)) > 0)
				{
					((Stream)zlibStream).Write(array, 0, num);
				}
			}
			finally
			{
				((global::System.IDisposable)val)?.Dispose();
			}
			Console.WriteLine("File '" + filePath + "' compressed successfully.");
		}
		catch (global::System.Exception ex)
		{
			Console.WriteLine("Error compressing file '" + filePath + "': " + ex.Message);
		}
	}

	public static void ExtractSkin(string skinFilePath)
	{
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		//IL_002b: Expected O, but got Unknown
		string text = Path.Combine(Path.GetDirectoryName(skinFilePath), Path.GetFileNameWithoutExtension(skinFilePath));
		try
		{
			Directory.CreateDirectory(text);
			FileStream val = File.OpenRead(skinFilePath);
			try
			{
				ZlibStream val2 = new ZlibStream((Stream)(object)val, (CompressionMode)1);
				try
				{
					ExtractFromZlibStream(val2, text);
				}
				finally
				{
					((global::System.IDisposable)val2)?.Dispose();
				}
			}
			finally
			{
				((global::System.IDisposable)val)?.Dispose();
			}
			Console.WriteLine($"Skin '{skinFilePath}' extracted successfully to '{text}'.");
		}
		catch (global::System.Exception ex)
		{
			Console.WriteLine("Error extracting skin: " + ex.Message);
		}
	}

	private static void ExtractFromZlibStream(ZlibStream zlibStream, string extractFolder)
	{
		try
		{
			byte[] array = new byte[4096];
			Directory.CreateDirectory(extractFolder);
			int num = 0;
			string text;
			while ((text = ReadLineFromZlibStream(zlibStream)) != null)
			{
				text = text.Trim();
				string fileName = Path.GetFileName(text);
				fileName = ReplaceInvalidFileNameChars(fileName);
				string text2 = Path.Combine(extractFolder, fileName);
				try
				{
					byte[] array2 = new byte[4];
					((Stream)zlibStream).Read(array2, 0, array2.Length);
					int num2 = BitConverter.ToInt32(array2, 0);
					if (!fileName.Contains(".png"))
					{
						return;
					}
					FileStream val = File.Create(text2);
					try
					{
						long num3 = num2;
						while (num3 > 0)
						{
							int num4 = (int)Math.Min(num3, (long)array.Length);
							int num5 = ((Stream)zlibStream).Read(array, 0, num4);
							if (num5 == 0)
							{
								throw new global::System.Exception("Unexpected end of stream.");
							}
							((Stream)val).Write(array, 0, num5);
							num3 -= num5;
						}
					}
					finally
					{
						((global::System.IDisposable)val)?.Dispose();
					}
					Console.WriteLine("Extracted file '" + text2 + "' successfully.");
					num++;
				}
				catch (global::System.Exception ex)
				{
					Console.WriteLine("Error processing file '" + text2 + "': " + ex.Message);
				}
			}
			Console.WriteLine($"Total files processed: {num}");
		}
		catch (global::System.Exception ex2)
		{
			Console.WriteLine("Error extracting from zlib stream: " + ex2.Message);
		}
	}

	private static string ReplaceInvalidFileNameChars(string fileName)
	{
		char[] invalidFileNameChars = Path.GetInvalidFileNameChars();
		foreach (char c in invalidFileNameChars)
		{
			fileName = fileName.Replace(c.ToString(), "_");
		}
		return fileName;
	}

	private static string ReadLineFromZlibStream(ZlibStream zlibStream)
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0008: Expected O, but got Unknown
		try
		{
			MemoryStream val = new MemoryStream();
			int num;
			while ((num = ((Stream)zlibStream).ReadByte()) != -1 && num != 10)
			{
				((Stream)val).WriteByte((byte)num);
			}
			return Encoding.UTF8.GetString(val.ToArray());
		}
		catch
		{
			return null;
		}
	}
}