Decompiled source of FixPluginTypesSerializationDebug v1.0.2

BepInEx/patchers/FixPluginTypesSerializationDebug/FixPluginTypesSerialization.dll

Decompiled 3 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using FixPluginTypesSerialization.Patchers;
using FixPluginTypesSerialization.UnityPlayer;
using FixPluginTypesSerialization.UnityPlayer.Structs.Default;
using FixPluginTypesSerialization.Util;
using Microsoft.CodeAnalysis;
using Microsoft.Deployment.Compression;
using Microsoft.Deployment.Compression.Cab;
using Mono.Cecil;
using MonoMod.RuntimeDetour;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8.1", FrameworkDisplayName = ".NET Framework 4.8.1")]
[assembly: AssemblyCompany("FixPluginTypesSerialization")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+37ee88f7b95fe60e83732e237129286de19299f2")]
[assembly: AssemblyProduct("FixPluginTypesSerialization")]
[assembly: AssemblyTitle("FixPluginTypesSerialization")]
[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]
	internal sealed class IsUnmanagedAttribute : Attribute
	{
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NativeIntegerAttribute : Attribute
	{
		public readonly bool[] TransformFlags;

		public NativeIntegerAttribute()
		{
			TransformFlags = new bool[1] { true };
		}

		public NativeIntegerAttribute(bool[] P_0)
		{
			TransformFlags = P_0;
		}
	}
	[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 FixPluginTypesSerialization
{
	internal static class Config
	{
		private static readonly ConfigFile _config = new ConfigFile(Path.Combine(Paths.ConfigPath, "FixPluginTypesSerializationDebug.cfg"), true);

		internal static ConfigEntry<string> UnityVersionOverride = _config.Bind<string>("Overrides", "UnityVersionOverride", "", "Unity version is Major.Minor.Patch format i.e. 2017.2.1." + Environment.NewLine + "If specified, this version will be used instead of auto-detection" + Environment.NewLine + "from executable info. Specify only if the patcher doesn't work otherwise.");

		internal static ConfigEntry<FunctionOffsetLookup> FunctionOffsetLookupType = _config.Bind<FunctionOffsetLookup>("Overrides", "FunctionOffsetLookupType", FunctionOffsetLookup.PreferSupportedVersions, "PreferSupportedVersions - using values for supported versions, if a version is not supported trying to use pdb." + Environment.NewLine + "PreferPdb - using pdb, it will be downloaded from  Unity symbols server,if there is no pdb or download failed trying to use values for supported versions." + Environment.NewLine + "Manual - using offsets from [Cache] section of the config, which you need to specify yourself as hex values.");

		internal static ConfigEntry<string> LastDownloadedGUID = _config.Bind<string>("Cache", "LastDownloadedGUID", "000000000000000000000000000000000", "The GUID of the last downloaded UnityPlayer pdb file." + Environment.NewLine + "If this GUID matches with the current one," + Environment.NewLine + "the offsets for the functions below will be used" + Environment.NewLine + "instead of generating them at runtime.");

		internal static ConfigEntry<string> MonoManagerAwakeFromLoadOffset = _config.Bind<string>("Cache", "MonoManagerAwakeFromLoadOffset", "00", "The in-memory offset of the MonoManager::AwakeFromLoad function.");

		internal static ConfigEntry<string> MonoManagerIsAssemblyCreatedOffset = _config.Bind<string>("Cache", "MonoManagerIsAssemblyCreatedOffset", "00", "The in-memory offset of the MonoManager::IsAssemblyCreated function.");

		internal static ConfigEntry<string> IsFileCreatedOffset = _config.Bind<string>("Cache", "IsFileCreatedOffset", "00", "The in-memory offset of the IsFileCreated function.");

		internal static ConfigEntry<string> ScriptingManagerDeconstructorOffset = _config.Bind<string>("Cache", "ScriptingManagerDeconstructorOffset", "00", "The in-memory offset of the ScriptingManagerDeconstructor function.");

		internal static ConfigEntry<string> ConvertSeparatorsToPlatformOffset = _config.Bind<string>("Cache", "ConvertSeparatorsToPlatformOffset", "00", "The in-memory offset of the ConvertSeparatorsToPlatform function.");

		internal static ConfigEntry<string> FreeAllocInternalOffset = _config.Bind<string>("Cache", "FreeAllocInternalOffset", "00", "The in-memory offset of the free_alloc_internal function.");

		internal static ConfigEntry<string> MallocInternalOffset = _config.Bind<string>("Cache", "MallocInternalOffset", "00", "The in-memory offset of the malloc_internal function.");

		internal static ConfigEntry<string> ScriptingAssembliesOffset = _config.Bind<string>("Cache", "ScriptingAssembliesOffset", "00", "The in-memory offset of the m_ScriptingAssemblies global field.");
	}
	internal static class FixPluginTypesSerializationPatcher
	{
		public static List<string> PluginPaths = (from f in Directory.GetFiles(Paths.PluginPath, "*.dll", SearchOption.AllDirectories)
			where IsNetAssembly(f)
			select f).ToList();

		public static List<string> PluginNames = PluginPaths.Select((string p) => Path.GetFileName(p)).ToList();

		public static IEnumerable<string> TargetDLLs { get; } = new string[0];


		public static bool IsNetAssembly(string fileName)
		{
			try
			{
				AssemblyName.GetAssemblyName(fileName);
			}
			catch (BadImageFormatException)
			{
				return false;
			}
			return true;
		}

		public static void Patch(AssemblyDefinition ass)
		{
		}

		public static void Initialize()
		{
			Log.Init();
			try
			{
				InitializeInternal();
			}
			catch (Exception ex)
			{
				Log.Error($"Failed to initialize plugin types serialization fix: ({ex.GetType()}) {ex.Message}. Some plugins may not work properly.");
				Log.Error(ex);
			}
		}

		private static void InitializeInternal()
		{
			DetourUnityPlayer();
		}

		private static void DetourUnityPlayer()
		{
			string text = Path.Combine(Paths.GameRootPath, "UnityPlayer.dll");
			if (!File.Exists(text))
			{
				text = Paths.ExecutablePath;
			}
			ProcessModule processModule = Process.GetCurrentProcess().Modules.Cast<ProcessModule>().FirstOrDefault(IsUnityPlayer) ?? Process.GetCurrentProcess().MainModule;
			PatternDiscoverer patternDiscoverer = new PatternDiscoverer(processModule.BaseAddress, text);
			CommonUnityFunctions.Init(patternDiscoverer);
			AwakeFromLoad awakeFromLoad = new AwakeFromLoad();
			IsAssemblyCreated isAssemblyCreated = new IsAssemblyCreated();
			IsFileCreated isFileCreated = new IsFileCreated();
			ScriptingManagerDeconstructor scriptingManagerDeconstructor = new ScriptingManagerDeconstructor();
			ConvertSeparatorsToPlatform convertSeparatorsToPlatform = new ConvertSeparatorsToPlatform();
			awakeFromLoad.Patch(patternDiscoverer, Config.MonoManagerAwakeFromLoadOffset);
			isAssemblyCreated.Patch(patternDiscoverer, Config.MonoManagerIsAssemblyCreatedOffset);
			if (!IsAssemblyCreated.IsApplied)
			{
				isFileCreated.Patch(patternDiscoverer, Config.IsFileCreatedOffset);
			}
			convertSeparatorsToPlatform.Patch(patternDiscoverer, Config.ConvertSeparatorsToPlatformOffset);
			scriptingManagerDeconstructor.Patch(patternDiscoverer, Config.ScriptingManagerDeconstructorOffset);
			static bool IsUnityPlayer(ProcessModule p)
			{
				return p.ModuleName.ToLowerInvariant().Contains("unityplayer");
			}
		}
	}
	internal static class Log
	{
		internal static ManualLogSource _logSource;

		internal static void Init()
		{
			_logSource = Logger.CreateLogSource("FixPluginTypesSerialization");
		}

		internal static void Debug(object data)
		{
			_logSource.LogDebug(data);
		}

		internal static void Error(object data)
		{
			_logSource.LogError(data);
		}

		internal static void Fatal(object data)
		{
			_logSource.LogFatal(data);
		}

		internal static void Info(object data)
		{
			_logSource.LogInfo(data);
		}

		internal static void Message(object data)
		{
			_logSource.LogMessage(data);
		}

		internal static void Warning(object data)
		{
			_logSource.LogWarning(data);
		}
	}
}
namespace FixPluginTypesSerialization.Util
{
	internal class BytePattern
	{
		private readonly byte?[] pattern;

		private int[] jumpTable;

		public int Length => pattern.Length;

		public bool IsE8 => ((int?)pattern[0]).GetValueOrDefault() == 232;

		public BytePattern(string bytes)
		{
			pattern = bytes.ParseHexBytes();
			CreateJumpTable();
		}

		public BytePattern(byte[] bytes)
		{
			pattern = bytes.Cast<byte?>().ToArray();
			CreateJumpTable();
		}

		public static implicit operator BytePattern(string pattern)
		{
			return new BytePattern(pattern);
		}

		public static implicit operator BytePattern(byte[] pattern)
		{
			return new BytePattern(pattern);
		}

		private void CreateJumpTable()
		{
			jumpTable = new int[pattern.Length];
			int num = 0;
			jumpTable[0] = -1;
			int num2 = 1;
			while (num2 < pattern.Length)
			{
				if (pattern[num2] == pattern[num])
				{
					jumpTable[num2] = jumpTable[num];
				}
				else
				{
					jumpTable[num2] = num;
					while (num >= 0 && pattern[num2] != pattern[num])
					{
						num = jumpTable[num];
					}
				}
				num2++;
				num++;
			}
		}

		public unsafe long Match(IntPtr start, long maxSize)
		{
			byte* ptr = (byte*)start.ToPointer();
			long num = 0L;
			long num2 = 0L;
			while (num < maxSize)
			{
				if (!pattern[num2].HasValue || ptr[num] == pattern[num2])
				{
					num++;
					num2++;
					if (num2 == pattern.Length)
					{
						return num - num2;
					}
				}
				else
				{
					num2 = jumpTable[num2];
					if (num2 < 0)
					{
						num++;
						num2++;
					}
				}
			}
			return 0L;
		}
	}
	internal class CommonUnityFunctions
	{
		public enum AllocateOptions
		{
			None,
			NullIfOutOfMemory
		}

		public struct MemLabelId
		{
			public int id;

			public nint rootref;
		}

		private unsafe delegate IntPtr MallocInternalFunc(ulong size, ulong align, MemLabelId* label, AllocateOptions allocateOptions, IntPtr file, int line);

		private delegate void FreeAllocInternalV1Func(IntPtr ptr, int label);

		private unsafe delegate void FreeAllocInternalV2Func(IntPtr ptr, MemLabelId* label, IntPtr file, int line);

		private static MallocInternalFunc mallocInternal;

		private static FreeAllocInternalV1Func freeAllocInternalV1;

		private static FreeAllocInternalV2Func freeAllocInternalV2;

		public static IntPtr ScriptingAssemblies { get; private set; }

		public static void Init(PatternDiscoverer patternDiscoverer)
		{
			IntPtr intPtr = patternDiscoverer.Discover(Config.MallocInternalOffset, new BytePattern[1] { Encoding.ASCII.GetBytes("malloc_internal") });
			if (intPtr != IntPtr.Zero)
			{
				mallocInternal = (MallocInternalFunc)Marshal.GetDelegateForFunctionPointer(intPtr, typeof(MallocInternalFunc));
			}
			IntPtr intPtr2 = patternDiscoverer.Discover(Config.FreeAllocInternalOffset, new BytePattern[1] { Encoding.ASCII.GetBytes("free_alloc_internal") });
			if (intPtr2 != IntPtr.Zero)
			{
				if (UseRightStructs.UnityVersion >= new Version(2019, 3))
				{
					freeAllocInternalV2 = (FreeAllocInternalV2Func)Marshal.GetDelegateForFunctionPointer(intPtr2, typeof(FreeAllocInternalV2Func));
				}
				else
				{
					freeAllocInternalV1 = (FreeAllocInternalV1Func)Marshal.GetDelegateForFunctionPointer(intPtr2, typeof(FreeAllocInternalV1Func));
				}
			}
			IntPtr intPtr3 = patternDiscoverer.Discover(Config.ScriptingAssembliesOffset, new BytePattern[1] { Encoding.ASCII.GetBytes("m_ScriptingAssemblies@") });
			if (intPtr3 != IntPtr.Zero)
			{
				ScriptingAssemblies = intPtr3;
			}
		}

		public unsafe static IntPtr MallocString(string str, int label, out ulong length)
		{
			IntPtr intPtr = Marshal.StringToHGlobalAnsi(str);
			length = (ulong)str.Length;
			byte* ptr = (byte*)(void*)intPtr + length;
			while (*ptr != 0)
			{
				ptr++;
				length++;
			}
			MemLabelId memLabelId = default(MemLabelId);
			memLabelId.id = label;
			memLabelId.rootref = IntPtr.Zero;
			MemLabelId memLabelId2 = memLabelId;
			IntPtr intPtr2 = mallocInternal(length + 1, 16uL, &memLabelId2, AllocateOptions.NullIfOutOfMemory, IntPtr.Zero, 0);
			for (ulong num = 0uL; num <= length; num++)
			{
				((byte*)(void*)intPtr2)[num] = ((byte*)(void*)intPtr)[num];
			}
			Marshal.FreeHGlobal(intPtr);
			return intPtr2;
		}

		public unsafe static void FreeAllocInternal(IntPtr ptr, int label)
		{
			MemLabelId memLabelId = default(MemLabelId);
			memLabelId.id = label;
			memLabelId.rootref = IntPtr.Zero;
			MemLabelId memLabelId2 = memLabelId;
			if (UseRightStructs.UnityVersion >= new Version(2019, 3))
			{
				freeAllocInternalV2(ptr, &memLabelId2, IntPtr.Zero, 0);
			}
			else
			{
				freeAllocInternalV1(ptr, label);
			}
		}
	}
	internal static class DictionaryExtensions
	{
		public static void Deconstruct<T1, T2>(this KeyValuePair<T1, T2> tuple, out T1 key, out T2 value)
		{
			key = tuple.Key;
			value = tuple.Value;
		}

		public static void Deconstruct(this VersionedHandler versionedHandler, out Version version, out object handler)
		{
			version = versionedHandler.version;
			handler = versionedHandler.handler;
		}
	}
	public enum FunctionOffsetLookup
	{
		PreferSupportedVersions,
		PreferPdb,
		Manual
	}
	public static class FunctionOffsets
	{
		public static bool TryGet(Version unityVersion, out Dictionary<string, long> offsets)
		{
			offsets = ((IntPtr.Size == 4) ? Get32(unityVersion) : Get64(unityVersion));
			return offsets != null;
		}

		private static Dictionary<string, long> Get32(Version unityVersion)
		{
			return null;
		}

		private static Dictionary<string, long> Get64(Version unityVersion)
		{
			if ((object)unityVersion != null && unityVersion.Major == 2022 && unityVersion.Minor == 3 && unityVersion.Build == 9)
			{
				return CreateOffsets(16538592L, 16555504L, 0L, 16644000L, 14526128L, 4997952L, 4997904L, 45844288L);
			}
			switch (unityVersion.Major)
			{
			case 5:
				switch (unityVersion.Minor)
				{
				case 0:
					switch (unityVersion.Build)
					{
					case 0:
						return CreateOffsets(1519584L, 0L, 2772736L, 1572448L, 2795760L, 11808L, 9536L, 0L);
					case 1:
						return CreateOffsets(1526224L, 0L, 2776448L, 1578976L, 2799424L, 11808L, 9536L, 0L);
					case 2:
						return CreateOffsets(1526512L, 0L, 2780208L, 1578704L, 2803280L, 11984L, 9712L, 0L);
					case 3:
						return CreateOffsets(1532016L, 0L, 2788720L, 1584288L, 2811408L, 11984L, 9712L, 0L);
					case 4:
						return CreateOffsets(1532352L, 0L, 2787216L, 1585264L, 2810400L, 11824L, 9552L, 0L);
					}
					break;
				case 1:
					switch (unityVersion.Build)
					{
					case 0:
						return CreateOffsets(1539536L, 0L, 2895136L, 1591456L, 2914064L, 11792L, 9520L, 0L);
					case 1:
						return CreateOffsets(1532352L, 0L, 2889568L, 1584848L, 2909008L, 11776L, 9504L, 0L);
					case 2:
						return CreateOffsets(1536608L, 0L, 2895968L, 1588528L, 2914816L, 11968L, 9696L, 0L);
					case 3:
						return CreateOffsets(1534064L, 0L, 2893280L, 1586352L, 2912464L, 11792L, 9520L, 0L);
					case 4:
						return CreateOffsets(1534560L, 0L, 2897920L, 1586960L, 2917712L, 11776L, 9504L, 0L);
					case 5:
						return CreateOffsets(1536544L, 0L, 2895200L, 1589008L, 2914736L, 11776L, 9504L, 0L);
					}
					break;
				case 2:
					switch (unityVersion.Build)
					{
					case 0:
						return CreateOffsets(1601024L, 0L, 2917232L, 1653200L, 2938816L, 11936L, 9664L, 0L);
					case 1:
						return CreateOffsets(1604832L, 0L, 2921792L, 1657232L, 2942912L, 11776L, 9504L, 0L);
					case 2:
						return CreateOffsets(1608448L, 0L, 2921632L, 1660080L, 2943344L, 11952L, 9680L, 0L);
					case 3:
						return CreateOffsets(1609760L, 0L, 2918432L, 1661824L, 2940192L, 11824L, 9552L, 0L);
					case 4:
						return CreateOffsets(1610208L, 0L, 2923312L, 1661584L, 2945072L, 11760L, 9488L, 0L);
					case 5:
						return CreateOffsets(1603040L, 0L, 2920608L, 1655584L, 2942368L, 11760L, 9488L, 0L);
					}
					break;
				case 3:
					switch (unityVersion.Build)
					{
					case 0:
						return CreateOffsets(2058016L, 0L, 3148928L, 2107216L, 3172256L, 1179552L, 1176448L, 0L);
					case 1:
						return CreateOffsets(2054016L, 0L, 3149200L, 2102688L, 3173328L, 1171392L, 1168288L, 0L);
					case 2:
						return CreateOffsets(2054240L, 0L, 3147872L, 2103040L, 3172048L, 1176608L, 1173504L, 0L);
					case 3:
						return CreateOffsets(2055600L, 0L, 3152432L, 2104288L, 3175856L, 1174752L, 1171648L, 0L);
					case 4:
						return CreateOffsets(1996128L, 0L, 3090368L, 2045792L, 3114800L, 1133136L, 1129424L, 0L);
					case 5:
						return CreateOffsets(2003360L, 0L, 3112208L, 2052592L, 3136096L, 1137840L, 1133504L, 0L);
					case 6:
						return CreateOffsets(2018064L, 0L, 3116768L, 2067408L, 3140608L, 1147680L, 1143344L, 0L);
					case 7:
						return CreateOffsets(2025424L, 0L, 3130592L, 2074400L, 3154544L, 1152864L, 1148528L, 0L);
					case 8:
						return CreateOffsets(2026160L, 0L, 3131296L, 2075056L, 3155232L, 1158080L, 1153744L, 0L);
					}
					break;
				case 4:
					switch (unityVersion.Build)
					{
					case 0:
						return CreateOffsets(2151120L, 0L, 3326704L, 2192800L, 3343888L, 1307984L, 1304112L, 0L);
					case 1:
						return CreateOffsets(2164448L, 0L, 3345952L, 2206416L, 3362960L, 1322688L, 1318816L, 0L);
					case 2:
						return CreateOffsets(2167920L, 0L, 3344976L, 2210608L, 3362080L, 1323072L, 1319200L, 0L);
					case 3:
						return CreateOffsets(2157424L, 0L, 3344160L, 2199552L, 3361968L, 1314432L, 1310560L, 0L);
					case 4:
						return CreateOffsets(2167120L, 0L, 3346880L, 2209696L, 3363392L, 1325200L, 1321328L, 0L);
					case 5:
						return CreateOffsets(2164688L, 0L, 3352400L, 2206656L, 3369104L, 1320624L, 1316752L, 0L);
					case 6:
						return CreateOffsets(2167600L, 0L, 3355312L, 2209344L, 3372816L, 1324048L, 1320176L, 0L);
					}
					break;
				case 5:
					switch (unityVersion.Build)
					{
					case 0:
						return CreateOffsets(3187616L, 0L, 2666208L, 3236944L, 2678768L, 80864L, 77712L, 0L);
					case 1:
						return CreateOffsets(3193200L, 0L, 2670816L, 3241920L, 2683376L, 81456L, 78288L, 0L);
					case 2:
						return CreateOffsets(3205712L, 0L, 2683728L, 3254592L, 2696288L, 81280L, 78112L, 0L);
					case 3:
						return CreateOffsets(3203472L, 0L, 2684544L, 3252048L, 2695808L, 81088L, 77920L, 0L);
					case 4:
						return CreateOffsets(3204368L, 0L, 2682752L, 3254256L, 2695376L, 81344L, 78176L, 0L);
					case 5:
						return CreateOffsets(3205552L, 0L, 2679536L, 3255328L, 2691840L, 80896L, 77728L, 0L);
					case 6:
						return CreateOffsets(3212144L, 0L, 2689424L, 3261824L, 2701120L, 81168L, 78000L, 0L);
					}
					break;
				case 6:
					switch (unityVersion.Build)
					{
					case 0:
						return CreateOffsets(8607808L, 0L, 7398368L, 6477584L, 7397984L, 8475808L, 8475984L, 0L);
					case 1:
						return CreateOffsets(8613168L, 0L, 7402064L, 6478288L, 7401680L, 8481280L, 8481456L, 0L);
					case 2:
						return CreateOffsets(8634192L, 0L, 7413264L, 6491008L, 7412880L, 8502496L, 8502672L, 0L);
					case 3:
						return CreateOffsets(8641584L, 0L, 7421536L, 6501520L, 7421152L, 8508976L, 8509152L, 0L);
					case 4:
						return CreateOffsets(8645968L, 0L, 7425024L, 6502240L, 7424640L, 8515008L, 8515184L, 0L);
					case 5:
						return CreateOffsets(8650080L, 0L, 7426080L, 6502768L, 7425696L, 8517088L, 8517264L, 0L);
					case 6:
						return CreateOffsets(8644208L, 0L, 7420704L, 6497312L, 7420320L, 8511584L, 8511760L, 0L);
					case 7:
						return CreateOffsets(8644208L, 0L, 7420704L, 6497312L, 7420320L, 8511584L, 8511760L, 0L);
					}
					break;
				}
				break;
			case 2017:
				switch (unityVersion.Minor)
				{
				case 1:
					switch (unityVersion.Build)
					{
					case 0:
						return CreateOffsets(5689904L, 0L, 8344128L, 7269760L, 8357424L, 9310656L, 9306960L, 0L);
					case 1:
						return CreateOffsets(5693664L, 0L, 8350688L, 7274656L, 8364608L, 9318256L, 9314560L, 0L);
					case 2:
						return CreateOffsets(5698352L, 0L, 8350896L, 7277376L, 8364816L, 9322400L, 9318704L, 0L);
					case 3:
						return CreateOffsets(5703968L, 0L, 8363488L, 7285696L, 8377360L, 9338048L, 9334352L, 0L);
					case 4:
						return CreateOffsets(5713616L, 0L, 8372080L, 7296256L, 8385872L, 9345600L, 9341904L, 0L);
					case 5:
						return CreateOffsets(5710224L, 0L, 8372640L, 7292560L, 8386560L, 9345104L, 9341408L, 0L);
					}
					break;
				case 2:
					switch (unityVersion.Build)
					{
					case 0:
						return CreateOffsets(4525712L, 0L, 3978000L, 4598144L, 3993984L, 1163072L, 1159376L, 0L);
					case 1:
						return CreateOffsets(4527072L, 0L, 3981312L, 4599904L, 3997552L, 1159344L, 1155648L, 0L);
					case 2:
						return CreateOffsets(4527520L, 0L, 3979856L, 4600704L, 3995840L, 1161024L, 1157328L, 0L);
					case 3:
						return CreateOffsets(4535296L, 0L, 3987264L, 4608480L, 4003456L, 1160272L, 1156576L, 0L);
					case 4:
						return CreateOffsets(4531840L, 0L, 3980800L, 4605552L, 3997264L, 1161952L, 1158256L, 0L);
					case 5:
						return CreateOffsets(4531568L, 0L, 3989296L, 4604384L, 4005408L, 1159136L, 1155440L, 0L);
					}
					break;
				case 3:
					switch (unityVersion.Build)
					{
					case 0:
						return CreateOffsets(6098128L, 6114480L, 0L, 6201264L, 5566256L, 2970112L, 2969968L, 0L);
					case 1:
						return CreateOffsets(6092560L, 6108592L, 0L, 6195360L, 5561584L, 2968608L, 2968464L, 0L);
					}
					break;
				case 4:
					switch (unityVersion.Build)
					{
					case 0:
						return CreateOffsets(6099152L, 6115168L, 0L, 6200912L, 5570992L, 2962832L, 2962688L, 0L);
					case 1:
						return CreateOffsets(6090224L, 6106352L, 0L, 6192160L, 5563088L, 2966992L, 2966848L, 0L);
					case 2:
						return CreateOffsets(6089152L, 6105184L, 0L, 6191344L, 5558704L, 2966256L, 2966112L, 0L);
					case 3:
						return CreateOffsets(6098288L, 6114416L, 0L, 6200832L, 5569856L, 2976272L, 2976128L, 0L);
					case 4:
						return CreateOffsets(6093440L, 6109568L, 0L, 6195728L, 5562016L, 2968944L, 2968800L, 0L);
					case 5:
						return CreateOffsets(6105040L, 6121072L, 0L, 6207424L, 5575792L, 2969376L, 2969232L, 0L);
					case 6:
						return CreateOffsets(6088256L, 6104304L, 0L, 6190176L, 5555632L, 2970272L, 2970128L, 0L);
					case 7:
						return CreateOffsets(6102032L, 6118064L, 0L, 6203936L, 5573216L, 2967184L, 2967040L, 0L);
					case 8:
						return CreateOffsets(6105072L, 6121200L, 0L, 6207488L, 5576496L, 2979936L, 2979792L, 0L);
					case 9:
						return CreateOffsets(6099504L, 6115632L, 0L, 6202080L, 5567344L, 2969632L, 2969488L, 0L);
					case 10:
						return CreateOffsets(6109760L, 6125808L, 0L, 6212096L, 5574160L, 2970560L, 2970416L, 0L);
					case 11:
						return CreateOffsets(6109840L, 6125872L, 0L, 6211920L, 5575440L, 2968192L, 2968048L, 0L);
					case 12:
						return CreateOffsets(6119152L, 6135168L, 0L, 6221536L, 5589472L, 2973952L, 2973808L, 0L);
					case 13:
						return CreateOffsets(6114544L, 6130672L, 0L, 6217040L, 5579888L, 2980080L, 2979936L, 0L);
					case 14:
						return CreateOffsets(6117312L, 6133440L, 0L, 6220256L, 5580752L, 2985280L, 2985136L, 0L);
					case 15:
						return CreateOffsets(6117904L, 6133936L, 0L, 6221280L, 5581568L, 2981136L, 2980992L, 0L);
					case 16:
						return CreateOffsets(6118368L, 6134400L, 0L, 6221312L, 5587808L, 2969936L, 2969792L, 0L);
					case 17:
						return CreateOffsets(6121104L, 6137136L, 0L, 6224032L, 5590048L, 2973232L, 2973088L, 0L);
					case 18:
						return CreateOffsets(6123024L, 6139152L, 0L, 6226080L, 5591712L, 2970976L, 2970832L, 0L);
					case 19:
						return CreateOffsets(6121200L, 6137216L, 0L, 6223728L, 5585680L, 2974192L, 2974048L, 0L);
					case 20:
						return CreateOffsets(6116240L, 6132272L, 0L, 6219808L, 5580752L, 2969056L, 2968912L, 0L);
					case 21:
						return CreateOffsets(6122640L, 6138688L, 0L, 6225712L, 5589936L, 2980784L, 2980640L, 0L);
					case 22:
						return CreateOffsets(6122640L, 6138688L, 0L, 6225712L, 5589936L, 2980784L, 2980640L, 0L);
					case 23:
						return CreateOffsets(6123424L, 6139456L, 0L, 6226704L, 5591328L, 2969376L, 2969232L, 0L);
					case 24:
						return CreateOffsets(6116784L, 6132800L, 0L, 6219984L, 5585888L, 2982864L, 2982720L, 0L);
					case 25:
						return CreateOffsets(6116208L, 6132432L, 0L, 6219616L, 5582304L, 2982720L, 2982576L, 0L);
					case 26:
						return CreateOffsets(6120352L, 6136576L, 0L, 6223792L, 5586720L, 2970096L, 2969952L, 0L);
					case 27:
						return CreateOffsets(6124624L, 6140848L, 0L, 6228048L, 5592176L, 2980256L, 2980112L, 0L);
					case 28:
						return CreateOffsets(6107520L, 6123856L, 0L, 6211152L, 5571904L, 2974000L, 2973856L, 0L);
					case 29:
						return CreateOffsets(6107520L, 6123856L, 0L, 6211152L, 5571904L, 2974000L, 2973856L, 0L);
					case 30:
						return CreateOffsets(6125328L, 6141680L, 0L, 6228896L, 5586656L, 2982912L, 2982768L, 0L);
					case 31:
						return CreateOffsets(6120704L, 6136944L, 0L, 6223984L, 5587728L, 2976064L, 2975920L, 0L);
					case 32:
						return CreateOffsets(6108816L, 6125056L, 0L, 6212208L, 5573056L, 2968016L, 2967872L, 0L);
					case 33:
						return CreateOffsets(6122272L, 6138624L, 0L, 6225696L, 5585472L, 2984416L, 2984272L, 0L);
					case 34:
						return CreateOffsets(6122512L, 6138848L, 0L, 6226176L, 5586752L, 2983696L, 2983552L, 0L);
					case 35:
						return CreateOffsets(6122752L, 6138976L, 0L, 6225952L, 5590960L, 2972096L, 2971952L, 0L);
					case 36:
						return CreateOffsets(6126272L, 6142496L, 0L, 6229648L, 5592816L, 2986848L, 2986704L, 0L);
					case 37:
						return CreateOffsets(6121616L, 6137856L, 0L, 6225232L, 5585360L, 2971200L, 2971056L, 0L);
					case 38:
						return CreateOffsets(6121424L, 6137664L, 0L, 6225056L, 5587040L, 2978944L, 2978800L, 0L);
					case 39:
						return CreateOffsets(6122736L, 6138976L, 0L, 6226288L, 5591712L, 2985440L, 2985296L, 0L);
					case 40:
						return CreateOffsets(6117872L, 6134096L, 0L, 6221616L, 5582608L, 2982928L, 2982784L, 0L);
					}
					break;
				}
				break;
			case 2018:
				switch (unityVersion.Minor)
				{
				case 1:
					switch (unityVersion.Build)
					{
					case 0:
						return CreateOffsets(5841104L, 5860640L, 0L, 5923328L, 5335888L, 2849008L, 2848960L, 0L);
					case 1:
						return CreateOffsets(5834512L, 5854048L, 0L, 5916592L, 5330832L, 2848048L, 2837376L, 0L);
					case 2:
						return CreateOffsets(5839264L, 5858800L, 0L, 5921712L, 5335696L, 2850784L, 2840256L, 0L);
					case 3:
						return CreateOffsets(5835600L, 5855136L, 0L, 5918256L, 5331712L, 2847920L, 2847872L, 0L);
					case 4:
						return CreateOffsets(5841024L, 5860560L, 0L, 5923008L, 5335648L, 2846960L, 2846912L, 0L);
					case 5:
						return CreateOffsets(5839920L, 5859456L, 0L, 5922656L, 5333936L, 2848240L, 2837568L, 0L);
					case 6:
						return CreateOffsets(5839104L, 5858640L, 0L, 5921408L, 5334368L, 2848368L, 2837744L, 0L);
					case 7:
						return CreateOffsets(5839888L, 5859424L, 0L, 5922480L, 5336160L, 2853216L, 2842784L, 0L);
					case 8:
						return CreateOffsets(5840960L, 5860512L, 0L, 5923280L, 5334480L, 2845504L, 2845456L, 0L);
					case 9:
						return CreateOffsets(5838832L, 5858368L, 0L, 5921024L, 5336560L, 2851392L, 2840816L, 0L);
					}
					break;
				case 2:
					switch (unityVersion.Build)
					{
					case 0:
						return CreateOffsets(6134752L, 6152240L, 0L, 6214400L, 5567824L, 3004448L, 3004400L, 0L);
					case 1:
						return CreateOffsets(6136480L, 6154000L, 0L, 6216368L, 5573280L, 3004016L, 3003968L, 0L);
					case 2:
						return CreateOffsets(6136784L, 6154272L, 0L, 6216768L, 5572768L, 3003648L, 3003600L, 0L);
					case 3:
						return CreateOffsets(6134160L, 6151664L, 0L, 6214032L, 5569712L, 3005856L, 2995456L, 0L);
					case 4:
						return CreateOffsets(6137600L, 6155104L, 0L, 6217568L, 5573328L, 3000704L, 2990400L, 0L);
					case 5:
						return CreateOffsets(6135904L, 6153408L, 0L, 6217008L, 5572336L, 3002448L, 3002400L, 0L);
					case 6:
						return CreateOffsets(6140624L, 6158128L, 0L, 6220336L, 5576304L, 3005888L, 3005840L, 0L);
					case 7:
						return CreateOffsets(6141280L, 6158768L, 0L, 6221712L, 5574560L, 3007168L, 3007120L, 0L);
					case 8:
						return CreateOffsets(6141072L, 6158560L, 0L, 6220944L, 5574192L, 3006624L, 3006576L, 0L);
					case 9:
						return CreateOffsets(6142976L, 6160496L, 0L, 6223184L, 5577760L, 3006608L, 2996400L, 0L);
					case 10:
						return CreateOffsets(6144720L, 6162240L, 0L, 6224928L, 5580864L, 3006832L, 2996528L, 0L);
					case 11:
						return CreateOffsets(6140448L, 6157936L, 0L, 6220560L, 5574288L, 3005024L, 3004976L, 0L);
					case 12:
						return CreateOffsets(6144960L, 6162448L, 0L, 6224608L, 5578288L, 3007536L, 2997088L, 0L);
					case 13:
						return CreateOffsets(6144784L, 6162288L, 0L, 6224528L, 5579264L, 3007344L, 2997040L, 0L);
					case 14:
						return CreateOffsets(6148432L, 6165920L, 0L, 6228176L, 5582640L, 3008544L, 2998192L, 0L);
					case 15:
						return CreateOffsets(6146896L, 6164416L, 0L, 6226704L, 5582336L, 3008848L, 3008800L, 0L);
					case 16:
						return CreateOffsets(6147104L, 6164624L, 0L, 6226800L, 5585456L, 3009728L, 3009680L, 0L);
					case 17:
						return CreateOffsets(6147104L, 6164624L, 0L, 6226800L, 5585456L, 3009728L, 3009680L, 0L);
					case 18:
						return CreateOffsets(6141616L, 6159120L, 0L, 6221296L, 5578512L, 3007008L, 3006960L, 0L);
					case 19:
						return CreateOffsets(6145424L, 6162928L, 0L, 6225184L, 5580576L, 3008768L, 3008720L, 0L);
					case 20:
						return CreateOffsets(6147296L, 6164800L, 0L, 6227184L, 5583056L, 3007440L, 2997184L, 0L);
					case 21:
						return CreateOffsets(6147296L, 6164800L, 0L, 6227184L, 5583056L, 3007440L, 2997184L, 0L);
					}
					break;
				case 3:
					switch (unityVersion.Build)
					{
					case 0:
						return CreateOffsets(9297584L, 9308880L, 0L, 9330880L, 8839872L, 6427856L, 6427808L, 0L);
					case 1:
						return CreateOffsets(9298944L, 9310240L, 0L, 9332240L, 8841232L, 6428736L, 6428688L, 0L);
					case 2:
						return CreateOffsets(9298880L, 9310176L, 0L, 9332176L, 8841168L, 6428720L, 6428672L, 0L);
					case 3:
						return CreateOffsets(9300864L, 9312160L, 0L, 9334160L, 8843152L, 6430848L, 6430800L, 0L);
					case 4:
						return CreateOffsets(9301808L, 9313104L, 0L, 9335104L, 8844096L, 6431776L, 6431728L, 0L);
					case 5:
						return CreateOffsets(9303232L, 9314528L, 0L, 9336528L, 8845360L, 6432080L, 6432032L, 0L);
					case 6:
						return CreateOffsets(9310592L, 9321872L, 0L, 9343872L, 8852688L, 6439856L, 6439808L, 0L);
					case 7:
						return CreateOffsets(9313440L, 9324720L, 0L, 9346720L, 8855536L, 6441168L, 6441120L, 0L);
					case 8:
						return CreateOffsets(9316512L, 9327792L, 0L, 9349792L, 8842976L, 6443808L, 6443760L, 0L);
					case 9:
						return CreateOffsets(9316768L, 9328048L, 0L, 9350048L, 8843232L, 6444048L, 6444000L, 0L);
					case 10:
						return CreateOffsets(9318192L, 9329472L, 0L, 9351472L, 8844400L, 6444848L, 6444800L, 0L);
					case 11:
						return CreateOffsets(9318256L, 9329536L, 0L, 9351536L, 8844464L, 6444784L, 6444736L, 0L);
					case 12:
						return CreateOffsets(9318160L, 9329440L, 0L, 9351440L, 8844336L, 6446272L, 6446224L, 0L);
					case 13:
						return CreateOffsets(9319200L, 9330480L, 0L, 9352480L, 8845168L, 6447104L, 6447056L, 0L);
					case 14:
						return CreateOffsets(9317152L, 9328432L, 0L, 9350432L, 8843168L, 6447504L, 6447456L, 0L);
					}
					break;
				case 4:
					switch (unityVersion.Build)
					{
					case 1:
						return CreateOffsets(9318256L, 9329536L, 0L, 9351536L, 8844272L, 6448576L, 6448528L, 0L);
					case 2:
						return CreateOffsets(9320864L, 9332144L, 0L, 9354144L, 8846880L, 6450800L, 6450752L, 0L);
					case 3:
						return CreateOffsets(9320768L, 9332048L, 0L, 9354048L, 8846784L, 6450560L, 6450512L, 0L);
					case 4:
						return CreateOffsets(9320640L, 9331920L, 0L, 9353920L, 8846640L, 6450688L, 6450640L, 0L);
					case 5:
						return CreateOffsets(9321040L, 9332320L, 0L, 9354320L, 8847008L, 6451552L, 6451504L, 0L);
					case 6:
						return CreateOffsets(9321952L, 9333232L, 0L, 9355232L, 8847920L, 6451568L, 6451520L, 0L);
					case 7:
						return CreateOffsets(9321952L, 9333232L, 0L, 9355232L, 8847920L, 6451568L, 6451520L, 0L);
					case 8:
						return CreateOffsets(9320432L, 9331712L, 0L, 9353712L, 8846352L, 6449696L, 6449648L, 0L);
					case 9:
						return CreateOffsets(9326096L, 9337376L, 0L, 9359376L, 8851888L, 6453808L, 6453760L, 0L);
					case 10:
						return CreateOffsets(9336368L, 9347648L, 0L, 9369648L, 8862128L, 6460048L, 6460000L, 0L);
					case 11:
						return CreateOffsets(9336816L, 9348096L, 0L, 9370096L, 8862576L, 6460544L, 6460496L, 0L);
					case 12:
						return CreateOffsets(9337168L, 9348448L, 0L, 9370448L, 8862928L, 6460896L, 6460848L, 0L);
					case 13:
						return CreateOffsets(9339296L, 9350576L, 0L, 9372576L, 8864832L, 6460512L, 6460464L, 0L);
					case 14:
						return CreateOffsets(9343008L, 9354288L, 0L, 9376048L, 8868544L, 6462976L, 6462928L, 0L);
					case 15:
						return CreateOffsets(9346320L, 9357600L, 0L, 9379360L, 8871840L, 6465216L, 6465168L, 0L);
					case 16:
						return CreateOffsets(9348000L, 9359280L, 0L, 9381040L, 8873504L, 6466592L, 6466544L, 0L);
					case 17:
						return CreateOffsets(9349424L, 9360704L, 0L, 9382464L, 8874928L, 6467872L, 6467824L, 0L);
					case 18:
						return CreateOffsets(9351392L, 9362672L, 0L, 9384432L, 8875168L, 6468128L, 6468080L, 0L);
					case 19:
						return CreateOffsets(9353920L, 9365200L, 0L, 9386960L, 8877696L, 6468832L, 6468784L, 0L);
					case 20:
						return CreateOffsets(9354640L, 9365920L, 0L, 9387680L, 8878352L, 6469520L, 6469472L, 0L);
					case 21:
						return CreateOffsets(9354608L, 9365888L, 0L, 9387648L, 8878288L, 6469488L, 6469440L, 0L);
					case 22:
						return CreateOffsets(9355392L, 9366672L, 0L, 9388432L, 8879072L, 6469920L, 6469872L, 0L);
					case 23:
						return CreateOffsets(9349008L, 9360288L, 0L, 9382048L, 8872688L, 6469296L, 6469248L, 0L);
					case 24:
						return CreateOffsets(9354976L, 9366256L, 0L, 9388016L, 8878656L, 6474432L, 6474384L, 0L);
					case 25:
						return CreateOffsets(9358448L, 9369728L, 0L, 9391488L, 8882128L, 6477616L, 6477568L, 0L);
					case 26:
						return CreateOffsets(9360176L, 9371456L, 0L, 9393216L, 8883840L, 6478464L, 6478416L, 0L);
					case 27:
						return CreateOffsets(9362704L, 9373984L, 0L, 9395744L, 8885872L, 6478688L, 6478640L, 0L);
					case 28:
						return CreateOffsets(9361728L, 9373008L, 0L, 9394768L, 8884896L, 6477680L, 6477632L, 0L);
					case 29:
						return CreateOffsets(9363568L, 9374848L, 0L, 9396608L, 8886736L, 6478832L, 6478784L, 0L);
					case 30:
						return CreateOffsets(9365728L, 9377008L, 0L, 9398816L, 8888896L, 6479888L, 6479840L, 0L);
					case 31:
						return CreateOffsets(9365968L, 9377248L, 0L, 9399056L, 8889136L, 6479904L, 6479856L, 0L);
					case 32:
						return CreateOffsets(9366304L, 9377584L, 0L, 9399392L, 8889472L, 6480000L, 6479952L, 0L);
					case 33:
						return CreateOffsets(9366320L, 9377600L, 0L, 9399408L, 8889488L, 6480000L, 6479952L, 0L);
					case 34:
						return CreateOffsets(9369360L, 9380640L, 0L, 9402448L, 8892528L, 6480000L, 6479952L, 0L);
					case 35:
						return CreateOffsets(9369712L, 9380992L, 0L, 9402800L, 8892880L, 6480352L, 6480304L, 0L);
					case 36:
						return CreateOffsets(9370320L, 9381600L, 0L, 9403408L, 8893280L, 6480688L, 6480640L, 0L);
					}
					break;
				}
				break;
			case 2019:
				switch (unityVersion.Minor)
				{
				case 1:
					switch (unityVersion.Build)
					{
					case 0:
						return CreateOffsets(9142272L, 9166192L, 0L, 9200784L, 8543344L, 6065712L, 6065664L, 0L);
					case 1:
						return CreateOffsets(9143856L, 9167776L, 0L, 9202368L, 8544928L, 6067216L, 6067168L, 0L);
					case 2:
						return CreateOffsets(9145552L, 9169472L, 0L, 9204064L, 8546624L, 6067984L, 6067936L, 0L);
					case 3:
						return CreateOffsets(9146416L, 9170336L, 0L, 9204928L, 8529248L, 6068992L, 6068944L, 0L);
					case 4:
						return CreateOffsets(9138256L, 9162176L, 0L, 9196768L, 8521088L, 6060064L, 6060016L, 0L);
					case 5:
						return CreateOffsets(9138256L, 9162176L, 0L, 9196768L, 8521088L, 6060064L, 6060016L, 0L);
					case 6:
						return CreateOffsets(9137808L, 9161728L, 0L, 9196320L, 8520512L, 6058848L, 6058800L, 0L);
					case 7:
						return CreateOffsets(9138304L, 9162224L, 0L, 9196816L, 8521008L, 6059136L, 6059088L, 0L);
					case 8:
						return CreateOffsets(9138224L, 9162144L, 0L, 9196736L, 8520928L, 6058912L, 6058864L, 0L);
					case 9:
						return CreateOffsets(9139280L, 9163200L, 0L, 9197792L, 8521984L, 6059792L, 6059744L, 0L);
					case 10:
						return CreateOffsets(9138688L, 9162624L, 0L, 9197216L, 8521392L, 6059968L, 6059920L, 0L);
					case 11:
						return CreateOffsets(9138720L, 9162656L, 0L, 9197248L, 8521424L, 6059968L, 6059920L, 0L);
					case 12:
						return CreateOffsets(9138720L, 9162656L, 0L, 9197248L, 8521424L, 6059968L, 6059920L, 0L);
					case 13:
						return CreateOffsets(9139200L, 9163136L, 0L, 9197728L, 8521904L, 6059776L, 6059728L, 0L);
					case 14:
						return CreateOffsets(9140224L, 9164160L, 0L, 9198880L, 8522928L, 6060784L, 6060736L, 0L);
					}
					break;
				case 2:
					switch (unityVersion.Build)
					{
					case 0:
						return CreateOffsets(8830144L, 8854096L, 0L, 8888896L, 8195296L, 5738272L, 5738224L, 0L);
					case 1:
						return CreateOffsets(8830880L, 8854832L, 0L, 8889632L, 8196048L, 5738352L, 5738304L, 0L);
					case 2:
						return CreateOffsets(8832304L, 8856256L, 0L, 8891056L, 8197472L, 5738448L, 5738400L, 0L);
					case 3:
						return CreateOffsets(8833472L, 8857424L, 0L, 8892224L, 8198640L, 5739584L, 5739536L, 0L);
					case 4:
						return CreateOffsets(8836032L, 8859984L, 0L, 8894784L, 8201200L, 5741568L, 5741520L, 0L);
					case 5:
						return CreateOffsets(8836160L, 8860112L, 0L, 8894912L, 8201264L, 5740976L, 5740928L, 0L);
					case 6:
						return CreateOffsets(8835888L, 8859840L, 0L, 8894640L, 8200992L, 5740496L, 5740448L, 0L);
					case 7:
						return CreateOffsets(8837152L, 8861104L, 0L, 8895664L, 8202256L, 5740416L, 5740368L, 0L);
					case 8:
						return CreateOffsets(8837488L, 8861456L, 0L, 8896016L, 8202512L, 5740656L, 5740608L, 0L);
					case 9:
						return CreateOffsets(8838368L, 8862336L, 0L, 8896896L, 8203392L, 5741088L, 5741040L, 0L);
					case 10:
						return CreateOffsets(8839008L, 8862976L, 0L, 8897536L, 8203888L, 5741600L, 5741552L, 0L);
					case 11:
						return CreateOffsets(8839552L, 8863520L, 0L, 8898080L, 8204432L, 5742048L, 5742000L, 0L);
					case 12:
						return CreateOffsets(8839696L, 8863664L, 0L, 8898224L, 8204576L, 5742080L, 5742032L, 0L);
					case 13:
						return CreateOffsets(8840752L, 8864720L, 0L, 8899280L, 8205632L, 5742160L, 5742112L, 0L);
					case 14:
						return CreateOffsets(8842256L, 8866224L, 0L, 8900784L, 8207120L, 5742704L, 5742656L, 0L);
					case 15:
						return CreateOffsets(8842736L, 8866704L, 0L, 8901264L, 8207600L, 5743184L, 5743136L, 0L);
					case 16:
						return CreateOffsets(8843440L, 8867408L, 0L, 8901968L, 8208272L, 5743728L, 5743680L, 0L);
					case 17:
						return CreateOffsets(8845744L, 8869712L, 0L, 8904272L, 8210576L, 5745920L, 5745872L, 0L);
					case 18:
						return CreateOffsets(8845136L, 8869104L, 0L, 8903664L, 8209968L, 5744992L, 5744944L, 0L);
					case 19:
						return CreateOffsets(8840176L, 8864144L, 0L, 8898704L, 8205008L, 5740032L, 5739984L, 0L);
					case 20:
						return CreateOffsets(8840400L, 8864368L, 0L, 8898928L, 8205200L, 5740224L, 5740176L, 0L);
					case 21:
						return CreateOffsets(8840400L, 8864368L, 0L, 8898928L, 8205200L, 5740224L, 5740176L, 0L);
					}
					break;
				case 3:
					switch (unityVersion.Build)
					{
					case 0:
						return CreateOffsets(9002592L, 9014576L, 0L, 9035568L, 8329232L, 5734800L, 5734704L, 0L);
					case 1:
						return CreateOffsets(9004928L, 9016912L, 0L, 9037904L, 8331648L, 5735296L, 5735200L, 0L);
					case 2:
						return CreateOffsets(9006448L, 9018432L, 0L, 9039424L, 8333168L, 5738096L, 5738000L, 0L);
					case 3:
						return CreateOffsets(9006592L, 9018576L, 0L, 9039568L, 8333312L, 5738112L, 5738016L, 0L);
					case 4:
						return CreateOffsets(9012320L, 9024304L, 0L, 9045296L, 8339040L, 5740016L, 5739920L, 0L);
					case 5:
						return CreateOffsets(9014880L, 9026864L, 0L, 9047856L, 8341600L, 5741152L, 5741056L, 0L);
					case 6:
						return CreateOffsets(9021328L, 9033312L, 0L, 9054368L, 8347568L, 5745680L, 5745584L, 0L);
					case 7:
						return CreateOffsets(9024528L, 9036512L, 0L, 9057568L, 8350736L, 5747968L, 5747872L, 0L);
					case 8:
						return CreateOffsets(9033456L, 9045440L, 0L, 9066496L, 8359664L, 5748608L, 5748512L, 0L);
					case 9:
						return CreateOffsets(9034000L, 9045984L, 0L, 9067040L, 8360208L, 5747904L, 5747808L, 0L);
					case 10:
						return CreateOffsets(9034928L, 9046912L, 0L, 9067968L, 8360784L, 5748128L, 5748032L, 0L);
					case 11:
						return CreateOffsets(9041712L, 9053696L, 0L, 9074752L, 8367376L, 5753664L, 5753568L, 0L);
					case 12:
						return CreateOffsets(9042576L, 9054560L, 0L, 9075616L, 8367808L, 5754080L, 5753984L, 0L);
					case 13:
						return CreateOffsets(9043520L, 9055504L, 0L, 9076560L, 8368720L, 5754912L, 5754816L, 0L);
					case 14:
						return CreateOffsets(9045920L, 9057904L, 0L, 9078960L, 8371104L, 5757152L, 5757056L, 0L);
					case 15:
						return CreateOffsets(9057024L, 9069008L, 0L, 9090064L, 8382144L, 5765296L, 5765200L, 0L);
					}
					break;
				case 4:
					switch (unityVersion.Build)
					{
					case 0:
						return CreateOffsets(9058752L, 9070736L, 0L, 9091792L, 8383872L, 5765664L, 5765568L, 0L);
					case 1:
						return CreateOffsets(9058816L, 9070768L, 0L, 9091856L, 8383936L, 5765664L, 5765568L, 0L);
					case 2:
						return CreateOffsets(9060704L, 9072656L, 0L, 9093744L, 8385824L, 5766816L, 5766720L, 0L);
					case 3:
						return CreateOffsets(9067440L, 9079392L, 0L, 9100480L, 8392560L, 5771232L, 5771136L, 0L);
					case 4:
						return CreateOffsets(9067552L, 9079504L, 0L, 9100592L, 8392672L, 5771232L, 5771136L, 0L);
					case 5:
						return CreateOffsets(9068288L, 9080240L, 0L, 9101328L, 8393392L, 5771584L, 5771488L, 0L);
					case 6:
						return CreateOffsets(9069664L, 9081616L, 0L, 9102704L, 8394752L, 5772672L, 5772576L, 0L);
					case 7:
						return CreateOffsets(9073056L, 9085008L, 0L, 9106096L, 8398112L, 5775648L, 5775552L, 0L);
					case 8:
						return CreateOffsets(9073008L, 9084960L, 0L, 9106048L, 8398064L, 5775184L, 5775088L, 0L);
					case 9:
						return CreateOffsets(9081712L, 9093664L, 0L, 9114752L, 8406224L, 5776832L, 5776736L, 0L);
					case 10:
						return CreateOffsets(9087568L, 9099520L, 0L, 9120608L, 8412080L, 5782096L, 5782000L, 0L);
					case 11:
						return CreateOffsets(9089136L, 9101088L, 0L, 9122176L, 8413760L, 5782416L, 5782320L, 0L);
					case 12:
						return CreateOffsets(9091056L, 9103008L, 0L, 9124096L, 8415344L, 5785168L, 5785072L, 0L);
					case 13:
						return CreateOffsets(9091792L, 9103744L, 0L, 9124832L, 8416080L, 5785440L, 5785344L, 0L);
					case 14:
						return CreateOffsets(9092352L, 9104304L, 0L, 9125392L, 8416640L, 5785776L, 5785680L, 0L);
					case 15:
						return CreateOffsets(9092848L, 9104800L, 0L, 9125888L, 8416976L, 5786064L, 5785968L, 0L);
					case 16:
						return CreateOffsets(9098160L, 9110112L, 0L, 9131232L, 8422144L, 5789232L, 5789136L, 0L);
					case 17:
						return CreateOffsets(9101728L, 9113680L, 0L, 9134800L, 8425008L, 5791824L, 5791728L, 0L);
					case 18:
						return CreateOffsets(9107216L, 9119168L, 0L, 9140288L, 8430512L, 5795952L, 5795856L, 0L);
					case 19:
						return CreateOffsets(9110464L, 9122416L, 0L, 9143536L, 8433616L, 5796864L, 5796768L, 0L);
					case 20:
						return CreateOffsets(9115296L, 9127248L, 0L, 9148368L, 8437840L, 5800832L, 5800736L, 0L);
					case 21:
						return CreateOffsets(9110672L, 9122688L, 0L, 9143808L, 8433184L, 5795968L, 5795872L, 0L);
					case 22:
						return CreateOffsets(9115872L, 9127888L, 0L, 9149008L, 8438336L, 5798352L, 5798256L, 0L);
					case 23:
						return CreateOffsets(9138784L, 9150800L, 0L, 9170672L, 8459856L, 5818064L, 5817968L, 0L);
					case 24:
						return CreateOffsets(9144336L, 9156320L, 0L, 9176112L, 8465104L, 5825632L, 5825536L, 0L);
					case 25:
						return CreateOffsets(9144416L, 9156400L, 0L, 9176192L, 8465248L, 5825712L, 5825616L, 0L);
					case 26:
						return CreateOffsets(9146160L, 9158144L, 0L, 9177936L, 8466288L, 5825760L, 5825664L, 0L);
					case 27:
						return CreateOffsets(9148608L, 9160592L, 0L, 9180272L, 8468752L, 5827792L, 5827696L, 0L);
					case 28:
						return CreateOffsets(9149168L, 9161152L, 0L, 9180832L, 8469280L, 5827984L, 5827888L, 0L);
					case 29:
						return CreateOffsets(9154368L, 9166368L, 0L, 9186048L, 8474480L, 5829488L, 5829392L, 0L);
					case 30:
						return CreateOffsets(9158224L, 9170224L, 0L, 9189904L, 8478336L, 5832976L, 5832880L, 0L);
					case 31:
						return CreateOffsets(9169952L, 9181936L, 0L, 9201616L, 8490064L, 5841152L, 5841056L, 0L);
					case 32:
						return CreateOffsets(9171328L, 9183312L, 0L, 9202992L, 8490320L, 5841600L, 5841504L, 0L);
					case 33:
						return CreateOffsets(9174592L, 9186576L, 0L, 9206256L, 8493584L, 5842464L, 5842368L, 0L);
					case 34:
						return CreateOffsets(9174576L, 9186560L, 0L, 9206240L, 8493568L, 5842416L, 5842320L, 0L);
					case 35:
						return CreateOffsets(9177728L, 9189712L, 0L, 9209392L, 8496720L, 5845248L, 5845152L, 0L);
					case 36:
						return CreateOffsets(9178992L, 9190976L, 0L, 9210656L, 8497968L, 5846416L, 5846320L, 0L);
					case 37:
						return CreateOffsets(9185360L, 9197344L, 0L, 9217008L, 8499712L, 5846544L, 5846448L, 0L);
					case 38:
						return CreateOffsets(9186160L, 9198144L, 0L, 9217808L, 8500480L, 5847360L, 5847264L, 0L);
					case 39:
						return CreateOffsets(9190464L, 9202448L, 0L, 9222112L, 8504784L, 5851648L, 5851552L, 0L);
					case 40:
						return CreateOffsets(9191424L, 9203408L, 0L, 9223072L, 8505728L, 5852480L, 5852384L, 0L);
					}
					break;
				}
				break;
			case 2020:
				switch (unityVersion.Minor)
				{
				case 1:
					switch (unityVersion.Build)
					{
					case 0:
						return CreateOffsets(8542848L, 8555104L, 0L, 8573920L, 7836576L, 5291184L, 5291088L, 0L);
					case 1:
						return CreateOffsets(8554816L, 8567072L, 0L, 8585888L, 7839760L, 5293008L, 5292912L, 0L);
					case 2:
						return CreateOffsets(8555040L, 8567296L, 0L, 8586112L, 7839984L, 5293232L, 5293136L, 0L);
					case 3:
						return CreateOffsets(8555136L, 8567392L, 0L, 8586208L, 7839888L, 5292896L, 5292800L, 0L);
					case 4:
						return CreateOffsets(8558144L, 8570400L, 0L, 8589216L, 7842480L, 5294512L, 5294416L, 0L);
					case 5:
						return CreateOffsets(8559504L, 8571728L, 0L, 8590576L, 7843552L, 5294336L, 5294240L, 0L);
					case 6:
						return CreateOffsets(8560112L, 8572336L, 0L, 8591184L, 7844160L, 5294912L, 5294816L, 0L);
					case 7:
						return CreateOffsets(8564240L, 8576464L, 0L, 8595312L, 7847888L, 5297120L, 5297024L, 0L);
					case 8:
						return CreateOffsets(8564064L, 8576288L, 0L, 8595136L, 7847712L, 5296976L, 5296880L, 0L);
					case 9:
						return CreateOffsets(8564496L, 8576720L, 0L, 8595568L, 7848144L, 5296720L, 5296624L, 0L);
					case 10:
						return CreateOffsets(8564688L, 8576912L, 0L, 8595760L, 7848336L, 5296992L, 5296896L, 0L);
					case 11:
						return CreateOffsets(8566320L, 8578544L, 0L, 8597392L, 7849968L, 5298736L, 5298640L, 0L);
					case 12:
						return CreateOffsets(8566672L, 8578896L, 0L, 8597744L, 7850320L, 5298864L, 5298768L, 0L);
					case 13:
						return CreateOffsets(8572176L, 8584400L, 0L, 8603248L, 7855856L, 5304352L, 5304256L, 0L);
					case 14:
						return CreateOffsets(8577376L, 8589616L, 0L, 8608368L, 7861024L, 5307440L, 5307344L, 0L);
					case 15:
						return CreateOffsets(8580352L, 8592592L, 0L, 8611376L, 7863840L, 5309536L, 5309440L, 0L);
					case 16:
						return CreateOffsets(8585936L, 8598176L, 0L, 8616960L, 7869040L, 5312880L, 5312784L, 0L);
					case 17:
						return CreateOffsets(8586304L, 8598544L, 0L, 8617328L, 7869408L, 5313072L, 5312976L, 0L);
					}
					break;
				case 2:
					switch (unityVersion.Build)
					{
					case 0:
						return CreateOffsets(9087040L, 9101408L, 0L, 9122512L, 8355392L, 5680336L, 5680240L, 26666624L);
					case 1:
						return CreateOffsets(9087040L, 9101408L, 0L, 9122512L, 8355392L, 5680336L, 5680240L, 26666624L);
					case 2:
						return CreateOffsets(9090976L, 9105344L, 0L, 9126448L, 8358752L, 5682848L, 5682752L, 26670784L);
					case 3:
						return CreateOffsets(9100640L, 9115008L, 0L, 9136112L, 8368192L, 5685776L, 5685680L, 26687232L);
					case 4:
						return CreateOffsets(9101840L, 9116208L, 0L, 9137344L, 8369392L, 5686848L, 5686752L, 26695488L);
					case 5:
						return CreateOffsets(9103824L, 9118192L, 0L, 9139328L, 8371376L, 5688016L, 5687920L, 26699712L);
					case 6:
						return CreateOffsets(9099936L, 9114304L, 0L, 9135440L, 8367488L, 5683312L, 5683216L, 26703744L);
					case 7:
						return CreateOffsets(9101744L, 9116112L, 0L, 9137248L, 8369296L, 5684752L, 5684656L, 26708096L);
					}
					break;
				case 3:
					switch (unityVersion.Build)
					{
					case 0:
						return CreateOffsets(9102800L, 9117168L, 0L, 9138304L, 8370352L, 5684832L, 5684736L, 26708096L);
					case 1:
						return CreateOffsets(9135888L, 9150256L, 0L, 9171392L, 8402912L, 5718320L, 5718224L, 26753152L);
					case 2:
						return CreateOffsets(9137280L, 9151648L, 0L, 9172784L, 8404144L, 5718288L, 5718192L, 26757248L);
					case 3:
						return CreateOffsets(9139248L, 9153616L, 0L, 9174752L, 8406048L, 5719504L, 5719408L, 26757248L);
					case 4:
						return CreateOffsets(9139568L, 9153936L, 0L, 9175072L, 8406368L, 5719520L, 5719424L, 26757248L);
					case 5:
						return CreateOffsets(9147488L, 9161856L, 0L, 9182992L, 8413136L, 5724112L, 5724016L, 26773696L);
					case 6:
						return CreateOffsets(9146384L, 9160752L, 0L, 9181888L, 8412032L, 5724160L, 5724064L, 26769600L);
					case 7:
						return CreateOffsets(9147248L, 9161616L, 0L, 9182752L, 8412528L, 5724576L, 5724480L, 26777792L);
					case 8:
						return CreateOffsets(9147952L, 9162320L, 0L, 9183456L, 8412240L, 5724080L, 5723984L, 26474688L);
					case 9:
						return CreateOffsets(9148192L, 9162560L, 0L, 9183696L, 8412400L, 5724272L, 5724176L, 26538752L);
					case 10:
						return CreateOffsets(9156768L, 9171136L, 0L, 9192272L, 8420640L, 5724928L, 5724832L, 26547008L);
					case 11:
						return CreateOffsets(9160864L, 9175232L, 0L, 9196368L, 8424768L, 5728624L, 5728528L, 26551232L);
					case 12:
						return CreateOffsets(9161808L, 9176176L, 0L, 9197312L, 8425696L, 5729328L, 5729232L, 26543040L);
					case 13:
						return CreateOffsets(9163456L, 9177824L, 0L, 9198960L, 8427216L, 5730144L, 5730048L, 26547136L);
					case 14:
						return CreateOffsets(9165152L, 9179600L, 0L, 9200736L, 8428912L, 5731824L, 5731728L, 26563520L);
					case 15:
						return CreateOffsets(9165120L, 9179568L, 0L, 9200704L, 8428896L, 5731824L, 5731728L, 26563520L);
					case 16:
						return CreateOffsets(9168512L, 9182944L, 0L, 9203904L, 8432208L, 5734288L, 5734192L, 26571712L);
					case 17:
						return CreateOffsets(9173248L, 9187680L, 0L, 9208640L, 8436928L, 5738592L, 5738496L, 26584256L);
					case 18:
						return CreateOffsets(9191056L, 9205488L, 0L, 9226448L, 8454496L, 5755536L, 5755440L, 26600640L);
					case 19:
						return CreateOffsets(9191200L, 9205632L, 0L, 9226592L, 8454928L, 5755040L, 5754944L, 26600576L);
					case 20:
						return CreateOffsets(9191680L, 9206112L, 0L, 9227072L, 8455296L, 5755216L, 5755120L, 26600576L);
					case 21:
						return CreateOffsets(9192784L, 9207216L, 0L, 9228176L, 8455472L, 5755168L, 5755072L, 26625152L);
					case 22:
						return CreateOffsets(9196320L, 9210752L, 0L, 9231712L, 8458960L, 5756528L, 5756432L, 26629248L);
					case 23:
						return CreateOffsets(9193808L, 9208240L, 0L, 9229200L, 8458000L, 5757024L, 5756928L, 26625344L);
					case 24:
						return CreateOffsets(9195328L, 9209760L, 0L, 9230720L, 8459424L, 5758448L, 5758352L, 26695168L);
					case 25:
						return CreateOffsets(9202192L, 9216624L, 0L, 9237584L, 8466400L, 5765376L, 5765280L, 26703360L);
					case 26:
						return CreateOffsets(9202848L, 9217280L, 0L, 9238240L, 8467040L, 5766048L, 5765952L, 26703360L);
					case 27:
						return CreateOffsets(9207264L, 9221696L, 0L, 9242656L, 8470784L, 5769712L, 5769616L, 26707520L);
					case 28:
						return CreateOffsets(9209568L, 9224000L, 0L, 9244960L, 8473024L, 5771328L, 5771232L, 26711616L);
					case 29:
						return CreateOffsets(9211408L, 9225840L, 0L, 9246800L, 8474864L, 5771968L, 5771872L, 26703552L);
					case 30:
						return CreateOffsets(9212528L, 9226960L, 0L, 9247920L, 8475984L, 5772784L, 5772688L, 26703552L);
					case 31:
						return CreateOffsets(9244416L, 9259040L, 0L, 9280736L, 8497744L, 5787920L, 5787824L, 26744576L);
					case 32:
						return CreateOffsets(9245184L, 9259808L, 0L, 9281504L, 8498496L, 5788320L, 5788224L, 26748672L);
					case 33:
						return CreateOffsets(9244608L, 9259232L, 0L, 9280928L, 8497856L, 5787920L, 5787824L, 26748672L);
					case 34:
						return CreateOffsets(9244960L, 9259584L, 0L, 9281280L, 8497920L, 5787904L, 5787808L, 26752768L);
					case 35:
						return CreateOffsets(9247424L, 9262048L, 0L, 9283744L, 8500256L, 5788576L, 5788480L, 26752768L);
					case 36:
						return CreateOffsets(9247872L, 9262496L, 0L, 9284192L, 8500704L, 5788832L, 5788736L, 26760960L);
					case 37:
						return CreateOffsets(9251104L, 9265728L, 0L, 9287424L, 8503936L, 5789952L, 5789856L, 26777344L);
					case 38:
						return CreateOffsets(9260896L, 9275552L, 0L, 9297248L, 8513648L, 5791632L, 5791536L, 26777472L);
					case 39:
						return CreateOffsets(9261504L, 9276160L, 0L, 9297856L, 8512864L, 5791952L, 5791856L, 26818368L);
					case 40:
						return CreateOffsets(9262560L, 9277216L, 0L, 9298912L, 8513920L, 5791984L, 5791888L, 26953536L);
					case 41:
						return CreateOffsets(9266896L, 9281552L, 0L, 9303248L, 8517680L, 5794032L, 5793936L, 26961920L);
					case 42:
						return CreateOffsets(9277136L, 9291792L, 0L, 9313488L, 8527648L, 5803488L, 5803392L, 26974208L);
					case 43:
						return CreateOffsets(9280848L, 9295504L, 0L, 9317200L, 8531360L, 5804160L, 5804064L, 26978304L);
					case 44:
						return CreateOffsets(9274672L, 9289280L, 0L, 9309952L, 8525120L, 5800848L, 5800752L, 26961856L);
					case 45:
						return CreateOffsets(8980480L, 8995088L, 0L, 9015760L, 8230560L, 5502768L, 5502672L, 26986432L);
					case 46:
						return CreateOffsets(8981712L, 8996320L, 0L, 9016992L, 8231792L, 5503600L, 5503504L, 26986496L);
					case 47:
						return CreateOffsets(8982128L, 8996736L, 0L, 9017408L, 8232208L, 5504064L, 5503968L, 26990592L);
					case 48:
						return CreateOffsets(8985392L, 9000000L, 0L, 9020672L, 8235664L, 5506688L, 5506592L, 26990592L);
					}
					break;
				}
				break;
			case 2021:
				switch (unityVersion.Minor)
				{
				case 1:
					switch (unityVersion.Build)
					{
					case 0:
						return CreateOffsets(9107152L, 9120176L, 0L, 9140112L, 8377760L, 5711216L, 5711120L, 26714752L);
					case 1:
						return CreateOffsets(9110304L, 9123328L, 0L, 9143264L, 8380848L, 5712688L, 5712592L, 26722944L);
					case 2:
						return CreateOffsets(9113344L, 9126368L, 0L, 9146304L, 8383744L, 5715584L, 5715488L, 26727040L);
					case 3:
						return CreateOffsets(9114656L, 9127680L, 0L, 9147616L, 8384640L, 5715888L, 5715792L, 26788480L);
					case 4:
						return CreateOffsets(9115632L, 9128656L, 0L, 9148592L, 8384608L, 5715568L, 5715472L, 26792576L);
					case 5:
						return CreateOffsets(9114752L, 9127776L, 0L, 9147696L, 8383792L, 5715440L, 5715344L, 26489472L);
					case 6:
						return CreateOffsets(9116704L, 9129728L, 0L, 9149648L, 8385456L, 5717264L, 5717168L, 26493568L);
					case 7:
						return CreateOffsets(9116688L, 9129712L, 0L, 9149632L, 8385440L, 5717168L, 5717072L, 26493568L);
					case 9:
						return CreateOffsets(9119360L, 9132464L, 0L, 9152384L, 8387840L, 5718240L, 5718144L, 26485440L);
					case 10:
						return CreateOffsets(9122064L, 9135168L, 0L, 9155088L, 8390288L, 5720304L, 5720208L, 26489536L);
					case 11:
						return CreateOffsets(9122064L, 9135168L, 0L, 9155088L, 8390288L, 5720304L, 5720208L, 26489536L);
					case 12:
						return CreateOffsets(9122128L, 9135232L, 0L, 9155152L, 8390336L, 5720352L, 5720256L, 26489536L);
					case 13:
						return CreateOffsets(9122272L, 9135376L, 0L, 9155296L, 8390480L, 5720496L, 5720400L, 26489536L);
					case 14:
						return CreateOffsets(9123696L, 9136800L, 0L, 9156720L, 8391904L, 5721936L, 5721840L, 26493632L);
					case 15:
						return CreateOffsets(9124368L, 9137488L, 0L, 9157328L, 8392640L, 5722672L, 5722576L, 26505920L);
					case 16:
						return CreateOffsets(9001600L, 9014720L, 0L, 9034560L, 8269728L, 5600688L, 5600592L, 26516224L);
					case 17:
						return CreateOffsets(9004032L, 9017152L, 0L, 9036992L, 8272096L, 5602304L, 5602208L, 26520320L);
					case 18:
						return CreateOffsets(9020048L, 9033168L, 0L, 9053008L, 8288016L, 5618256L, 5618160L, 26537024L);
					case 19:
						return CreateOffsets(9021216L, 9034336L, 0L, 9054176L, 8289184L, 5619216L, 5619120L, 26537024L);
					case 20:
						return CreateOffsets(9022272L, 9035392L, 0L, 9055232L, 8290240L, 5620112L, 5620016L, 26541120L);
					case 21:
						return CreateOffsets(9022752L, 9035872L, 0L, 9055712L, 8290672L, 5620336L, 5620240L, 26541120L);
					case 22:
						return CreateOffsets(9023920L, 9037040L, 0L, 9056880L, 8292032L, 5620320L, 5620224L, 26541120L);
					case 23:
						return CreateOffsets(9023392L, 9036512L, 0L, 9056352L, 8291504L, 5620032L, 5619936L, 26541120L);
					case 24:
						return CreateOffsets(9022208L, 9035328L, 0L, 9055168L, 8290352L, 5618944L, 5618848L, 26561600L);
					case 25:
						return CreateOffsets(9026880L, 9040000L, 0L, 9059840L, 8294112L, 5620704L, 5620608L, 26569792L);
					case 26:
						return CreateOffsets(9027472L, 9040592L, 0L, 9060432L, 8294688L, 5621152L, 5621056L, 26569792L);
					case 27:
						return CreateOffsets(9026768L, 9039888L, 0L, 9059728L, 8293984L, 5620224L, 5620128L, 26569792L);
					case 28:
						return CreateOffsets(9026528L, 9039648L, 0L, 9059488L, 8293680L, 5619808L, 5619712L, 26569792L);
					}
					break;
				case 2:
					switch (unityVersion.Build)
					{
					case 0:
						return CreateOffsets(6652704L, 6667376L, 0L, 6692368L, 5807344L, 2872928L, 2872848L, 27258624L);
					case 1:
						return CreateOffsets(6652976L, 6667648L, 0L, 6692640L, 5807568L, 2872928L, 2872848L, 27258624L);
					case 2:
						return CreateOffsets(6655264L, 6669936L, 0L, 6694928L, 5809856L, 2874560L, 2874480L, 27266880L);
					case 3:
						return CreateOffsets(6656032L, 6670704L, 0L, 6695696L, 5810656L, 2874464L, 2874384L, 27271040L);
					case 4:
						return CreateOffsets(6655456L, 6670128L, 0L, 6695120L, 5810080L, 2874688L, 2874608L, 27271232L);
					case 5:
						return CreateOffsets(6656720L, 6671392L, 0L, 6696384L, 5811344L, 2875344L, 2875264L, 27275200L);
					case 6:
						return CreateOffsets(6657024L, 6671696L, 0L, 6696688L, 5811648L, 2875344L, 2875264L, 27275264L);
					case 7:
						return CreateOffsets(6657344L, 6672016L, 0L, 6697008L, 5811968L, 2875664L, 2875584L, 27279360L);
					case 8:
						return CreateOffsets(6658624L, 6673296L, 0L, 6698288L, 5813216L, 2876048L, 2875968L, 27287616L);
					case 9:
						return CreateOffsets(6659744L, 6674416L, 0L, 6699408L, 5814192L, 2876384L, 2876304L, 27291776L);
					case 10:
						return CreateOffsets(6660320L, 6674992L, 0L, 6699984L, 5814064L, 2876384L, 2876304L, 27295872L);
					case 11:
						return CreateOffsets(6660240L, 6674912L, 0L, 6699904L, 5813984L, 2876272L, 2876192L, 27295872L);
					case 12:
						return CreateOffsets(6661344L, 6676016L, 0L, 6701008L, 5815104L, 2876528L, 2876448L, 27300096L);
					case 13:
						return CreateOffsets(6661360L, 6676032L, 0L, 6701024L, 5815104L, 2876528L, 2876448L, 27300096L);
					case 14:
						return CreateOffsets(6661744L, 6676416L, 0L, 6701408L, 5815488L, 2876528L, 2876448L, 27300096L);
					case 15:
						return CreateOffsets(6661744L, 6676416L, 0L, 6701408L, 5815488L, 2876528L, 2876448L, 27304192L);
					case 16:
						return CreateOffsets(6661744L, 6676416L, 0L, 6701408L, 5815488L, 2876528L, 2876448L, 27312384L);
					case 17:
						return CreateOffsets(6663264L, 6677952L, 0L, 6702672L, 5815616L, 2876528L, 2876448L, 27320576L);
					case 18:
						return CreateOffsets(6666800L, 6681488L, 0L, 6706208L, 5819664L, 2877440L, 2877360L, 27324672L);
					case 19:
						return CreateOffsets(6666928L, 6681616L, 0L, 6706336L, 5819792L, 2877744L, 2877664L, 27324672L);
					}
					break;
				case 3:
					switch (unityVersion.Build)
					{
					case 0:
						return CreateOffsets(6666928L, 6681616L, 0L, 6706336L, 5819792L, 2877744L, 2877664L, 27324672L);
					case 1:
						return CreateOffsets(6668880L, 6683568L, 0L, 6708288L, 5821696L, 2877744L, 2877664L, 27328768L);
					case 2:
						return CreateOffsets(6669776L, 6684464L, 0L, 6709184L, 5822160L, 2877744L, 2877664L, 27332864L);
					case 3:
						return CreateOffsets(6669856L, 6684544L, 0L, 6709264L, 5822240L, 2877840L, 2877760L, 27337024L);
					case 4:
						return CreateOffsets(6672928L, 6687616L, 0L, 6712336L, 5825312L, 2878608L, 2878528L, 27345152L);
					case 5:
						return CreateOffsets(6674656L, 6689344L, 0L, 6714064L, 5826928L, 2878640L, 2878560L, 27345216L);
					case 6:
						return CreateOffsets(6376752L, 6391440L, 0L, 6416160L, 5529024L, 2580704L, 2580624L, 27369792L);
					case 7:
						return CreateOffsets(6380896L, 6395584L, 0L, 6420304L, 5533168L, 2583872L, 2583792L, 27373888L);
					case 8:
						return CreateOffsets(6381040L, 6395728L, 0L, 6452416L, 5533312L, 2583936L, 2583856L, 27374208L);
					case 9:
						return CreateOffsets(6386512L, 6401152L, 0L, 6457664L, 5538928L, 2583632L, 2583552L, 27370112L);
					case 10:
						return CreateOffsets(6393664L, 6408304L, 0L, 6464816L, 5546064L, 2584256L, 2584176L, 27386560L);
					case 11:
						return CreateOffsets(6395648L, 6410288L, 0L, 6466800L, 5547456L, 2584576L, 2584496L, 27517632L);
					case 12:
						return CreateOffsets(6410224L, 6424864L, 0L, 6481392L, 5559296L, 2586112L, 2586032L, 27543424L);
					case 13:
						return CreateOffsets(6411888L, 6426528L, 0L, 6483056L, 5560272L, 2586288L, 2586208L, 27551616L);
					case 14:
						return CreateOffsets(6413456L, 6428096L, 0L, 6484624L, 5561808L, 2586528L, 2586448L, 27563968L);
					case 15:
						return CreateOffsets(6416896L, 6431536L, 0L, 6488064L, 5565216L, 2586608L, 2586528L, 27564032L);
					case 16:
						return CreateOffsets(6443840L, 6458480L, 0L, 6515008L, 5591552L, 2611616L, 2611536L, 27736704L);
					case 17:
						return CreateOffsets(6445008L, 6459648L, 0L, 6516176L, 5592960L, 2614560L, 2614480L, 27749120L);
					case 18:
						return CreateOffsets(6447856L, 6462496L, 0L, 6519040L, 5595792L, 2614864L, 2614784L, 27753344L);
					case 19:
						return CreateOffsets(6448480L, 6463120L, 0L, 6519664L, 5596128L, 2615088L, 2615008L, 27769728L);
					case 20:
						return CreateOffsets(6449712L, 6464352L, 0L, 6520896L, 5597360L, 2615744L, 2615664L, 27769792L);
					case 21:
						return CreateOffsets(6451840L, 6466480L, 0L, 6523024L, 5599184L, 2616480L, 2616400L, 27839424L);
					case 22:
						return CreateOffsets(6452016L, 6466656L, 0L, 6523200L, 5599360L, 2616480L, 2616400L, 27839424L);
					case 23:
						return CreateOffsets(6452656L, 6467296L, 0L, 6523840L, 5600192L, 2617376L, 2617296L, 27847680L);
					case 24:
						return CreateOffsets(6452688L, 6467328L, 0L, 6523872L, 5600176L, 2617376L, 2617296L, 27847680L);
					case 25:
						return CreateOffsets(6453056L, 6467696L, 0L, 6524240L, 5601376L, 2617424L, 2617344L, 27843584L);
					case 26:
						return CreateOffsets(6454560L, 6469200L, 0L, 6525744L, 5602864L, 2617472L, 2617392L, 27847680L);
					case 27:
						return CreateOffsets(6454800L, 6469440L, 0L, 6525984L, 5602880L, 2617472L, 2617392L, 27847680L);
					case 28:
						return CreateOffsets(6457680L, 6472320L, 0L, 6528864L, 5605600L, 2617744L, 2617664L, 27855872L);
					case 29:
						return CreateOffsets(6441072L, 6455712L, 0L, 6512256L, 5589024L, 2593760L, 2593680L, 27855936L);
					case 30:
						return CreateOffsets(6444464L, 6459104L, 0L, 6515648L, 5593776L, 2594128L, 2594048L, 27864128L);
					case 31:
						return CreateOffsets(6446528L, 6461168L, 0L, 6517712L, 5594896L, 2595088L, 2595008L, 27921472L);
					case 32:
						return CreateOffsets(6448704L, 6463344L, 0L, 6519888L, 5597008L, 2596272L, 2596192L, 27925568L);
					case 33:
						return CreateOffsets(6446528L, 6461168L, 0L, 6517712L, 5594304L, 2593680L, 2593600L, 27913152L);
					case 34:
						return CreateOffsets(6452272L, 6466912L, 0L, 6524096L, 5599184L, 2594336L, 2594256L, 27925504L);
					}
					break;
				}
				break;
			case 2022:
				switch (unityVersion.Minor)
				{
				case 1:
					switch (unityVersion.Build)
					{
					case 0:
						return CreateOffsets(6777184L, 6791680L, 0L, 6816768L, 5906960L, 2901088L, 2901008L, 27528640L);
					case 1:
						return CreateOffsets(6778016L, 6792528L, 0L, 6817616L, 5907392L, 2901232L, 2901152L, 27528640L);
					case 2:
						return CreateOffsets(6780976L, 6795488L, 0L, 6820576L, 5910352L, 2901600L, 2901520L, 27532672L);
					case 3:
						return CreateOffsets(6780976L, 6795488L, 0L, 6820576L, 5910352L, 2901600L, 2901520L, 27532672L);
					case 4:
						return CreateOffsets(6780608L, 6795120L, 0L, 6820208L, 5909984L, 2901600L, 2901520L, 27532672L);
					case 5:
						return CreateOffsets(6780608L, 6795120L, 0L, 6820208L, 5909984L, 2901600L, 2901520L, 27532672L);
					case 6:
						return CreateOffsets(6780528L, 6795040L, 0L, 6820128L, 5909600L, 2901600L, 2901520L, 27532672L);
					case 7:
						return CreateOffsets(6780528L, 6795040L, 0L, 6820128L, 5909600L, 2901600L, 2901520L, 27536768L);
					case 8:
						return CreateOffsets(6780848L, 6795360L, 0L, 6820448L, 5909920L, 2901600L, 2901520L, 27536768L);
					case 9:
						return CreateOffsets(6784272L, 6798784L, 0L, 6823872L, 5913344L, 2901888L, 2901808L, 27684224L);
					case 10:
						return CreateOffsets(6784272L, 6798784L, 0L, 6856288L, 5913344L, 2901888L, 2901808L, 27684480L);
					case 11:
						return CreateOffsets(6784272L, 6798784L, 0L, 6856288L, 5913344L, 2901888L, 2901808L, 27684480L);
					case 12:
						return CreateOffsets(6785312L, 6799824L, 0L, 6857344L, 5914368L, 2902112L, 2902032L, 27684544L);
					case 13:
						return CreateOffsets(6797280L, 6811792L, 0L, 6869312L, 5926352L, 2902112L, 2902032L, 27696832L);
					case 14:
						return CreateOffsets(6797104L, 6811616L, 0L, 6869136L, 5926176L, 2901952L, 2901872L, 27729600L);
					case 15:
						return CreateOffsets(6797104L, 6811616L, 0L, 6869136L, 5926176L, 2901952L, 2901872L, 27737792L);
					case 16:
						return CreateOffsets(6797360L, 6811872L, 0L, 6869392L, 5926176L, 2901952L, 2901872L, 27737792L);
					case 17:
						return CreateOffsets(6798208L, 6812720L, 0L, 6870240L, 5927024L, 2901936L, 2901856L, 27733696L);
					case 18:
						return CreateOffsets(6800912L, 6815424L, 0L, 6872944L, 5929184L, 2902288L, 2902208L, 27737920L);
					case 19:
						return CreateOffsets(6801392L, 6815904L, 0L, 6873424L, 5929664L, 2902608L, 2902528L, 27737920L);
					case 20:
						return CreateOffsets(6801376L, 6815888L, 0L, 6873408L, 5929648L, 2902592L, 2902512L, 27737920L);
					case 21:
						return CreateOffsets(6807376L, 6821888L, 0L, 6879408L, 5935264L, 2902992L, 2902912L, 27746176L);
					case 22:
						return CreateOffsets(6807568L, 6822080L, 0L, 6879600L, 5935456L, 2902992L, 2902912L, 27746176L);
					case 23:
						return CreateOffsets(6807968L, 6822480L, 0L, 6880000L, 5935744L, 2903152L, 2903072L, 27754368L);
					case 24:
						return CreateOffsets(6809360L, 6823872L, 0L, 6881392L, 5937024L, 2903152L, 2903072L, 27746176L);
					}
					break;
				case 2:
					switch (unityVersion.Build)
					{
					case 0:
						return CreateOffsets(7635360L, 7634128L, 0L, 7719360L, 6690192L, 3458912L, 6453920L, 28917696L);
					case 1:
						return CreateOffsets(7637952L, 7636720L, 0L, 7721952L, 6692784L, 3457664L, 6456512L, 28917760L);
					case 2:
						return CreateOffsets(7643824L, 7642592L, 0L, 7727824L, 6698096L, 3457296L, 6461824L, 28934144L);
					case 3:
						return CreateOffsets(7647840L, 7646608L, 0L, 7731840L, 6702048L, 3460656L, 6461728L, 28933120L);
					case 4:
						return CreateOffsets(7666592L, 7665360L, 0L, 7750896L, 6717104L, 3472224L, 6476864L, 28963136L);
					case 5:
						return CreateOffsets(7668512L, 7667280L, 0L, 7752832L, 6719024L, 3473280L, 6478784L, 28967168L);
					case 6:
						return CreateOffsets(7669008L, 7667776L, 0L, 7753328L, 6719184L, 3473216L, 6478944L, 28967232L);
					case 7:
						return CreateOffsets(7681936L, 7680704L, 0L, 7766256L, 6732192L, 3478656L, 6492608L, 28979520L);
					case 8:
						return CreateOffsets(7683840L, 7682608L, 0L, 7768160L, 6733888L, 3480368L, 6494320L, 28983616L);
					case 9:
						return CreateOffsets(7683616L, 7682384L, 0L, 7767936L, 6735184L, 3481280L, 6495616L, 28991808L);
					case 10:
						return CreateOffsets(7685120L, 7683888L, 0L, 7769440L, 6737008L, 3482176L, 6497424L, 28983616L);
					case 11:
						return CreateOffsets(7687392L, 7686160L, 0L, 7771712L, 6739120L, 3481888L, 6498848L, 28987776L);
					case 12:
						return CreateOffsets(7688928L, 7687696L, 0L, 7773248L, 6740656L, 3480112L, 6500384L, 28995968L);
					case 13:
						return CreateOffsets(7686160L, 7684928L, 0L, 7770480L, 6738016L, 3478880L, 6497744L, 28991872L);
					case 14:
						return CreateOffsets(7690688L, 7689456L, 0L, 7775008L, 6742544L, 3481072L, 6502272L, 29004224L);
					case 15:
						return CreateOffsets(7696432L, 7695200L, 0L, 7780784L, 6748528L, 3482784L, 6508256L, 29012416L);
					case 16:
						return CreateOffsets(7698016L, 7696784L, 0L, 7782368L, 6750352L, 3482544L, 6510080L, 29012288L);
					case 17:
						return CreateOffsets(7698752L, 7697520L, 0L, 7783104L, 6750816L, 3482528L, 6510528L, 29008128L);
					case 18:
						return CreateOffsets(7712128L, 7710896L, 0L, 7796480L, 6764032L, 3482960L, 6523504L, 29032896L);
					case 19:
						return CreateOffsets(7713040L, 7711808L, 0L, 7797392L, 6764944L, 3482992L, 6524416L, 29118976L);
					case 20:
						return CreateOffsets(7843536L, 7842304L, 0L, 7928272L, 6889552L, 3570320L, 6649504L, 29295232L);
					case 21:
						return CreateOffsets(7846064L, 7844832L, 0L, 7930800L, 6892224L, 3570592L, 6652176L, 29295296L);
					}
					break;
				case 3:
					switch (unityVersion.Build)
					{
					case 0:
						return CreateOffsets(7847584L, 7846352L, 0L, 7932528L, 6892992L, 3570704L, 6652400L, 29299392L);
					case 1:
						return CreateOffsets(7845168L, 7843936L, 0L, 7930080L, 6891360L, 3570512L, 6650848L, 29299456L);
					case 2:
						return CreateOffsets(7845584L, 7844352L, 0L, 7930496L, 6891600L, 3570656L, 6651088L, 29299456L);
					case 3:
						return CreateOffsets(7844976L, 7843744L, 0L, 7929888L, 6891504L, 3570768L, 6651024L, 29303552L);
					case 4:
						return CreateOffsets(7845360L, 7844128L, 0L, 7930272L, 6891872L, 3571136L, 6651392L, 29303552L);
					case 5:
						return CreateOffsets(7770736L, 7769504L, 0L, 7855648L, 6816912L, 3496112L, 6575392L, 29305024L);
					case 6:
						return CreateOffsets(7770304L, 7769072L, 0L, 7855216L, 6816176L, 3494512L, 6574496L, 29313280L);
					case 7:
						return CreateOffsets(7777520L, 7776288L, 0L, 7863936L, 6823312L, 3494432L, 6581392L, 29329856L);
					case 8:
						return CreateOffsets(7781552L, 7780320L, 0L, 7868240L, 6827904L, 3495520L, 6585968L, 29338048L);
					case 9:
						return CreateOffsets(7782592L, 7781360L, 0L, 7869280L, 6828848L, 3495632L, 6586912L, 29342272L);
					case 10:
						return CreateOffsets(7781968L, 7780736L, 0L, 7868656L, 6827888L, 3496800L, 6586336L, 29342208L);
					case 11:
						return CreateOffsets(7790496L, 7789264L, 0L, 7877248L, 6833280L, 3499872L, 6593040L, 29341760L);
					case 12:
						return CreateOffsets(7791136L, 7789904L, 0L, 7877920L, 6833904L, 3501472L, 6583520L, 29345984L);
					case 13:
						return CreateOffsets(7791744L, 7790512L, 0L, 7878528L, 6834000L, 3501568L, 6583616L, 29362368L);
					case 14:
						return CreateOffsets(7814944L, 7814464L, 0L, 7904272L, 6854512L, 3502448L, 6601600L, 29481152L);
					case 15:
						return CreateOffsets(7815904L, 7815424L, 0L, 7905408L, 6855280L, 3502128L, 6602368L, 29489344L);
					case 16:
						return CreateOffsets(7826928L, 7826448L, 0L, 7916400L, 6865920L, 3503072L, 6612752L, 29513984L);
					case 17:
						return CreateOffsets(7824736L, 7824256L, 0L, 7914208L, 6864000L, 3503088L, 6610832L, 29509824L);
					}
					break;
				}
				break;
			case 2023:
				switch (unityVersion.Minor)
				{
				case 1:
					switch (unityVersion.Build)
					{
					case 0:
						return CreateOffsets(6824560L, 6824016L, 0L, 6914080L, 5866960L, 2476800L, 5489344L, 28587648L);
					case 1:
						return CreateOffsets(6826352L, 6825808L, 0L, 6915872L, 5868752L, 2476976L, 5491168L, 28595840L);
					case 2:
						return CreateOffsets(6827456L, 6826912L, 0L, 6916976L, 5870496L, 2477888L, 5492912L, 28595840L);
					case 3:
						return CreateOffsets(6816704L, 6816160L, 0L, 6906224L, 5859744L, 2467136L, 5482208L, 28587648L);
					case 4:
						return CreateOffsets(6816736L, 6816192L, 0L, 6906256L, 5859776L, 2466688L, 5482192L, 28609600L);
					case 5:
						return CreateOffsets(6815968L, 6815424L, 0L, 6905488L, 5858960L, 2467248L, 5481376L, 28609600L);
					case 6:
						return CreateOffsets(6816400L, 6815856L, 0L, 6905920L, 5859392L, 2467328L, 5481648L, 28609600L);
					case 7:
						return CreateOffsets(6815216L, 6814672L, 0L, 6904736L, 5857920L, 2465872L, 5480176L, 28613696L);
					case 8:
						return CreateOffsets(6820336L, 6819792L, 0L, 6909856L, 5863088L, 2465664L, 5485104L, 28617728L);
					case 9:
						return CreateOffsets(6822976L, 6822432L, 0L, 6912768L, 5866416L, 2465712L, 5488416L, 28630080L);
					case 10:
						return CreateOffsets(6823552L, 6823008L, 0L, 6913344L, 5866944L, 2466208L, 5488944L, 28638272L);
					case 11:
						return CreateOffsets(6826448L, 6825904L, 0L, 6916240L, 5867984L, 2466320L, 5489984L, 28638272L);
					case 12:
						return CreateOffsets(6828720L, 6828176L, 0L, 6918512L, 5869888L, 2467312L, 5492480L, 28642496L);
					case 13:
						return CreateOffsets(6828992L, 6828448L, 0L, 6918784L, 5869984L, 2467872L, 5492560L, 28646592L);
					case 14:
						return CreateOffsets(6829424L, 6828880L, 0L, 6919216L, 5870368L, 2467888L, 5492944L, 28646656L);
					case 15:
						return CreateOffsets(6828320L, 6827776L, 0L, 6918112L, 5869312L, 2467792L, 5491776L, 28646656L);
					case 16:
						return CreateOffsets(6829280L, 6828736L, 0L, 6919072L, 5870272L, 2468448L, 5492352L, 28654848L);
					case 17:
						return CreateOffsets(6831440L, 6830896L, 0L, 6921152L, 5872336L, 2470672L, 5495888L, 28679488L);
					case 18:
						return CreateOffsets(6831792L, 6831248L, 0L, 6921552L, 5872672L, 2470912L, 5496224L, 28683584L);
					case 19:
						return CreateOffsets(6829024L, 6828480L, 0L, 6918784L, 5869904L, 2470928L, 5495696L, 28679488L);
					case 20:
						return CreateOffsets(6827824L, 6827280L, 0L, 6917296L, 5871216L, 2475888L, 5497056L, 28695872L);
					}
					break;
				case 2:
					switch (unityVersion.Build)
					{
					case 0:
						return CreateOffsets(7015696L, 7015120L, 0L, 7091776L, 6050128L, 2586768L, 2586960L, 29192896L);
					case 1:
						return CreateOffsets(7016576L, 7016000L, 0L, 7092672L, 6050928L, 2586416L, 2586608L, 29192896L);
					case 2:
						return CreateOffsets(7018288L, 7017712L, 0L, 7094384L, 6052832L, 2587200L, 2587392L, 29192896L);
					case 3:
						return CreateOffsets(7018224L, 7017648L, 0L, 7094320L, 6052768L, 2587216L, 2587408L, 29209280L);
					case 4:
						return CreateOffsets(7025840L, 7025264L, 0L, 7101952L, 6059616L, 2588864L, 2589056L, 29225664L);
					case 5:
						return CreateOffsets(7026144L, 7025568L, 0L, 7102256L, 6059888L, 2588880L, 2589072L, 29229760L);
					}
					break;
				}
				break;
			}
			return null;
		}

		private static Dictionary<string, long> CreateOffsets(long monoManagerAwakeFromLoadOffset, long monoManagerIsAssemblyCreatedOffset, long isFileCreatedOffset, long scriptingManagerDeconstructorOffset, long convertSeparatorsToPlatformOffset, long mallocInternalOffset, long freeAllocInternalOffset, long scriptingAssembliesOffset)
		{
			return new Dictionary<string, long>
			{
				["MonoManagerAwakeFromLoadOffset"] = monoManagerAwakeFromLoadOffset,
				["MonoManagerIsAssemblyCreatedOffset"] = monoManagerIsAssemblyCreatedOffset,
				["IsFileCreatedOffset"] = isFileCreatedOffset,
				["ScriptingManagerDeconstructorOffset"] = scriptingManagerDeconstructorOffset,
				["ConvertSeparatorsToPlatformOffset"] = convertSeparatorsToPlatformOffset,
				["MallocInternalOffset"] = mallocInternalOffset,
				["FreeAllocInternalOffset"] = freeAllocInternalOffset,
				["ScriptingAssembliesOffset"] = scriptingAssembliesOffset
			};
		}
	}
	internal class MiniPdbReader
	{
		private static readonly HttpClient _httpClient = new HttpClient
		{
			Timeout = TimeSpan.FromMinutes(5.0)
		};

		private readonly PeReader _peReader;

		private byte[] _pdbFile;

		internal bool IsPdbAvailable;

		internal bool UseCache;

		private static byte[] DownloadFromWeb(string url)
		{
			Log.Info("Downloading : " + url + "\nThis pdb file is needed for the plugin to work properly. This may take a while, relax, modding is coming.");
			try
			{
				HttpResponseMessage result = _httpClient.GetAsync(url).GetAwaiter().GetResult();
				Log.Info("Status Code : " + result.StatusCode);
				if (result.StatusCode != HttpStatusCode.OK)
				{
					return null;
				}
				return result.Content.ReadAsByteArrayAsync().GetAwaiter().GetResult();
			}
			catch (TaskCanceledException)
			{
				Log.Info("Could not download pdb. Plugin may not work correctly.");
				return null;
			}
		}

		internal MiniPdbReader(string targetFilePath)
		{
			_peReader = new PeReader(targetFilePath);
			if (_peReader.RsdsPdbFileName == null)
			{
				Log.Info("No pdb path found in the pe file. Falling back to supported versions");
				return;
			}
			UseCache = Config.LastDownloadedGUID.Value == _peReader.PdbGuid;
			Log.Message((UseCache ? "U" : "Not u") + "sing the config cache");
			if (!UseCache)
			{
				if (DownloadUnityPdb(_peReader))
				{
					Config.LastDownloadedGUID.Value = _peReader.PdbGuid;
					IsPdbAvailable = true;
				}
				else
				{
					Log.Info("Failed to find the linked pdb in the unity symbol server. Falling back to supported versions");
				}
			}
			else
			{
				IsPdbAvailable = true;
			}
		}

		private bool DownloadUnityPdb(PeReader peReader)
		{
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Expected O, but got Unknown
			string text = peReader.RsdsPdbFileName.TrimEnd(new char[1] { 'b' }) + "_";
			string url = "http://symbolserver.unity3d.com/" + peReader.RsdsPdbFileName + "/" + peReader.PdbGuid + "/" + text;
			byte[] array = DownloadFromWeb(url);
			if (array != null)
			{
				string tempPath = Path.GetTempPath();
				string text2 = Path.Combine(tempPath, "pdb.cab");
				try
				{
					File.Delete(text2);
				}
				catch (Exception)
				{
				}
				Log.Info("Writing the compressed pdb to " + text2);
				File.WriteAllBytes(text2, array);
				CabInfo val = new CabInfo(text2);
				Log.Info("Unpacking the compressed pdb");
				((ArchiveInfo)val).Unpack(tempPath);
				string path = Path.Combine(tempPath, peReader.RsdsPdbFileName);
				_pdbFile = File.ReadAllBytes(path);
				File.Delete(text2);
				File.Delete(path);
			}
			return _pdbFile != null;
		}

		internal unsafe IntPtr FindFunctionOffset(BytePattern[] bytePatterns)
		{
			fixed (byte* ptr = &_pdbFile[0])
			{
				IntPtr pdbStartAddress = (IntPtr)ptr;
				long sizeOfPdb = _pdbFile.Length;
				var anon = bytePatterns.Select((BytePattern p) => new
				{
					p = p,
					res = p.Match(pdbStartAddress, sizeOfPdb)
				}).FirstOrDefault(m => m.res > 0);
				if (anon == null)
				{
					return IntPtr.Zero;
				}
				Log.Info($"Found at {anon.res:X} ({pdbStartAddress.ToInt64() + anon.res:X})");
				uint* ptr2 = (uint*)(pdbStartAddress.ToInt64() + anon.res - 7);
				uint num = *ptr2;
				ushort* ptr3 = (ushort*)(pdbStartAddress.ToInt64() + anon.res - 3);
				int num2 = *ptr3 - 1;
				num += _peReader.ImageSectionHeaders[num2].VirtualAddress;
				Log.Info("Function offset : " + num.ToString("X") + " | PE section : " + num2);
				return new IntPtr(num);
			}
		}
	}
	internal static class MonoManagerCommon
	{
		public unsafe static void CopyNativeAssemblyListToManagedV0(List<StringStorageDefaultV0> managedAssemblyList, Vector<StringStorageDefaultV0> assemblyNames)
		{
			managedAssemblyList.Clear();
			for (StringStorageDefaultV0* ptr = assemblyNames.first; ptr != assemblyNames.last; ptr++)
			{
				managedAssemblyList.Add(*ptr);
			}
		}

		public unsafe static void AddAssembliesToManagedListV0(List<StringStorageDefaultV0> managedAssemblyList, List<string> pluginAssemblyPaths)
		{
			foreach (string pluginAssemblyPath in pluginAssemblyPaths)
			{
				string fileName = Path.GetFileName(pluginAssemblyPath);
				ulong num = (ulong)fileName.Length;
				IntPtr intPtr = Marshal.StringToHGlobalAnsi(fileName);
				byte* ptr = (byte*)(void*)intPtr + num;
				while (*ptr != 0)
				{
					ptr++;
					num++;
				}
				StringStorageDefaultV0 stringStorageDefaultV = default(StringStorageDefaultV0);
				stringStorageDefaultV.data = intPtr;
				stringStorageDefaultV.extra1 = num;
				stringStorageDefaultV.size = num;
				stringStorageDefaultV.flags = 31uL;
				stringStorageDefaultV.extra2 = 0uL;
				StringStorageDefaultV0 item = stringStorageDefaultV;
				managedAssemblyList.Add(item);
			}
		}

		public unsafe static void AllocNativeAssemblyListFromManagedV0(List<StringStorageDefaultV0> managedAssemblyList, Vector<StringStorageDefaultV0>* assemblyNames)
		{
			StringStorageDefaultV0* ptr = (StringStorageDefaultV0*)(void*)Marshal.AllocHGlobal(Marshal.SizeOf(typeof(StringStorageDefaultV0)) * managedAssemblyList.Count);
			int i = 0;
			StringStorageDefaultV0* ptr2 = ptr;
			for (; i < managedAssemblyList.Count; i++)
			{
				*ptr2 = managedAssemblyList[i];
				ptr2++;
			}
			assemblyNames->first = ptr;
			assemblyNames->last = ptr + managedAssemblyList.Count;
			assemblyNames->end = assemblyNames->last;
		}

		public unsafe static void PrintAssembliesV0(Vector<StringStorageDefaultV0> assemblyNames)
		{
			for (StringStorageDefaultV0* ptr = assemblyNames.first; ptr != assemblyNames.last; ptr++)
			{
				if (ptr->flags < 16)
				{
					Log.Warning("Ass: " + Marshal.PtrToStringAnsi((IntPtr)ptr));
				}
				else
				{
					Log.Warning("Ass: " + Marshal.PtrToStringAnsi(ptr->data, (int)ptr->size));
				}
			}
		}

		public unsafe static void CopyNativeAssemblyListToManagedV1(List<StringStorageDefaultV1> managedAssemblyList, Vector<StringStorageDefaultV1> assemblyNames)
		{
			managedAssemblyList.Clear();
			for (StringStorageDefaultV1* ptr = assemblyNames.first; ptr != assemblyNames.last; ptr++)
			{
				managedAssemblyList.Add(*ptr);
			}
		}

		public unsafe static void AddAssembliesToManagedListV1(List<StringStorageDefaultV1> managedAssemblyList, List<string> pluginAssemblyPaths)
		{
			foreach (string pluginAssemblyPath in pluginAssemblyPaths)
			{
				string fileName = Path.GetFileName(pluginAssemblyPath);
				ulong num = (ulong)fileName.Length;
				IntPtr intPtr = Marshal.StringToHGlobalAnsi(fileName);
				byte* ptr = (byte*)(void*)intPtr + num;
				while (*ptr != 0)
				{
					ptr++;
					num++;
				}
				StringStorageDefaultV1 stringStorageDefaultV = default(StringStorageDefaultV1);
				stringStorageDefaultV.label = UseRightStructs.LabelMemStringId;
				stringStorageDefaultV.data = intPtr;
				stringStorageDefaultV.capacity = num;
				stringStorageDefaultV.size = num;
				StringStorageDefaultV1 item = stringStorageDefaultV;
				managedAssemblyList.Add(item);
			}
		}

		public unsafe static void AllocNativeAssemblyListFromManagedV1(List<StringStorageDefaultV1> managedAssemblyList, Vector<StringStorageDefaultV1>* assemblyNames)
		{
			StringStorageDefaultV1* ptr = (StringStorageDefaultV1*)(void*)Marshal.AllocHGlobal(Marshal.SizeOf(typeof(StringStorageDefaultV1)) * managedAssemblyList.Count);
			int i = 0;
			StringStorageDefaultV1* ptr2 = ptr;
			for (; i < managedAssemblyList.Count; i++)
			{
				*ptr2 = managedAssemblyList[i];
				ptr2++;
			}
			assemblyNames->first = ptr;
			assemblyNames->last = ptr + managedAssemblyList.Count;
			assemblyNames->end = assemblyNames->last;
		}

		public unsafe static void PrintAssembliesV1(Vector<StringStorageDefaultV1> assemblyNames)
		{
			for (StringStorageDefaultV1* ptr = assemblyNames.first; ptr != assemblyNames.last; ptr++)
			{
				nint ptr2 = ptr->data;
				if (ptr->data == 0)
				{
					ptr2 = (nint)((byte*)ptr + 8);
				}
				Log.Warning($"Ass: {Marshal.PtrToStringAnsi(ptr2, (int)ptr->size)} | label : {ptr->label:X}");
			}
		}

		public unsafe static void CopyNativeAssemblyListToManagedV2(List<StringStorageDefaultV1> managedAssemblyList, DynamicArrayData assemblyNames)
		{
			managedAssemblyList.Clear();
			ulong num = 0uL;
			StringStorageDefaultV1* ptr = (StringStorageDefaultV1*)assemblyNames.ptr;
			for (; num < assemblyNames.size; num++)
			{
				managedAssemblyList.Add(*ptr);
				ptr++;
			}
		}

		public unsafe static void AllocNativeAssemblyListFromManagedV2(List<StringStorageDefaultV1> managedAssemblyList, DynamicArrayData* assemblyNames)
		{
			StringStorageDefaultV1* ptr = (StringStorageDefaultV1*)(void*)Marshal.AllocHGlobal(Marshal.SizeOf(typeof(StringStorageDefaultV1)) * managedAssemblyList.Count);
			int i = 0;
			StringStorageDefaultV1* ptr2 = ptr;
			for (; i < managedAssemblyList.Count; i++)
			{
				*ptr2 = managedAssemblyList[i];
				ptr2++;
			}
			assemblyNames->ptr = (nint)ptr;
			assemblyNames->size = (ulong)managedAssemblyList.Count;
			assemblyNames->capacity = assemblyNames->size;
		}

		public unsafe static void PrintAssembliesV2(DynamicArrayData assemblyNames)
		{
			ulong num = 0uL;
			StringStorageDefaultV1* ptr = (StringStorageDefaultV1*)assemblyNames.ptr;
			for (; num < assemblyNames.size; num++)
			{
				nint ptr2 = ptr->data;
				if (ptr->data == 0)
				{
					ptr2 = (nint)((byte*)ptr + 8);
				}
				Log.Warning($"Ass: {Marshal.PtrToStringAnsi(ptr2, (int)ptr->size)} | label : {ptr->label:X}");
				ptr++;
			}
		}

		public unsafe static void CopyNativeAssemblyListToManagedV3(List<StringStorageDefaultV2> managedAssemblyList, DynamicArrayData assemblyNames)
		{
			managedAssemblyList.Clear();
			ulong num = 0uL;
			StringStorageDefaultV2* ptr = (StringStorageDefaultV2*)assemblyNames.ptr;
			for (; num < assemblyNames.size; num++)
			{
				managedAssemblyList.Add(*ptr);
				ptr++;
			}
		}

		public unsafe static void AddAssembliesToManagedListV3(List<StringStorageDefaultV2> managedAssemblyList, List<string> pluginAssemblyPaths)
		{
			foreach (string pluginAssemblyPath in pluginAssemblyPaths)
			{
				string fileName = Path.GetFileName(pluginAssemblyPath);
				ulong num = (ulong)fileName.Length;
				IntPtr intPtr = Marshal.StringToHGlobalAnsi(fileName);
				byte* ptr = (byte*)(void*)intPtr + num;
				while (*ptr != 0)
				{
					ptr++;
					num++;
				}
				StringStorageDefaultV2 stringStorageDefaultV = default(StringStorageDefaultV2);
				stringStorageDefaultV.union = new StringStorageDefaultV2Union
				{
					heap = new HeapAllocatedRepresentationV2
					{
						data = intPtr,
						capacity = num,
						size = num
					}
				};
				stringStorageDefaultV.data_repr = StringRepresentation.Heap;
				stringStorageDefaultV.label = UseRightStructs.LabelMemStringId;
				StringStorageDefaultV2 item = stringStorageDefaultV;
				managedAssemblyList.Add(item);
			}
		}

		public unsafe static void AllocNativeAssemblyListFromManagedV3(List<StringStorageDefaultV2> managedAssemblyList, DynamicArrayData* assemblyNames)
		{
			StringStorageDefaultV2* ptr = (StringStorageDefaultV2*)(void*)Marshal.AllocHGlobal(Marshal.SizeOf(typeof(StringStorageDefaultV2)) * managedAssemblyList.Count);
			int i = 0;
			StringStorageDefaultV2* ptr2 = ptr;
			for (; i < managedAssemblyList.Count; i++)
			{
				*ptr2 = managedAssemblyList[i];
				ptr2++;
			}
			assemblyNames->ptr = (nint)ptr;
			assemblyNames->size = (ulong)managedAssemblyList.Count;
			assemblyNames->capacity = assemblyNames->size;
		}

		public unsafe static void PrintAssembliesV3(DynamicArrayData assemblyNames)
		{
			ulong num = 0uL;
			StringStorageDefaultV2* ptr = (StringStorageDefaultV2*)assemblyNames.ptr;
			for (; num < assemblyNames.size; num++)
			{
				if (ptr->data_repr == StringRepresentation.Embedded)
				{
					Log.Warning($"Ass: {Marshal.PtrToStringAnsi((IntPtr)ptr->union.embedded.data)} | label : {ptr->label:X}");
				}
				else
				{
					Log.Warning($"Ass: {Marshal.PtrToStringAnsi(ptr->union.heap.data, (int)ptr->union.heap.size)} | label : {ptr->label:X}");
				}
				ptr++;
			}
		}

		public unsafe static void CopyNativeAssemblyListToManagedV4(List<StringStorageDefaultV3> managedAssemblyList, DynamicArrayData assemblyNames)
		{
			managedAssemblyList.Clear();
			ulong num = 0uL;
			StringStorageDefaultV3* ptr = (StringStorageDefaultV3*)assemblyNames.ptr;
			for (; num < assemblyNames.size; num++)
			{
				managedAssemblyList.Add(*ptr);
				ptr++;
			}
		}

		public unsafe static void AddAssembliesToManagedListV4(List<StringStorageDefaultV3> managedAssemblyList, List<string> pluginAssemblyPaths)
		{
			foreach (string pluginAssemblyPath in pluginAssemblyPaths)
			{
				string fileName = Path.GetFileName(pluginAssemblyPath);
				ulong num = (ulong)fileName.Length;
				IntPtr intPtr = Marshal.StringToHGlobalAnsi(fileName);
				byte* ptr = (byte*)(void*)intPtr + num;
				while (*ptr != 0)
				{
					ptr++;
					num++;
				}
				StringStorageDefaultV3 stringStorageDefaultV = default(StringStorageDefaultV3);
				stringStorageDefaultV.union = new StringStorageDefaultV3Union
				{
					heap = new HeapAllocatedRepresentationV3
					{
						data = intPtr,
						capacity = num,
						size = num,
						flags = new StringStorageDefaultV3Flags
						{
							IsHeap = true
						}
					}
				};
				stringStorageDefaultV.label = UseRightStructs.LabelMemStringId;
				StringStorageDefaultV3 item = stringStorageDefaultV;
				managedAssemblyList.Add(item);
			}
		}

		public unsafe static void AllocNativeAssemblyListFromManagedV4(List<StringStorageDefaultV3> managedAssemblyList, DynamicArrayData* assemblyNames)
		{
			StringStorageDefaultV3* ptr = (StringStorageDefaultV3*)(void*)Marshal.AllocHGlobal(Marshal.SizeOf(typeof(StringStorageDefaultV3)) * managedAssemblyList.Count);
			int i = 0;
			StringStorageDefaultV3* ptr2 = ptr;
			for (; i < managedAssemblyList.Count; i++)
			{
				*ptr2 = managedAssemblyList[i];
				ptr2++;
			}
			assemblyNames->ptr = (nint)ptr;
			assemblyNames->size = (ulong)managedAssemblyList.Count;
			assemblyNames->capacity = assemblyNames->size;
		}

		public unsafe static void PrintAssembliesV4(DynamicArrayData assemblyNames)
		{
			ulong num = 0uL;
			StringStorageDefaultV3* ptr = (StringStorageDefaultV3*)assemblyNames.ptr;
			for (; num < assemblyNames.size; num++)
			{
				if (ptr->union.embedded.flags.IsEmbedded)
				{
					Log.Warning($"Ass: {Marshal.PtrToStringAnsi((IntPtr)ptr->union.embedded.data)} | label : {ptr->label:X}");
				}
				else
				{
					Log.Warning($"Ass: {Marshal.PtrToStringAnsi(ptr->union.heap.data, (int)ptr->union.heap.size)} | label : {ptr->label:X}");
				}
				ptr++;
			}
		}
	}
	internal class PatternDiscoverer
	{
		private readonly IntPtr unityModule;

		private readonly MiniPdbReader pdbReader;

		private readonly bool usePdb;

		private readonly Dictionary<string, long> functionOffsets;

		public PatternDiscoverer(IntPtr unityModule, string unityPlayerPath)
		{
			this.unityModule = unityModule;
			switch (Config.FunctionOffsetLookupType.Value)
			{
			case FunctionOffsetLookup.Manual:
				break;
			case FunctionOffsetLookup.PreferPdb:
				pdbReader = new MiniPdbReader(unityPlayerPath);
				usePdb = pdbReader.IsPdbAvailable;
				if (!usePdb)
				{
					if (!FunctionOffsets.TryGet(UseRightStructs.UnityVersion, out functionOffsets))
					{
						throw new NotSupportedException($"Pdb not found and {UseRightStructs.UnityVersion} is not a supported version");
					}
					Log.Info("Found offsets for current version, using them.");
				}
				break;
			case FunctionOffsetLookup.PreferSupportedVersions:
				if (!FunctionOffsets.TryGet(UseRightStructs.UnityVersion, out functionOffsets))
				{
					pdbReader = new MiniPdbReader(unityPlayerPath);
					usePdb = pdbReader.IsPdbAvailable;
					if (!usePdb)
					{
						throw new NotSupportedException($"{UseRightStructs.UnityVersion} is not a supported version and pdb not found");
					}
				}
				else
				{
					Log.Info("Found offsets for current version, using them.");
				}
				break;
			default:
				throw new ArgumentException("FunctionOffsetLookupType");
			}
		}

		public IntPtr Discover(ConfigEntry<string> functionOffsetCache, BytePattern[] pdbPatterns)
		{
			if (usePdb)
			{
				return DiscoverWithPdb(functionOffsetCache, pdbPatterns);
			}
			long num;
			if (functionOffsets != null)
			{
				num = functionOffsets[((ConfigEntryBase)functionOffsetCache).Definition.Key];
				functionOffsetCache.Value = num.ToString("X2");
				if (num == 0L)
				{
					return IntPtr.Zero;
				}
				IntPtr intPtr = unityModule;
				return (IntPtr)(intPtr.ToInt64() + num);
			}
			if (long.TryParse(functionOffsetCache.Value, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out num))
			{
				IntPtr intPtr = unityModule;
				return (IntPtr)(intPtr.ToInt64() + num);
			}
			return IntPtr.Zero;
		}

		private IntPtr DiscoverWithPdb(ConfigEntry<string> functionOffsetCache, BytePattern[] pdbPatterns)
		{
			IntPtr intPtr;
			if (pdbReader.UseCache)
			{
				intPtr = new IntPtr(Convert.ToInt64(functionOffsetCache.Value, 16));
				if (intPtr == IntPtr.Zero)
				{
					return intPtr;
				}
			}
			else
			{
				intPtr = pdbReader.FindFunctionOffset(pdbPatterns);
				if (intPtr == IntPtr.Zero)
				{
					functionOffsetCache.Value = "00";
					return intPtr;
				}
				functionOffsetCache.Value = intPtr.ToString("X2");
			}
			IntPtr intPtr2 = unityModule;
			return (IntPtr)(intPtr2.ToInt64() + intPtr.ToInt64());
		}
	}
	internal class PeReader
	{
		public struct IMAGE_DOS_HEADER
		{
			public ushort e_magic;

			public ushort e_cblp;

			public ushort e_cp;

			public ushort e_crlc;

			public ushort e_cparhdr;

			public ushort e_minalloc;

			public ushort e_maxalloc;

			public ushort e_ss;

			public ushort e_sp;

			public ushort e_csum;

			public ushort e_ip;

			public ushort e_cs;

			public ushort e_lfarlc;

			public ushort e_ovno;

			public ushort e_res_0;

			public ushort e_res_1;

			public ushort e_res_2;

			public ushort e_res_3;

			public ushort e_oemid;

			public ushort e_oeminfo;

			public ushort e_res2_0;

			public ushort e_res2_1;

			public ushort e_res2_2;

			public ushort e_res2_3;

			public ushort e_res2_4;

			public ushort e_res2_5;

			public ushort e_res2_6;

			public ushort e_res2_7;

			public ushort e_res2_8;

			public ushort e_res2_9;

			public uint e_lfanew;
		}

		public struct IMAGE_DATA_DIRECTORY
		{
			public uint VirtualAddress;

			public uint Size;
		}

		[StructLayout(LayoutKind.Sequential, Pack = 1)]
		public struct IMAGE_OPTIONAL_HEADER32
		{
			public ushort Magic;

			public byte MajorLinkerVersion;

			public byte MinorLinkerVersion;

			public uint SizeOfCode;

			public uint SizeOfInitializedData;

			public uint SizeOfUninitializedData;

			public uint AddressOfEntryPoint;

			public uint BaseOfCode;

			public uint BaseOfData;

			public uint ImageBase;

			public uint SectionAlignment;

			public uint FileAlignment;

			public ushort MajorOperatingSystemVersion;

			public ushort MinorOperatingSystemVersion;

			public ushort MajorImageVersion;

			public ushort MinorImageVersion;

			public ushort MajorSubsystemVersion;

			public ushort MinorSubsystemVersion;

			public uint Win32VersionValue;

			public uint SizeOfImage;

			public uint SizeOfHeaders;

			public uint CheckSum;

			public ushort Subsystem;

			public ushort DllCharacteristics;

			public uint SizeOfStackReserve;

			public uint SizeOfStackCommit;

			public uint SizeOfHeapReserve;

			public uint SizeOfHeapCommit;

			public uint LoaderFlags;

			public uint NumberOfRvaAndSizes;

			public IMAGE_DATA_DIRECTORY ExportTable;

			public IMAGE_DATA_DIRECTORY ImportTable;

			public IMAGE_DATA_DIRECTORY ResourceTable;

			public IMAGE_DATA_DIRECTORY ExceptionTable;

			public IMAGE_DATA_DIRECTORY CertificateTable;

			public IMAGE_DATA_DIRECTORY BaseRelocationTable;

			public IMAGE_DATA_DIRECTORY Debug;

			public IMAGE_DATA_DIRECTORY Architecture;

			public IMAGE_DATA_DIRECTORY GlobalPtr;

			public IMAGE_DATA_DIRECTORY TLSTable;

			public IMAGE_DATA_DIRECTORY LoadConfigTable;

			public IMAGE_DATA_DIRECTORY BoundImport;

			public IMAGE_DATA_DIRECTORY IAT;

			public IMAGE_DATA_DIRECTORY DelayImportDescriptor;

			public IMAGE_DATA_DIRECTORY CLRRuntimeHeader;

			public IMAGE_DATA_DIRECTORY Reserved;
		}

		[StructLayout(LayoutKind.Sequential, Pack = 1)]
		public struct IMAGE_OPTIONAL_HEADER64
		{
			public ushort Magic;

			public byte MajorLinkerVersion;

			public byte MinorLinkerVersion;

			public uint SizeOfCode;

			public uint SizeOfInitializedData;

			public uint SizeOfUninitializedData;

			public uint AddressOfEntryPoint;

			public uint BaseOfCode;

			public ulong ImageBase;

			public uint SectionAlignment;

			public uint FileAlignment;

			public ushort MajorOperatingSystemVersion;

			public ushort MinorOperatingSystemVersion;

			public ushort MajorImageVersion;

			public ushort MinorImageVersion;

			public ushort MajorSubsystemVersion;

			public ushort MinorSubsystemVersion;

			public uint Win32VersionValue;

			public uint SizeOfImage;

			public uint SizeOfHeaders;

			public uint CheckSum;

			public ushort Subsystem;

			public ushort DllCharacteristics;

			public ulong SizeOfStackReserve;

			public ulong SizeOfStackCommit;

			public ulong SizeOfHeapReserve;

			public ulong SizeOfHeapCommit;

			public uint LoaderFlags;

			public uint NumberOfRvaAndSizes;

			public IMAGE_DATA_DIRECTORY ExportTable;

			public IMAGE_DATA_DIRECTORY ImportTable;

			public IMAGE_DATA_DIRECTORY ResourceTable;

			public IMAGE_DATA_DIRECTORY ExceptionTable;

			public IMAGE_DATA_DIRECTORY CertificateTable;

			public IMAGE_DATA_DIRECTORY BaseRelocationTable;

			public IMAGE_DATA_DIRECTORY Debug;

			public IMAGE_DATA_DIRECTORY Architecture;

			public IMAGE_DATA_DIRECTORY GlobalPtr;

			public IMAGE_DATA_DIRECTORY TLSTable;

			public IMAGE_DATA_DIRECTORY LoadConfigTable;

			public IMAGE_DATA_DIRECTORY BoundImport;

			public IMAGE_DATA_DIRECTORY IAT;

			public IMAGE_DATA_DIRECTORY DelayImportDescriptor;

			public IMAGE_DATA_DIRECTORY CLRRuntimeHeader;

			public IMAGE_DATA_DIRECTORY Reserved;
		}

		[StructLayout(LayoutKind.Sequential, Pack = 1)]
		public struct IMAGE_FILE_HEADER
		{
			public ushort Machine;

			public ushort NumberOfSections;

			public uint TimeDateStamp;

			public uint PointerToSymbolTable;

			public uint NumberOfSymbols;

			public ushort SizeOfOptionalHeader;

			public ushort Characteristics;
		}

		[StructLayout(LayoutKind.Explicit)]
		public struct IMAGE_SECTION_HEADER
		{
			[FieldOffset(0)]
			[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)]
			public string Name;

			[FieldOffset(8)]
			public uint VirtualSize;

			[FieldOffset(12)]
			public uint VirtualAddress;

			[FieldOffset(16)]
			public uint SizeOfRawData;

			[FieldOffset(20)]
			public uint PointerToRawData;

			[FieldOffset(24)]
			public uint PointerToRelocations;

			[FieldOffset(28)]
			public uint PointerToLinenumbers;

			[FieldOffset(32)]
			public ushort NumberOfRelocations;

			[FieldOffset(34)]
			public ushort NumberOfLinenumbers;

			[FieldOffset(36)]
			public DataSectionFlags Characteristics;
		}

		[Flags]
		public enum DataSectionFlags : uint
		{
			TypeReg = 0u,
			TypeDsect = 1u,
			TypeNoLoad = 2u,
			TypeGroup = 4u,
			TypeNoPadded = 8u,
			TypeCopy = 0x10u,
			ContentCode = 0x20u,
			ContentInitializedData = 0x40u,
			ContentUninitializedData = 0x80u,
			LinkOther = 0x100u,
			LinkInfo = 0x200u,
			TypeOver = 0x400u,
			LinkRemove = 0x800u,
			LinkComDat = 0x1000u,
			NoDeferSpecExceptions = 0x4000u,
			RelativeGP = 0x8000u,
			MemPurgeable = 0x20000u,
			Memory16Bit = 0x20000u,
			MemoryLocked = 0x40000u,
			MemoryPreload = 0x80000u,
			Align1Bytes = 0x100000u,
			Align2Bytes = 0x200000u,
			Align4Bytes = 0x300000u,
			Align8Bytes = 0x400000u,
			Align16Bytes = 0x500000u,
			Align32Bytes = 0x600000u,
			Align64Bytes = 0x700000u,
			Align128Bytes = 0x800000u,
			A

BepInEx/patchers/FixPluginTypesSerializationDebug/Microsoft.Deployment.Compression.Cab.dll

Decompiled 3 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Security;
using System.Security.Permissions;
using System.Text;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyDescription("Managed libraries for cabinet archive packing and unpacking")]
[assembly: CLSCompliant(true)]
[assembly: ComVisible(false)]
[assembly: AllowPartiallyTrustedCallers]
[assembly: AssemblyFileVersion("3.10.1.2213")]
[assembly: AssemblyCompany("Outercurve Foundation")]
[assembly: AssemblyCopyright("Copyright (c) Outercurve Foundation. All rights reserved.")]
[assembly: AssemblyProduct("Windows Installer XML Toolset")]
[assembly: AssemblyConfiguration("")]
[assembly: NeutralResourcesLanguage("en-US")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, Assertion = true, UnmanagedCode = true)]
[assembly: AssemblyVersion("3.0.0.0")]
namespace Microsoft.Tools.WindowsInstallerXml
{
	internal static class WixDistribution
	{
		public static string NewsUrl = "http://wixtoolset.org/news/";

		public static string ShortProduct = "WiX Toolset";

		public static string SupportUrl = "http://wixtoolset.org/";

		public static string TelemetryUrlFormat = "http://wixtoolset.org/telemetry/v{0}/?r={1}";

		public static string ReplacePlaceholders(string original, Assembly assembly)
		{
			if ((object)assembly != null)
			{
				FileVersionInfo versionInfo = FileVersionInfo.GetVersionInfo(assembly.Location);
				original = original.Replace("[FileComments]", versionInfo.Comments);
				original = original.Replace("[FileCopyright]", versionInfo.LegalCopyright);
				original = original.Replace("[FileProductName]", versionInfo.ProductName);
				original = original.Replace("[FileVersion]", versionInfo.FileVersion);
				if (original.Contains("[FileVersionMajorMinor]"))
				{
					Version version = new Version(versionInfo.FileVersion);
					original = original.Replace("[FileVersionMajorMinor]", version.Major + "." + version.Minor);
				}
				if (TryGetAttribute<AssemblyCompanyAttribute>(assembly, out var attribute))
				{
					original = original.Replace("[AssemblyCompany]", attribute.Company);
				}
				if (TryGetAttribute<AssemblyCopyrightAttribute>(assembly, out var attribute2))
				{
					original = original.Replace("[AssemblyCopyright]", attribute2.Copyright);
				}
				if (TryGetAttribute<AssemblyDescriptionAttribute>(assembly, out var attribute3))
				{
					original = original.Replace("[AssemblyDescription]", attribute3.Description);
				}
				if (TryGetAttribute<AssemblyProductAttribute>(assembly, out var attribute4))
				{
					original = original.Replace("[AssemblyProduct]", attribute4.Product);
				}
				if (TryGetAttribute<AssemblyTitleAttribute>(assembly, out var attribute5))
				{
					original = original.Replace("[AssemblyTitle]", attribute5.Title);
				}
			}
			original = original.Replace("[NewsUrl]", NewsUrl);
			original = original.Replace("[ShortProduct]", ShortProduct);
			original = original.Replace("[SupportUrl]", SupportUrl);
			return original;
		}

		private static bool TryGetAttribute<T>(Assembly assembly, out T attribute) where T : Attribute
		{
			attribute = null;
			object[] customAttributes = assembly.GetCustomAttributes(typeof(T), inherit: false);
			if (customAttributes != null && customAttributes.Length != 0)
			{
				attribute = customAttributes[0] as T;
			}
			return attribute != null;
		}
	}
}
namespace Microsoft.Deployment.Compression.Cab
{
	internal class CabPacker : CabWorker
	{
		private const string TempStreamName = "%%TEMP%%";

		private NativeMethods.FCI.Handle fciHandle;

		private NativeMethods.FCI.PFNALLOC fciAllocMemHandler;

		private NativeMethods.FCI.PFNFREE fciFreeMemHandler;

		private NativeMethods.FCI.PFNOPEN fciOpenStreamHandler;

		private NativeMethods.FCI.PFNREAD fciReadStreamHandler;

		private NativeMethods.FCI.PFNWRITE fciWriteStreamHandler;

		private NativeMethods.FCI.PFNCLOSE fciCloseStreamHandler;

		private NativeMethods.FCI.PFNSEEK fciSeekStreamHandler;

		private NativeMethods.FCI.PFNFILEPLACED fciFilePlacedHandler;

		private NativeMethods.FCI.PFNDELETE fciDeleteFileHandler;

		private NativeMethods.FCI.PFNGETTEMPFILE fciGetTempFileHandler;

		private NativeMethods.FCI.PFNGETNEXTCABINET fciGetNextCabinet;

		private NativeMethods.FCI.PFNSTATUS fciCreateStatus;

		private NativeMethods.FCI.PFNGETOPENINFO fciGetOpenInfo;

		private IPackStreamContext context;

		private FileAttributes fileAttributes;

		private DateTime fileLastWriteTime;

		private int maxCabBytes;

		private long totalFolderBytesProcessedInCurrentCab;

		private CompressionLevel compressionLevel;

		private bool dontUseTempFiles;

		private IList<Stream> tempStreams;

		public bool UseTempFiles
		{
			get
			{
				return !dontUseTempFiles;
			}
			set
			{
				dontUseTempFiles = !value;
			}
		}

		public CompressionLevel CompressionLevel
		{
			get
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				return compressionLevel;
			}
			set
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				compressionLevel = value;
			}
		}

		public CabPacker(CabEngine cabEngine)
			: base(cabEngine)
		{
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			fciAllocMemHandler = base.CabAllocMem;
			fciFreeMemHandler = base.CabFreeMem;
			fciOpenStreamHandler = CabOpenStreamEx;
			fciReadStreamHandler = CabReadStreamEx;
			fciWriteStreamHandler = CabWriteStreamEx;
			fciCloseStreamHandler = CabCloseStreamEx;
			fciSeekStreamHandler = CabSeekStreamEx;
			fciFilePlacedHandler = CabFilePlaced;
			fciDeleteFileHandler = CabDeleteFile;
			fciGetTempFileHandler = CabGetTempFile;
			fciGetNextCabinet = CabGetNextCabinet;
			fciCreateStatus = CabCreateStatus;
			fciGetOpenInfo = CabGetOpenInfo;
			tempStreams = new List<Stream>();
			compressionLevel = (CompressionLevel)6;
		}

		private void CreateFci(long maxArchiveSize)
		{
			NativeMethods.FCI.CCAB cCAB = new NativeMethods.FCI.CCAB();
			checked
			{
				if (maxArchiveSize > 0 && maxArchiveSize < cCAB.cb)
				{
					cCAB.cb = Math.Max(32768, (int)maxArchiveSize);
				}
				object option = context.GetOption("maxFolderSize", (object[])null);
				if (option != null)
				{
					long num = Convert.ToInt64(option, CultureInfo.InvariantCulture);
					if (num > 0 && num < cCAB.cbFolderThresh)
					{
						cCAB.cbFolderThresh = (int)num;
					}
				}
				maxCabBytes = cCAB.cb;
				cCAB.szCab = context.GetArchiveName(0);
				if (cCAB.szCab == null)
				{
					throw new FileNotFoundException("Cabinet name not provided by stream context.");
				}
				cCAB.setID = (short)new Random().Next(-32768, 32768);
				base.CabNumbers[cCAB.szCab] = 0;
				currentArchiveName = cCAB.szCab;
				totalArchives = 1;
				base.CabStream = null;
				base.Erf.Clear();
				fciHandle = NativeMethods.FCI.Create(base.ErfHandle.AddrOfPinnedObject(), fciFilePlacedHandler, fciAllocMemHandler, fciFreeMemHandler, fciOpenStreamHandler, fciReadStreamHandler, fciWriteStreamHandler, fciCloseStreamHandler, fciSeekStreamHandler, fciDeleteFileHandler, fciGetTempFileHandler, cCAB, IntPtr.Zero);
				CheckError(extracting: false);
			}
		}

		[SecurityPermission(SecurityAction.Assert, UnmanagedCode = true)]
		public void Pack(IPackStreamContext streamContext, IEnumerable<string> files, long maxArchiveSize)
		{
			//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
			if (streamContext == null)
			{
				throw new ArgumentNullException("streamContext");
			}
			if (files == null)
			{
				throw new ArgumentNullException("files");
			}
			lock (this)
			{
				try
				{
					context = streamContext;
					ResetProgressData();
					CreateFci(maxArchiveSize);
					checked
					{
						FileAttributes fileAttributes = default(FileAttributes);
						DateTime dateTime = default(DateTime);
						foreach (string file in files)
						{
							Stream stream = context.OpenFileReadStream(file, ref fileAttributes, ref dateTime);
							if (stream != null)
							{
								totalFileBytes += stream.Length;
								totalFiles++;
								context.CloseFileReadStream(file, stream);
							}
						}
						long num = 0L;
						currentFileNumber = -1;
						FileAttributes attributes = default(FileAttributes);
						DateTime lastWriteTime = default(DateTime);
						foreach (string file2 in files)
						{
							Stream stream2 = context.OpenFileReadStream(file2, ref attributes, ref lastWriteTime);
							if (stream2 == null)
							{
								continue;
							}
							if (stream2.Length >= 2147450880)
							{
								throw new NotSupportedException(string.Format(CultureInfo.InvariantCulture, "File {0} exceeds maximum file size for cabinet format.", new object[1] { file2 }));
							}
							if (num > 0)
							{
								bool flag = num + stream2.Length >= 2147450880;
								if (!flag)
								{
									flag = Convert.ToBoolean(streamContext.GetOption("nextFolder", new object[2] { file2, currentFolderNumber }), CultureInfo.InvariantCulture);
								}
								if (flag)
								{
									FlushFolder();
									num = 0L;
								}
							}
							if (currentFolderTotalBytes > 0)
							{
								currentFolderTotalBytes = 0L;
								currentFolderNumber++;
								num = 0L;
							}
							currentFileName = file2;
							currentFileNumber++;
							currentFileTotalBytes = stream2.Length;
							currentFileBytesProcessed = 0L;
							OnProgress((ArchiveProgressType)0);
							num += stream2.Length;
							AddFile(file2, stream2, attributes, lastWriteTime, execute: false, CompressionLevel);
						}
						FlushFolder();
						FlushCabinet();
					}
				}
				finally
				{
					if (base.CabStream != null)
					{
						context.CloseArchiveWriteStream((int)currentArchiveNumber, currentArchiveName, base.CabStream);
						base.CabStream = null;
					}
					if (base.FileStream != null)
					{
						context.CloseFileReadStream(currentFileName, base.FileStream);
						base.FileStream = null;
					}
					context = null;
					if (fciHandle != null)
					{
						fciHandle.Dispose();
						fciHandle = null;
					}
				}
			}
		}

		internal override int CabOpenStreamEx(string path, int openFlags, int shareMode, out int err, IntPtr pv)
		{
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Expected O, but got Unknown
			if (base.CabNumbers.ContainsKey(path))
			{
				Stream stream = base.CabStream;
				if (stream == null)
				{
					short num = base.CabNumbers[path];
					currentFolderTotalBytes = 0L;
					stream = context.OpenArchiveWriteStream((int)num, path, true, (CompressionEngine)(object)base.CabEngine);
					if (stream == null)
					{
						throw new FileNotFoundException(string.Format(CultureInfo.InvariantCulture, "Cabinet {0} not provided.", new object[1] { num }));
					}
					currentArchiveName = path;
					currentArchiveTotalBytes = Math.Min(totalFolderBytesProcessedInCurrentCab, maxCabBytes);
					currentArchiveBytesProcessed = 0L;
					OnProgress((ArchiveProgressType)3);
					base.CabStream = stream;
				}
				path = "%%CAB%%";
			}
			else
			{
				if (path == "%%TEMP%%")
				{
					Stream stream2 = new MemoryStream();
					tempStreams.Add(stream2);
					int result = base.StreamHandles.AllocHandle(stream2);
					err = 0;
					return result;
				}
				if (path != "%%CAB%%")
				{
					path = Path.Combine(Path.GetTempPath(), path);
					Stream stream3 = new FileStream(path, FileMode.Open, FileAccess.ReadWrite);
					tempStreams.Add(stream3);
					stream3 = (Stream)new DuplicateStream(stream3);
					int result2 = base.StreamHandles.AllocHandle(stream3);
					err = 0;
					return result2;
				}
			}
			return base.CabOpenStreamEx(path, openFlags, shareMode, out err, pv);
		}

		internal override int CabWriteStreamEx(int streamHandle, IntPtr memory, int cb, out int err, IntPtr pv)
		{
			int num = base.CabWriteStreamEx(streamHandle, memory, cb, out err, pv);
			checked
			{
				if (num > 0 && err == 0 && DuplicateStream.OriginalStream(base.StreamHandles[streamHandle]) == DuplicateStream.OriginalStream(base.CabStream))
				{
					currentArchiveBytesProcessed += cb;
					if (currentArchiveBytesProcessed > currentArchiveTotalBytes)
					{
						currentArchiveBytesProcessed = currentArchiveTotalBytes;
					}
				}
				return num;
			}
		}

		internal override int CabCloseStreamEx(int streamHandle, out int err, IntPtr pv)
		{
			Stream stream = DuplicateStream.OriginalStream(base.StreamHandles[streamHandle]);
			checked
			{
				if (stream == DuplicateStream.OriginalStream(base.FileStream))
				{
					context.CloseFileReadStream(currentFileName, stream);
					base.FileStream = null;
					long num = currentFileTotalBytes - currentFileBytesProcessed;
					currentFileBytesProcessed += num;
					fileBytesProcessed += num;
					OnProgress((ArchiveProgressType)2);
					currentFileTotalBytes = 0L;
					currentFileBytesProcessed = 0L;
					currentFileName = null;
				}
				else if (stream == DuplicateStream.OriginalStream(base.CabStream))
				{
					if (stream.CanWrite)
					{
						stream.Flush();
					}
					currentArchiveBytesProcessed = currentArchiveTotalBytes;
					OnProgress((ArchiveProgressType)5);
					currentArchiveNumber++;
					totalArchives++;
					context.CloseArchiveWriteStream(unchecked((int)currentArchiveNumber), currentArchiveName, stream);
					currentArchiveName = base.NextCabinetName;
					currentArchiveBytesProcessed = (currentArchiveTotalBytes = 0L);
					totalFolderBytesProcessedInCurrentCab = 0L;
					base.CabStream = null;
				}
				else
				{
					stream.Close();
					tempStreams.Remove(stream);
				}
				return base.CabCloseStreamEx(streamHandle, out err, pv);
			}
		}

		protected override void Dispose(bool disposing)
		{
			try
			{
				if (disposing && fciHandle != null)
				{
					fciHandle.Dispose();
					fciHandle = null;
				}
			}
			finally
			{
				base.Dispose(disposing);
			}
		}

		private static NativeMethods.FCI.TCOMP GetCompressionType(CompressionLevel compLevel)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Invalid comparison between Unknown and I4
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Invalid comparison between Unknown and I4
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected I4, but got Unknown
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			if ((int)compLevel < 1)
			{
				return NativeMethods.FCI.TCOMP.TYPE_NONE;
			}
			if ((int)compLevel > 10)
			{
				compLevel = (CompressionLevel)10;
			}
			int num = checked(6 * (compLevel - 1)) / 9;
			return (NativeMethods.FCI.TCOMP)checked((ushort)(3 | (3840 + (num << 8))));
		}

		private void AddFile(string name, Stream stream, FileAttributes attributes, DateTime lastWriteTime, bool execute, CompressionLevel compLevel)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			base.FileStream = stream;
			fileAttributes = attributes & (FileAttributes.ReadOnly | FileAttributes.Hidden | FileAttributes.System | FileAttributes.Archive);
			fileLastWriteTime = lastWriteTime;
			currentFileName = name;
			NativeMethods.FCI.TCOMP compressionType = GetCompressionType(compLevel);
			IntPtr intPtr = IntPtr.Zero;
			try
			{
				Encoding encoding = Encoding.ASCII;
				if (Encoding.UTF8.GetByteCount(name) > name.Length)
				{
					encoding = Encoding.UTF8;
					fileAttributes |= FileAttributes.Normal;
				}
				byte[] bytes = encoding.GetBytes(name);
				intPtr = Marshal.AllocHGlobal(checked(bytes.Length + 1));
				Marshal.Copy(bytes, 0, intPtr, bytes.Length);
				Marshal.WriteByte(intPtr, bytes.Length, 0);
				base.Erf.Clear();
				NativeMethods.FCI.AddFile(fciHandle, string.Empty, intPtr, execute, fciGetNextCabinet, fciCreateStatus, fciGetOpenInfo, compressionType);
			}
			finally
			{
				if (intPtr != IntPtr.Zero)
				{
					Marshal.FreeHGlobal(intPtr);
				}
			}
			CheckError(extracting: false);
			base.FileStream = null;
			currentFileName = null;
		}

		private void FlushFolder()
		{
			base.Erf.Clear();
			NativeMethods.FCI.FlushFolder(fciHandle, fciGetNextCabinet, fciCreateStatus);
			CheckError(extracting: false);
		}

		private void FlushCabinet()
		{
			base.Erf.Clear();
			NativeMethods.FCI.FlushCabinet(fciHandle, fGetNextCab: false, fciGetNextCabinet, fciCreateStatus);
			CheckError(extracting: false);
		}

		private int CabGetOpenInfo(string path, out short date, out short time, out short attribs, out int err, IntPtr pv)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected O, but got Unknown
			CompressionEngine.DateTimeToDosDateAndTime(fileLastWriteTime, ref date, ref time);
			attribs = checked((short)fileAttributes);
			Stream stream = base.FileStream;
			base.FileStream = (Stream)new DuplicateStream(stream);
			int result = base.StreamHandles.AllocHandle(stream);
			err = 0;
			return result;
		}

		private int CabFilePlaced(IntPtr pccab, string filePath, long fileSize, int continuation, IntPtr pv)
		{
			return 0;
		}

		private int CabGetNextCabinet(IntPtr pccab, uint prevCabSize, IntPtr pv)
		{
			NativeMethods.FCI.CCAB cCAB = new NativeMethods.FCI.CCAB();
			Marshal.PtrToStructure(pccab, (object)cCAB);
			cCAB.szDisk = string.Empty;
			cCAB.szCab = context.GetArchiveName(cCAB.iCab);
			base.CabNumbers[cCAB.szCab] = checked((short)cCAB.iCab);
			base.NextCabinetName = cCAB.szCab;
			Marshal.StructureToPtr((object)cCAB, pccab, fDeleteOld: false);
			return 1;
		}

		private int CabCreateStatus(NativeMethods.FCI.STATUS typeStatus, uint cb1, uint cb2, IntPtr pv)
		{
			checked
			{
				switch (typeStatus)
				{
				case NativeMethods.FCI.STATUS.FILE:
					if (cb2 != 0 && currentFileBytesProcessed < currentFileTotalBytes)
					{
						if (currentFileBytesProcessed + cb2 > currentFileTotalBytes)
						{
							cb2 = (uint)currentFileTotalBytes - (uint)currentFileBytesProcessed;
						}
						currentFileBytesProcessed += cb2;
						fileBytesProcessed += cb2;
						OnProgress((ArchiveProgressType)1);
					}
					break;
				case NativeMethods.FCI.STATUS.FOLDER:
					if (cb1 == 0)
					{
						currentFolderTotalBytes = cb2 - totalFolderBytesProcessedInCurrentCab;
						totalFolderBytesProcessedInCurrentCab = cb2;
					}
					else if (currentFolderTotalBytes == 0L)
					{
						OnProgress((ArchiveProgressType)4);
					}
					break;
				}
				return 0;
			}
		}

		private int CabGetTempFile(IntPtr tempNamePtr, int tempNameSize, IntPtr pv)
		{
			string s = ((!UseTempFiles) ? "%%TEMP%%" : Path.GetFileName(Path.GetTempFileName()));
			byte[] bytes = Encoding.ASCII.GetBytes(s);
			if (bytes.Length >= tempNameSize)
			{
				return -1;
			}
			Marshal.Copy(bytes, 0, tempNamePtr, bytes.Length);
			Marshal.WriteByte(tempNamePtr, bytes.Length, 0);
			return 1;
		}

		private int CabDeleteFile(string path, out int err, IntPtr pv)
		{
			try
			{
				if (path != "%%TEMP%%")
				{
					path = Path.Combine(Path.GetTempPath(), path);
					File.Delete(path);
				}
			}
			catch (IOException)
			{
			}
			err = 0;
			return 1;
		}
	}
	public class CabEngine : CompressionEngine
	{
		private CabPacker packer;

		private CabUnpacker unpacker;

		private CabPacker Packer
		{
			get
			{
				if (packer == null)
				{
					packer = new CabPacker(this);
				}
				return packer;
			}
		}

		private CabUnpacker Unpacker
		{
			get
			{
				if (unpacker == null)
				{
					unpacker = new CabUnpacker(this);
				}
				return unpacker;
			}
		}

		protected override void Dispose(bool disposing)
		{
			if (disposing)
			{
				if (packer != null)
				{
					packer.Dispose();
					packer = null;
				}
				if (unpacker != null)
				{
					unpacker.Dispose();
					unpacker = null;
				}
			}
			((CompressionEngine)this).Dispose(disposing);
		}

		public override void Pack(IPackStreamContext streamContext, IEnumerable<string> files, long maxArchiveSize)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			Packer.CompressionLevel = ((CompressionEngine)this).CompressionLevel;
			Packer.UseTempFiles = ((CompressionEngine)this).UseTempFiles;
			Packer.Pack(streamContext, files, maxArchiveSize);
		}

		public override bool IsArchive(Stream stream)
		{
			return Unpacker.IsArchive(stream);
		}

		public override IList<ArchiveFileInfo> GetFileInfo(IUnpackStreamContext streamContext, Predicate<string> fileFilter)
		{
			return Unpacker.GetFileInfo(streamContext, fileFilter);
		}

		public override void Unpack(IUnpackStreamContext streamContext, Predicate<string> fileFilter)
		{
			Unpacker.Unpack(streamContext, fileFilter);
		}

		internal void ReportProgress(ArchiveProgressEventArgs e)
		{
			((CompressionEngine)this).OnProgress(e);
		}
	}
	internal abstract class CabWorker : IDisposable
	{
		internal const string CabStreamName = "%%CAB%%";

		private CabEngine cabEngine;

		private HandleManager<Stream> streamHandles;

		private Stream cabStream;

		private Stream fileStream;

		private NativeMethods.ERF erf;

		private GCHandle erfHandle;

		private IDictionary<string, short> cabNumbers;

		private string nextCabinetName;

		private bool suppressProgressEvents;

		private byte[] buf;

		protected string currentFileName;

		protected int currentFileNumber;

		protected int totalFiles;

		protected long currentFileBytesProcessed;

		protected long currentFileTotalBytes;

		protected short currentFolderNumber;

		protected long currentFolderTotalBytes;

		protected string currentArchiveName;

		protected short currentArchiveNumber;

		protected short totalArchives;

		protected long currentArchiveBytesProcessed;

		protected long currentArchiveTotalBytes;

		protected long fileBytesProcessed;

		protected long totalFileBytes;

		public CabEngine CabEngine => cabEngine;

		internal NativeMethods.ERF Erf => erf;

		internal GCHandle ErfHandle => erfHandle;

		internal HandleManager<Stream> StreamHandles => streamHandles;

		internal bool SuppressProgressEvents
		{
			get
			{
				return suppressProgressEvents;
			}
			set
			{
				suppressProgressEvents = value;
			}
		}

		internal IDictionary<string, short> CabNumbers => cabNumbers;

		internal string NextCabinetName
		{
			get
			{
				return nextCabinetName;
			}
			set
			{
				nextCabinetName = value;
			}
		}

		internal Stream CabStream
		{
			get
			{
				return cabStream;
			}
			set
			{
				cabStream = value;
			}
		}

		internal Stream FileStream
		{
			get
			{
				return fileStream;
			}
			set
			{
				fileStream = value;
			}
		}

		protected CabWorker(CabEngine cabEngine)
		{
			this.cabEngine = cabEngine;
			streamHandles = new HandleManager<Stream>();
			erf = new NativeMethods.ERF();
			erfHandle = GCHandle.Alloc(erf, GCHandleType.Pinned);
			cabNumbers = new Dictionary<string, short>(1);
			buf = new byte[32768];
		}

		~CabWorker()
		{
			Dispose(disposing: false);
		}

		public void Dispose()
		{
			Dispose(disposing: true);
			GC.SuppressFinalize(this);
		}

		protected void ResetProgressData()
		{
			currentFileName = null;
			currentFileNumber = 0;
			totalFiles = 0;
			currentFileBytesProcessed = 0L;
			currentFileTotalBytes = 0L;
			currentFolderNumber = 0;
			currentFolderTotalBytes = 0L;
			currentArchiveName = null;
			currentArchiveNumber = 0;
			totalArchives = 0;
			currentArchiveBytesProcessed = 0L;
			currentArchiveTotalBytes = 0L;
			fileBytesProcessed = 0L;
			totalFileBytes = 0L;
		}

		protected void OnProgress(ArchiveProgressType progressType)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Expected O, but got Unknown
			if (!suppressProgressEvents)
			{
				ArchiveProgressEventArgs e = new ArchiveProgressEventArgs(progressType, currentFileName, (currentFileNumber >= 0) ? currentFileNumber : 0, totalFiles, currentFileBytesProcessed, currentFileTotalBytes, currentArchiveName, (int)currentArchiveNumber, (int)totalArchives, currentArchiveBytesProcessed, currentArchiveTotalBytes, fileBytesProcessed, totalFileBytes);
				CabEngine.ReportProgress(e);
			}
		}

		internal IntPtr CabAllocMem(int byteCount)
		{
			return Marshal.AllocHGlobal((IntPtr)byteCount);
		}

		internal void CabFreeMem(IntPtr memPointer)
		{
			Marshal.FreeHGlobal(memPointer);
		}

		internal int CabOpenStream(string path, int openFlags, int shareMode)
		{
			int err;
			return CabOpenStreamEx(path, openFlags, shareMode, out err, IntPtr.Zero);
		}

		internal virtual int CabOpenStreamEx(string path, int openFlags, int shareMode, out int err, IntPtr pv)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			path = path.Trim();
			Stream stream = cabStream;
			cabStream = (Stream)new DuplicateStream(stream);
			int result = streamHandles.AllocHandle(stream);
			err = 0;
			return result;
		}

		internal int CabReadStream(int streamHandle, IntPtr memory, int cb)
		{
			int err;
			return CabReadStreamEx(streamHandle, memory, cb, out err, IntPtr.Zero);
		}

		internal virtual int CabReadStreamEx(int streamHandle, IntPtr memory, int cb, out int err, IntPtr pv)
		{
			Stream stream = streamHandles[streamHandle];
			int num = cb;
			if (num > buf.Length)
			{
				buf = new byte[num];
			}
			num = stream.Read(buf, 0, num);
			Marshal.Copy(buf, 0, memory, num);
			err = 0;
			return num;
		}

		internal int CabWriteStream(int streamHandle, IntPtr memory, int cb)
		{
			int err;
			return CabWriteStreamEx(streamHandle, memory, cb, out err, IntPtr.Zero);
		}

		internal virtual int CabWriteStreamEx(int streamHandle, IntPtr memory, int cb, out int err, IntPtr pv)
		{
			Stream stream = streamHandles[streamHandle];
			if (cb > buf.Length)
			{
				buf = new byte[cb];
			}
			Marshal.Copy(memory, buf, 0, cb);
			stream.Write(buf, 0, cb);
			err = 0;
			return cb;
		}

		internal int CabCloseStream(int streamHandle)
		{
			int err;
			return CabCloseStreamEx(streamHandle, out err, IntPtr.Zero);
		}

		internal virtual int CabCloseStreamEx(int streamHandle, out int err, IntPtr pv)
		{
			streamHandles.FreeHandle(streamHandle);
			err = 0;
			return 0;
		}

		internal int CabSeekStream(int streamHandle, int offset, int seekOrigin)
		{
			int err;
			return CabSeekStreamEx(streamHandle, offset, seekOrigin, out err, IntPtr.Zero);
		}

		internal virtual int CabSeekStreamEx(int streamHandle, int offset, int seekOrigin, out int err, IntPtr pv)
		{
			checked
			{
				offset = (int)streamHandles[streamHandle].Seek(offset, unchecked((SeekOrigin)seekOrigin));
				err = 0;
				return offset;
			}
		}

		protected virtual void Dispose(bool disposing)
		{
			if (disposing)
			{
				if (cabStream != null)
				{
					cabStream.Close();
					cabStream = null;
				}
				if (fileStream != null)
				{
					fileStream.Close();
					fileStream = null;
				}
			}
			if (erfHandle.IsAllocated)
			{
				erfHandle.Free();
			}
		}

		protected void CheckError(bool extracting)
		{
			if (Erf.Error)
			{
				throw new CabException(Erf.Oper, Erf.Type, CabException.GetErrorMessage(Erf.Oper, Erf.Type, extracting));
			}
		}
	}
	[Serializable]
	public class CabException : ArchiveException
	{
		private static ResourceManager errorResources;

		private int error;

		private int errorCode;

		public int Error => error;

		public int ErrorCode => errorCode;

		internal static ResourceManager ErrorResources
		{
			get
			{
				if (errorResources == null)
				{
					errorResources = new ResourceManager(typeof(CabException).Namespace + ".Errors", typeof(CabException).Assembly);
				}
				return errorResources;
			}
		}

		public CabException(string message, Exception innerException)
			: this(0, 0, message, innerException)
		{
		}

		public CabException(string message)
			: this(0, 0, message, null)
		{
		}

		public CabException()
			: this(0, 0, null, null)
		{
		}

		internal CabException(int error, int errorCode, string message, Exception innerException)
			: base(message, innerException)
		{
			this.error = error;
			this.errorCode = errorCode;
		}

		internal CabException(int error, int errorCode, string message)
			: this(error, errorCode, message, null)
		{
		}

		protected CabException(SerializationInfo info, StreamingContext context)
			: base(info, context)
		{
			if (info == null)
			{
				throw new ArgumentNullException("info");
			}
			error = info.GetInt32("cabError");
			errorCode = info.GetInt32("cabErrorCode");
		}

		[SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
		public override void GetObjectData(SerializationInfo info, StreamingContext context)
		{
			if (info == null)
			{
				throw new ArgumentNullException("info");
			}
			info.AddValue("cabError", error);
			info.AddValue("cabErrorCode", errorCode);
			((Exception)this).GetObjectData(info, context);
		}

		internal static string GetErrorMessage(int error, int errorCode, bool extracting)
		{
			int num = (extracting ? 2000 : 1000);
			string text = ErrorResources.GetString(checked(num + error).ToString(CultureInfo.InvariantCulture.NumberFormat), CultureInfo.CurrentCulture);
			if (text == null)
			{
				text = ErrorResources.GetString(num.ToString(CultureInfo.InvariantCulture.NumberFormat), CultureInfo.CurrentCulture);
			}
			if (errorCode != 0)
			{
				string @string = ErrorResources.GetString("1", CultureInfo.CurrentCulture);
				text = string.Format(CultureInfo.InvariantCulture, "{0} " + @string, new object[2] { text, errorCode });
			}
			return text;
		}
	}
	internal class CabUnpacker : CabWorker
	{
		private NativeMethods.FDI.Handle fdiHandle;

		private NativeMethods.FDI.PFNALLOC fdiAllocMemHandler;

		private NativeMethods.FDI.PFNFREE fdiFreeMemHandler;

		private NativeMethods.FDI.PFNOPEN fdiOpenStreamHandler;

		private NativeMethods.FDI.PFNREAD fdiReadStreamHandler;

		private NativeMethods.FDI.PFNWRITE fdiWriteStreamHandler;

		private NativeMethods.FDI.PFNCLOSE fdiCloseStreamHandler;

		private NativeMethods.FDI.PFNSEEK fdiSeekStreamHandler;

		private IUnpackStreamContext context;

		private List<ArchiveFileInfo> fileList;

		private int folderId;

		private Predicate<string> filter;

		[SecurityPermission(SecurityAction.Assert, UnmanagedCode = true)]
		public CabUnpacker(CabEngine cabEngine)
			: base(cabEngine)
		{
			fdiAllocMemHandler = base.CabAllocMem;
			fdiFreeMemHandler = base.CabFreeMem;
			fdiOpenStreamHandler = base.CabOpenStream;
			fdiReadStreamHandler = base.CabReadStream;
			fdiWriteStreamHandler = base.CabWriteStream;
			fdiCloseStreamHandler = base.CabCloseStream;
			fdiSeekStreamHandler = base.CabSeekStream;
			fdiHandle = NativeMethods.FDI.Create(fdiAllocMemHandler, fdiFreeMemHandler, fdiOpenStreamHandler, fdiReadStreamHandler, fdiWriteStreamHandler, fdiCloseStreamHandler, fdiSeekStreamHandler, 1, base.ErfHandle.AddrOfPinnedObject());
			if (base.Erf.Error)
			{
				int oper = base.Erf.Oper;
				int type = base.Erf.Type;
				base.ErfHandle.Free();
				throw new CabException(oper, type, CabException.GetErrorMessage(oper, type, extracting: true));
			}
		}

		[SecurityPermission(SecurityAction.Assert, UnmanagedCode = true)]
		public bool IsArchive(Stream stream)
		{
			if (stream == null)
			{
				throw new ArgumentNullException("stream");
			}
			lock (this)
			{
				short id;
				int cabFolderCount;
				int fileCount;
				return IsCabinet(stream, out id, out cabFolderCount, out fileCount);
			}
		}

		[SecurityPermission(SecurityAction.Assert, UnmanagedCode = true)]
		public IList<ArchiveFileInfo> GetFileInfo(IUnpackStreamContext streamContext, Predicate<string> fileFilter)
		{
			if (streamContext == null)
			{
				throw new ArgumentNullException("streamContext");
			}
			lock (this)
			{
				context = streamContext;
				filter = fileFilter;
				base.NextCabinetName = string.Empty;
				fileList = new List<ArchiveFileInfo>();
				bool flag = base.SuppressProgressEvents;
				base.SuppressProgressEvents = true;
				try
				{
					short num = 0;
					while (base.NextCabinetName != null)
					{
						base.Erf.Clear();
						base.CabNumbers[base.NextCabinetName] = num;
						NativeMethods.FDI.Copy(fdiHandle, base.NextCabinetName, string.Empty, 0, CabListNotify, IntPtr.Zero, IntPtr.Zero);
						CheckError(extracting: true);
						num = checked((short)(num + 1));
					}
					List<ArchiveFileInfo> list = fileList;
					fileList = null;
					return list.AsReadOnly();
				}
				finally
				{
					base.SuppressProgressEvents = flag;
					if (base.CabStream != null)
					{
						context.CloseArchiveReadStream((int)currentArchiveNumber, currentArchiveName, base.CabStream);
						base.CabStream = null;
					}
					context = null;
				}
			}
		}

		[SecurityPermission(SecurityAction.Assert, UnmanagedCode = true)]
		public void Unpack(IUnpackStreamContext streamContext, Predicate<string> fileFilter)
		{
			checked
			{
				lock (this)
				{
					IList<ArchiveFileInfo> fileInfo = GetFileInfo(streamContext, fileFilter);
					ResetProgressData();
					if (fileInfo != null)
					{
						totalFiles = fileInfo.Count;
						for (int i = 0; i < fileInfo.Count; i++)
						{
							totalFileBytes += fileInfo[i].Length;
							if (fileInfo[i].ArchiveNumber >= totalArchives)
							{
								int num = fileInfo[i].ArchiveNumber + 1;
								totalArchives = (short)num;
							}
						}
					}
					context = streamContext;
					fileList = null;
					base.NextCabinetName = string.Empty;
					folderId = -1;
					currentFileNumber = -1;
					try
					{
						short num2 = 0;
						while (base.NextCabinetName != null)
						{
							base.Erf.Clear();
							base.CabNumbers[base.NextCabinetName] = num2;
							NativeMethods.FDI.Copy(fdiHandle, base.NextCabinetName, string.Empty, 0, CabExtractNotify, IntPtr.Zero, IntPtr.Zero);
							CheckError(extracting: true);
							num2++;
						}
					}
					finally
					{
						if (base.CabStream != null)
						{
							context.CloseArchiveReadStream(unchecked((int)currentArchiveNumber), currentArchiveName, base.CabStream);
							base.CabStream = null;
						}
						if (base.FileStream != null)
						{
							context.CloseFileWriteStream(currentFileName, base.FileStream, FileAttributes.Normal, DateTime.Now);
							base.FileStream = null;
						}
						context = null;
					}
				}
			}
		}

		internal override int CabOpenStreamEx(string path, int openFlags, int shareMode, out int err, IntPtr pv)
		{
			if (base.CabNumbers.ContainsKey(path))
			{
				Stream stream = base.CabStream;
				if (stream == null)
				{
					short num = base.CabNumbers[path];
					stream = context.OpenArchiveReadStream((int)num, path, (CompressionEngine)(object)base.CabEngine);
					if (stream == null)
					{
						throw new FileNotFoundException(string.Format(CultureInfo.InvariantCulture, "Cabinet {0} not provided.", new object[1] { num }));
					}
					currentArchiveName = path;
					currentArchiveNumber = num;
					checked
					{
						if (totalArchives <= currentArchiveNumber)
						{
							int num2 = currentArchiveNumber + 1;
							totalArchives = (short)num2;
						}
						currentArchiveTotalBytes = stream.Length;
						currentArchiveBytesProcessed = 0L;
						if (folderId != -3)
						{
							OnProgress((ArchiveProgressType)3);
						}
						base.CabStream = stream;
					}
				}
				path = "%%CAB%%";
			}
			return base.CabOpenStreamEx(path, openFlags, shareMode, out err, pv);
		}

		internal override int CabReadStreamEx(int streamHandle, IntPtr memory, int cb, out int err, IntPtr pv)
		{
			int result = base.CabReadStreamEx(streamHandle, memory, cb, out err, pv);
			checked
			{
				if (err == 0 && base.CabStream != null && fileList == null && DuplicateStream.OriginalStream(base.StreamHandles[streamHandle]) == DuplicateStream.OriginalStream(base.CabStream))
				{
					currentArchiveBytesProcessed += cb;
					if (currentArchiveBytesProcessed > currentArchiveTotalBytes)
					{
						currentArchiveBytesProcessed = currentArchiveTotalBytes;
					}
				}
				return result;
			}
		}

		internal override int CabWriteStreamEx(int streamHandle, IntPtr memory, int cb, out int err, IntPtr pv)
		{
			int num = base.CabWriteStreamEx(streamHandle, memory, cb, out err, pv);
			checked
			{
				if (num > 0 && err == 0)
				{
					currentFileBytesProcessed += cb;
					fileBytesProcessed += cb;
					OnProgress((ArchiveProgressType)1);
				}
				return num;
			}
		}

		internal override int CabCloseStreamEx(int streamHandle, out int err, IntPtr pv)
		{
			Stream stream = DuplicateStream.OriginalStream(base.StreamHandles[streamHandle]);
			if (stream == DuplicateStream.OriginalStream(base.CabStream))
			{
				if (folderId != -3)
				{
					OnProgress((ArchiveProgressType)5);
				}
				context.CloseArchiveReadStream((int)currentArchiveNumber, currentArchiveName, stream);
				currentArchiveName = base.NextCabinetName;
				currentArchiveBytesProcessed = (currentArchiveTotalBytes = 0L);
				base.CabStream = null;
			}
			return base.CabCloseStreamEx(streamHandle, out err, pv);
		}

		protected override void Dispose(bool disposing)
		{
			try
			{
				if (disposing && fdiHandle != null)
				{
					fdiHandle.Dispose();
					fdiHandle = null;
				}
			}
			finally
			{
				base.Dispose(disposing);
			}
		}

		private static string GetFileName(NativeMethods.FDI.NOTIFICATION notification)
		{
			Encoding encoding = ((((uint)notification.attribs & 0x80u) != 0) ? Encoding.UTF8 : Encoding.Default);
			int i;
			for (i = 0; Marshal.ReadByte(notification.psz1, i) != 0; i = checked(i + 1))
			{
			}
			byte[] array = new byte[i];
			Marshal.Copy(notification.psz1, array, 0, i);
			string text = encoding.GetString(array);
			if (Path.IsPathRooted(text))
			{
				text = text.Replace(Path.VolumeSeparatorChar.ToString() ?? "", "");
			}
			return text;
		}

		private bool IsCabinet(Stream cabStream, out short id, out int cabFolderCount, out int fileCount)
		{
			int num = base.StreamHandles.AllocHandle(cabStream);
			try
			{
				base.Erf.Clear();
				NativeMethods.FDI.CABINFO pfdici;
				bool result = NativeMethods.FDI.IsCabinet(fdiHandle, num, out pfdici) != 0;
				if (base.Erf.Error)
				{
					if (base.Erf.Oper != 3)
					{
						throw new CabException(base.Erf.Oper, base.Erf.Type, CabException.GetErrorMessage(base.Erf.Oper, base.Erf.Type, extracting: true));
					}
					result = false;
				}
				id = pfdici.setID;
				cabFolderCount = pfdici.cFolders;
				fileCount = pfdici.cFiles;
				return result;
			}
			finally
			{
				base.StreamHandles.FreeHandle(num);
			}
		}

		private int CabListNotify(NativeMethods.FDI.NOTIFICATIONTYPE notificationType, NativeMethods.FDI.NOTIFICATION notification)
		{
			checked
			{
				switch (notificationType)
				{
				case NativeMethods.FDI.NOTIFICATIONTYPE.CABINET_INFO:
				{
					string text = Marshal.PtrToStringAnsi(notification.psz1);
					base.NextCabinetName = ((text.Length != 0) ? text : null);
					return 0;
				}
				case NativeMethods.FDI.NOTIFICATIONTYPE.PARTIAL_FILE:
					return 0;
				case NativeMethods.FDI.NOTIFICATIONTYPE.COPY_FILE:
				{
					string fileName = GetFileName(notification);
					if ((filter == null || filter(fileName)) && fileList != null)
					{
						FileAttributes fileAttributes = unchecked((FileAttributes)(notification.attribs & 0x27));
						if (fileAttributes == (FileAttributes)0)
						{
							fileAttributes = FileAttributes.Normal;
						}
						DateTime lastWriteTime = default(DateTime);
						CompressionEngine.DosDateAndTimeToDateTime(notification.date, notification.time, ref lastWriteTime);
						long length = notification.cb;
						CabFileInfo item = new CabFileInfo(fileName, notification.iFolder, notification.iCabinet, fileAttributes, lastWriteTime, length);
						fileList.Add((ArchiveFileInfo)(object)item);
						currentFileNumber = fileList.Count - 1;
						fileBytesProcessed += notification.cb;
					}
					totalFiles++;
					totalFileBytes += notification.cb;
					return 0;
				}
				default:
					return 0;
				}
			}
		}

		private int CabExtractNotify(NativeMethods.FDI.NOTIFICATIONTYPE notificationType, NativeMethods.FDI.NOTIFICATION notification)
		{
			switch (notificationType)
			{
			case NativeMethods.FDI.NOTIFICATIONTYPE.CABINET_INFO:
				if (base.NextCabinetName != null && base.NextCabinetName.StartsWith("?", StringComparison.Ordinal))
				{
					base.NextCabinetName = base.NextCabinetName.Substring(1);
				}
				else
				{
					string text = Marshal.PtrToStringAnsi(notification.psz1);
					base.NextCabinetName = ((text.Length != 0) ? text : null);
				}
				return 0;
			case NativeMethods.FDI.NOTIFICATIONTYPE.NEXT_CABINET:
			{
				string key = Marshal.PtrToStringAnsi(notification.psz1);
				base.CabNumbers[key] = notification.iCabinet;
				base.NextCabinetName = "?" + base.NextCabinetName;
				return 0;
			}
			case NativeMethods.FDI.NOTIFICATIONTYPE.COPY_FILE:
				return CabExtractCopyFile(notification);
			case NativeMethods.FDI.NOTIFICATIONTYPE.CLOSE_FILE_INFO:
				return CabExtractCloseFile(notification);
			default:
				return 0;
			}
		}

		private int CabExtractCopyFile(NativeMethods.FDI.NOTIFICATION notification)
		{
			checked
			{
				if (notification.iFolder != folderId)
				{
					if (notification.iFolder != -3 && folderId != -1)
					{
						currentFolderNumber++;
					}
					folderId = notification.iFolder;
				}
				string fileName = GetFileName(notification);
				if (filter == null || filter(fileName))
				{
					currentFileNumber++;
					currentFileName = fileName;
					currentFileBytesProcessed = 0L;
					currentFileTotalBytes = notification.cb;
					OnProgress((ArchiveProgressType)0);
					DateTime dateTime = default(DateTime);
					CompressionEngine.DosDateAndTimeToDateTime(notification.date, notification.time, ref dateTime);
					Stream stream = context.OpenFileWriteStream(fileName, unchecked((long)notification.cb), dateTime);
					if (stream != null)
					{
						base.FileStream = stream;
						return base.StreamHandles.AllocHandle(stream);
					}
					fileBytesProcessed += notification.cb;
					OnProgress((ArchiveProgressType)2);
					currentFileName = null;
				}
				return 0;
			}
		}

		private int CabExtractCloseFile(NativeMethods.FDI.NOTIFICATION notification)
		{
			Stream stream = base.StreamHandles[notification.hf];
			base.StreamHandles.FreeHandle(notification.hf);
			string fileName = GetFileName(notification);
			FileAttributes fileAttributes = (FileAttributes)(notification.attribs & 0x27);
			if (fileAttributes == (FileAttributes)0)
			{
				fileAttributes = FileAttributes.Normal;
			}
			DateTime dateTime = default(DateTime);
			CompressionEngine.DosDateAndTimeToDateTime(notification.date, notification.time, ref dateTime);
			stream.Flush();
			context.CloseFileWriteStream(fileName, stream, fileAttributes, dateTime);
			base.FileStream = null;
			checked
			{
				long num = currentFileTotalBytes - currentFileBytesProcessed;
				currentFileBytesProcessed += num;
				fileBytesProcessed += num;
				OnProgress((ArchiveProgressType)2);
				currentFileName = null;
				return 1;
			}
		}
	}
	[Serializable]
	public class CabFileInfo : ArchiveFileInfo
	{
		private int cabFolder;

		public CabInfo Cabinet => (CabInfo)(object)((ArchiveFileInfo)this).Archive;

		public string CabinetName => ((ArchiveFileInfo)this).ArchiveName;

		public int CabinetFolderNumber
		{
			get
			{
				if (cabFolder < 0)
				{
					((ArchiveFileInfo)this).Refresh();
				}
				return cabFolder;
			}
		}

		public CabFileInfo(CabInfo cabinetInfo, string filePath)
			: base((ArchiveInfo)(object)cabinetInfo, filePath)
		{
			if (cabinetInfo == null)
			{
				throw new ArgumentNullException("cabinetInfo");
			}
			cabFolder = -1;
		}

		internal CabFileInfo(string filePath, int cabFolder, int cabNumber, FileAttributes attributes, DateTime lastWriteTime, long length)
			: base(filePath, cabNumber, attributes, lastWriteTime, length)
		{
			this.cabFolder = cabFolder;
		}

		protected CabFileInfo(SerializationInfo info, StreamingContext context)
			: base(info, context)
		{
			cabFolder = info.GetInt32("cabFolder");
		}

		[SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
		public override void GetObjectData(SerializationInfo info, StreamingContext context)
		{
			((ArchiveFileInfo)this).GetObjectData(info, context);
			info.AddValue("cabFolder", cabFolder);
		}

		protected override void Refresh(ArchiveFileInfo newFileInfo)
		{
			((ArchiveFileInfo)this).Refresh(newFileInfo);
			cabFolder = ((CabFileInfo)(object)newFileInfo).cabFolder;
		}
	}
	[Serializable]
	public class CabInfo : ArchiveInfo
	{
		public CabInfo(string path)
			: base(path)
		{
		}

		protected CabInfo(SerializationInfo info, StreamingContext context)
			: base(info, context)
		{
		}

		protected override CompressionEngine CreateCompressionEngine()
		{
			return (CompressionEngine)(object)new CabEngine();
		}

		public IList<CabFileInfo> GetFiles()
		{
			IList<ArchiveFileInfo> files = ((ArchiveInfo)this).GetFiles();
			List<CabFileInfo> list = new List<CabFileInfo>(files.Count);
			foreach (CabFileInfo item in files)
			{
				list.Add(item);
			}
			return list.AsReadOnly();
		}

		public IList<CabFileInfo> GetFiles(string searchPattern)
		{
			IList<ArchiveFileInfo> files = ((ArchiveInfo)this).GetFiles(searchPattern);
			List<CabFileInfo> list = new List<CabFileInfo>(files.Count);
			foreach (CabFileInfo item in files)
			{
				list.Add(item);
			}
			return list.AsReadOnly();
		}
	}
	internal sealed class HandleManager<T> where T : class
	{
		private List<T> handles;

		public T this[int handle]
		{
			get
			{
				if (handle > 0 && handle <= handles.Count)
				{
					return handles[checked(handle - 1)];
				}
				return null;
			}
		}

		public HandleManager()
		{
			handles = new List<T>();
		}

		public int AllocHandle(T obj)
		{
			handles.Add(obj);
			return handles.Count;
		}

		public void FreeHandle(int handle)
		{
			if (handle > 0 && handle <= handles.Count)
			{
				handles[checked(handle - 1)] = null;
			}
		}
	}
	internal static class NativeMethods
	{
		internal static class FCI
		{
			[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
			internal delegate IntPtr PFNALLOC(int cb);

			[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
			internal delegate void PFNFREE(IntPtr pv);

			[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
			internal delegate int PFNOPEN(string path, int oflag, int pmode, out int err, IntPtr pv);

			[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
			internal delegate int PFNREAD(int fileHandle, IntPtr memory, int cb, out int err, IntPtr pv);

			[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
			internal delegate int PFNWRITE(int fileHandle, IntPtr memory, int cb, out int err, IntPtr pv);

			[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
			internal delegate int PFNCLOSE(int fileHandle, out int err, IntPtr pv);

			[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
			internal delegate int PFNSEEK(int fileHandle, int dist, int seekType, out int err, IntPtr pv);

			[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
			internal delegate int PFNDELETE(string path, out int err, IntPtr pv);

			[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
			internal delegate int PFNGETNEXTCABINET(IntPtr pccab, uint cbPrevCab, IntPtr pv);

			[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
			internal delegate int PFNFILEPLACED(IntPtr pccab, string path, long fileSize, int continuation, IntPtr pv);

			[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
			internal delegate int PFNGETOPENINFO(string path, out short date, out short time, out short pattribs, out int err, IntPtr pv);

			[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
			internal delegate int PFNSTATUS(STATUS typeStatus, uint cb1, uint cb2, IntPtr pv);

			[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
			internal delegate int PFNGETTEMPFILE(IntPtr tempNamePtr, int tempNameSize, IntPtr pv);

			internal enum ERROR
			{
				NONE,
				OPEN_SRC,
				READ_SRC,
				ALLOC_FAIL,
				TEMP_FILE,
				BAD_COMPR_TYPE,
				CAB_FILE,
				USER_ABORT,
				MCI_FAIL
			}

			internal enum TCOMP : ushort
			{
				MASK_TYPE = 15,
				TYPE_NONE = 0,
				TYPE_MSZIP = 1,
				TYPE_QUANTUM = 2,
				TYPE_LZX = 3,
				BAD = 15,
				MASK_LZX_WINDOW = 7936,
				LZX_WINDOW_LO = 3840,
				LZX_WINDOW_HI = 5376,
				SHIFT_LZX_WINDOW = 8,
				MASK_QUANTUM_LEVEL = 240,
				QUANTUM_LEVEL_LO = 16,
				QUANTUM_LEVEL_HI = 112,
				SHIFT_QUANTUM_LEVEL = 4,
				MASK_QUANTUM_MEM = 7936,
				QUANTUM_MEM_LO = 2560,
				QUANTUM_MEM_HI = 5376,
				SHIFT_QUANTUM_MEM = 8,
				MASK_RESERVED = 57344
			}

			internal enum STATUS : uint
			{
				FILE,
				FOLDER,
				CABINET
			}

			[StructLayout(LayoutKind.Sequential)]
			internal class CCAB
			{
				internal int cb = int.MaxValue;

				internal int cbFolderThresh = 2147450880;

				internal int cbReserveCFHeader;

				internal int cbReserveCFFolder;

				internal int cbReserveCFData;

				internal int iCab;

				internal int iDisk;

				internal int fFailOnIncompressible;

				internal short setID;

				[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
				internal string szDisk = string.Empty;

				[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
				internal string szCab = string.Empty;

				[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
				internal string szCabPath = string.Empty;
			}

			internal class Handle : SafeHandle
			{
				public override bool IsInvalid => handle == IntPtr.Zero;

				internal Handle()
					: base(IntPtr.Zero, ownsHandle: true)
				{
				}

				[SecurityPermission(SecurityAction.Assert, UnmanagedCode = true)]
				protected override bool ReleaseHandle()
				{
					return Destroy(handle);
				}
			}

			internal const int MIN_DISK = 32768;

			internal const int MAX_DISK = int.MaxValue;

			internal const int MAX_FOLDER = 2147450880;

			internal const int MAX_FILENAME = 256;

			internal const int MAX_CABINET_NAME = 256;

			internal const int MAX_CAB_PATH = 256;

			internal const int MAX_DISK_NAME = 256;

			internal const int CPU_80386 = 1;

			[DllImport("cabinet.dll", BestFitMapping = false, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, EntryPoint = "FCICreate", ThrowOnUnmappableChar = true)]
			internal static extern Handle Create(IntPtr perf, PFNFILEPLACED pfnfcifp, PFNALLOC pfna, PFNFREE pfnf, PFNOPEN pfnopen, PFNREAD pfnread, PFNWRITE pfnwrite, PFNCLOSE pfnclose, PFNSEEK pfnseek, PFNDELETE pfndelete, PFNGETTEMPFILE pfnfcigtf, [MarshalAs(UnmanagedType.LPStruct)] CCAB pccab, IntPtr pv);

			[DllImport("cabinet.dll", BestFitMapping = false, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, EntryPoint = "FCIAddFile", ThrowOnUnmappableChar = true)]
			internal static extern int AddFile(Handle hfci, string pszSourceFile, IntPtr pszFileName, [MarshalAs(UnmanagedType.Bool)] bool fExecute, PFNGETNEXTCABINET pfnfcignc, PFNSTATUS pfnfcis, PFNGETOPENINFO pfnfcigoi, TCOMP typeCompress);

			[DllImport("cabinet.dll", BestFitMapping = false, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, EntryPoint = "FCIFlushCabinet", ThrowOnUnmappableChar = true)]
			internal static extern int FlushCabinet(Handle hfci, [MarshalAs(UnmanagedType.Bool)] bool fGetNextCab, PFNGETNEXTCABINET pfnfcignc, PFNSTATUS pfnfcis);

			[DllImport("cabinet.dll", BestFitMapping = false, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, EntryPoint = "FCIFlushFolder", ThrowOnUnmappableChar = true)]
			internal static extern int FlushFolder(Handle hfci, PFNGETNEXTCABINET pfnfcignc, PFNSTATUS pfnfcis);

			[DllImport("cabinet.dll", BestFitMapping = false, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, EntryPoint = "FCIDestroy", ThrowOnUnmappableChar = true)]
			[SuppressUnmanagedCodeSecurity]
			[return: MarshalAs(UnmanagedType.Bool)]
			internal static extern bool Destroy(IntPtr hfci);
		}

		internal static class FDI
		{
			[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
			internal delegate IntPtr PFNALLOC(int cb);

			[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
			internal delegate void PFNFREE(IntPtr pv);

			[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
			internal delegate int PFNOPEN(string path, int oflag, int pmode);

			[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
			internal delegate int PFNREAD(int hf, IntPtr pv, int cb);

			[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
			internal delegate int PFNWRITE(int hf, IntPtr pv, int cb);

			[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
			internal delegate int PFNCLOSE(int hf);

			[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
			internal delegate int PFNSEEK(int hf, int dist, int seektype);

			[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
			internal delegate int PFNNOTIFY(NOTIFICATIONTYPE fdint, NOTIFICATION fdin);

			internal enum ERROR
			{
				NONE,
				CABINET_NOT_FOUND,
				NOT_A_CABINET,
				UNKNOWN_CABINET_VERSION,
				CORRUPT_CABINET,
				ALLOC_FAIL,
				BAD_COMPR_TYPE,
				MDI_FAIL,
				TARGET_FILE,
				RESERVE_MISMATCH,
				WRONG_CABINET,
				USER_ABORT
			}

			internal enum NOTIFICATIONTYPE
			{
				CABINET_INFO,
				PARTIAL_FILE,
				COPY_FILE,
				CLOSE_FILE_INFO,
				NEXT_CABINET,
				ENUMERATE
			}

			internal struct CABINFO
			{
				internal int cbCabinet;

				internal short cFolders;

				internal short cFiles;

				internal short setID;

				internal short iCabinet;

				internal int fReserve;

				internal int hasprev;

				internal int hasnext;
			}

			[StructLayout(LayoutKind.Sequential)]
			internal class NOTIFICATION
			{
				internal int cb;

				internal IntPtr psz1;

				internal IntPtr psz2;

				internal IntPtr psz3;

				internal IntPtr pv;

				internal IntPtr hf_ptr;

				internal short date;

				internal short time;

				internal short attribs;

				internal short setID;

				internal short iCabinet;

				internal short iFolder;

				internal int fdie;

				internal int hf => (int)hf_ptr;
			}

			internal class Handle : SafeHandle
			{
				public override bool IsInvalid => handle == IntPtr.Zero;

				internal Handle()
					: base(IntPtr.Zero, ownsHandle: true)
				{
				}

				protected override bool ReleaseHandle()
				{
					return Destroy(handle);
				}
			}

			internal const int MAX_DISK = int.MaxValue;

			internal const int MAX_FILENAME = 256;

			internal const int MAX_CABINET_NAME = 256;

			internal const int MAX_CAB_PATH = 256;

			internal const int MAX_DISK_NAME = 256;

			internal const int CPU_80386 = 1;

			[DllImport("cabinet.dll", BestFitMapping = false, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, EntryPoint = "FDICreate", ThrowOnUnmappableChar = true)]
			internal static extern Handle Create([MarshalAs(UnmanagedType.FunctionPtr)] PFNALLOC pfnalloc, [MarshalAs(UnmanagedType.FunctionPtr)] PFNFREE pfnfree, PFNOPEN pfnopen, PFNREAD pfnread, PFNWRITE pfnwrite, PFNCLOSE pfnclose, PFNSEEK pfnseek, int cpuType, IntPtr perf);

			[DllImport("cabinet.dll", BestFitMapping = false, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, EntryPoint = "FDICopy", ThrowOnUnmappableChar = true)]
			internal static extern int Copy(Handle hfdi, string pszCabinet, string pszCabPath, int flags, PFNNOTIFY pfnfdin, IntPtr pfnfdid, IntPtr pvUser);

			[DllImport("cabinet.dll", BestFitMapping = false, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, EntryPoint = "FDIDestroy", ThrowOnUnmappableChar = true)]
			[SuppressUnmanagedCodeSecurity]
			[return: MarshalAs(UnmanagedType.Bool)]
			internal static extern bool Destroy(IntPtr hfdi);

			[DllImport("cabinet.dll", BestFitMapping = false, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, EntryPoint = "FDIIsCabinet", ThrowOnUnmappableChar = true)]
			internal static extern int IsCabinet(Handle hfdi, int hf, out CABINFO pfdici);
		}

		[StructLayout(LayoutKind.Sequential)]
		internal class ERF
		{
			private int erfOper;

			private int erfType;

			private int fError;

			internal int Oper
			{
				get
				{
					return erfOper;
				}
				set
				{
					erfOper = value;
				}
			}

			internal int Type
			{
				get
				{
					return erfType;
				}
				set
				{
					erfType = value;
				}
			}

			internal bool Error
			{
				get
				{
					return fError != 0;
				}
				set
				{
					fError = (value ? 1 : 0);
				}
			}

			internal void Clear()
			{
				Oper = 0;
				Type = 0;
				Error = false;
			}
		}
	}
}

BepInEx/patchers/FixPluginTypesSerializationDebug/Microsoft.Deployment.Compression.dll

Decompiled 3 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Security;
using System.Security.Permissions;
using System.Text.RegularExpressions;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyDescription("Abstract base libraries for archive packing and unpacking")]
[assembly: CLSCompliant(true)]
[assembly: ComVisible(false)]
[assembly: AllowPartiallyTrustedCallers]
[assembly: AssemblyFileVersion("3.10.1.2213")]
[assembly: AssemblyCompany("Outercurve Foundation")]
[assembly: AssemblyCopyright("Copyright (c) Outercurve Foundation. All rights reserved.")]
[assembly: AssemblyProduct("Windows Installer XML Toolset")]
[assembly: AssemblyConfiguration("")]
[assembly: NeutralResourcesLanguage("en-US")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, Unrestricted = true)]
[assembly: AssemblyVersion("3.0.0.0")]
namespace Microsoft.Tools.WindowsInstallerXml
{
	internal static class WixDistribution
	{
		public static string NewsUrl = "http://wixtoolset.org/news/";

		public static string ShortProduct = "WiX Toolset";

		public static string SupportUrl = "http://wixtoolset.org/";

		public static string TelemetryUrlFormat = "http://wixtoolset.org/telemetry/v{0}/?r={1}";

		public static string ReplacePlaceholders(string original, Assembly assembly)
		{
			if ((object)assembly != null)
			{
				FileVersionInfo versionInfo = FileVersionInfo.GetVersionInfo(assembly.Location);
				original = original.Replace("[FileComments]", versionInfo.Comments);
				original = original.Replace("[FileCopyright]", versionInfo.LegalCopyright);
				original = original.Replace("[FileProductName]", versionInfo.ProductName);
				original = original.Replace("[FileVersion]", versionInfo.FileVersion);
				if (original.Contains("[FileVersionMajorMinor]"))
				{
					Version version = new Version(versionInfo.FileVersion);
					original = original.Replace("[FileVersionMajorMinor]", version.Major + "." + version.Minor);
				}
				if (TryGetAttribute<AssemblyCompanyAttribute>(assembly, out var attribute))
				{
					original = original.Replace("[AssemblyCompany]", attribute.Company);
				}
				if (TryGetAttribute<AssemblyCopyrightAttribute>(assembly, out var attribute2))
				{
					original = original.Replace("[AssemblyCopyright]", attribute2.Copyright);
				}
				if (TryGetAttribute<AssemblyDescriptionAttribute>(assembly, out var attribute3))
				{
					original = original.Replace("[AssemblyDescription]", attribute3.Description);
				}
				if (TryGetAttribute<AssemblyProductAttribute>(assembly, out var attribute4))
				{
					original = original.Replace("[AssemblyProduct]", attribute4.Product);
				}
				if (TryGetAttribute<AssemblyTitleAttribute>(assembly, out var attribute5))
				{
					original = original.Replace("[AssemblyTitle]", attribute5.Title);
				}
			}
			original = original.Replace("[NewsUrl]", NewsUrl);
			original = original.Replace("[ShortProduct]", ShortProduct);
			original = original.Replace("[SupportUrl]", SupportUrl);
			return original;
		}

		private static bool TryGetAttribute<T>(Assembly assembly, out T attribute) where T : Attribute
		{
			attribute = null;
			object[] customAttributes = assembly.GetCustomAttributes(typeof(T), inherit: false);
			if (customAttributes != null && customAttributes.Length != 0)
			{
				attribute = customAttributes[0] as T;
			}
			return attribute != null;
		}
	}
}
namespace Microsoft.Deployment.Compression
{
	[Serializable]
	public class ArchiveException : IOException
	{
		public ArchiveException(string message, Exception innerException)
			: base(message, innerException)
		{
		}

		public ArchiveException(string message)
			: this(message, null)
		{
		}

		public ArchiveException()
			: this(null, null)
		{
		}

		protected ArchiveException(SerializationInfo info, StreamingContext context)
			: base(info, context)
		{
		}
	}
	[Serializable]
	public abstract class ArchiveFileInfo : FileSystemInfo
	{
		private ArchiveInfo archiveInfo;

		private string name;

		private string path;

		private bool initialized;

		private bool exists;

		private int archiveNumber;

		private FileAttributes attributes;

		private DateTime lastWriteTime;

		private long length;

		public override string Name => name;

		public string Path => path;

		public override string FullName
		{
			get
			{
				string text = System.IO.Path.Combine(Path, Name);
				if (Archive != null)
				{
					text = System.IO.Path.Combine(ArchiveName, text);
				}
				return text;
			}
		}

		public ArchiveInfo Archive
		{
			get
			{
				return archiveInfo;
			}
			internal set
			{
				archiveInfo = value;
				OriginalPath = value?.FullName;
				FullPath = OriginalPath;
			}
		}

		public string ArchiveName
		{
			get
			{
				if (Archive == null)
				{
					return null;
				}
				return Archive.FullName;
			}
		}

		public int ArchiveNumber => archiveNumber;

		public override bool Exists
		{
			get
			{
				if (!initialized)
				{
					Refresh();
				}
				return exists;
			}
		}

		public long Length
		{
			get
			{
				if (!initialized)
				{
					Refresh();
				}
				return length;
			}
		}

		public new FileAttributes Attributes
		{
			get
			{
				if (!initialized)
				{
					Refresh();
				}
				return attributes;
			}
		}

		public new DateTime LastWriteTime
		{
			get
			{
				if (!initialized)
				{
					Refresh();
				}
				return lastWriteTime;
			}
		}

		protected ArchiveFileInfo(ArchiveInfo archiveInfo, string filePath)
		{
			if (filePath == null)
			{
				throw new ArgumentNullException("filePath");
			}
			Archive = archiveInfo;
			name = System.IO.Path.GetFileName(filePath);
			path = System.IO.Path.GetDirectoryName(filePath);
			attributes = FileAttributes.Normal;
			lastWriteTime = DateTime.MinValue;
		}

		protected ArchiveFileInfo(string filePath, int archiveNumber, FileAttributes attributes, DateTime lastWriteTime, long length)
			: this(null, filePath)
		{
			exists = true;
			this.archiveNumber = archiveNumber;
			this.attributes = attributes;
			this.lastWriteTime = lastWriteTime;
			this.length = length;
			initialized = true;
		}

		protected ArchiveFileInfo(SerializationInfo info, StreamingContext context)
			: base(info, context)
		{
			archiveInfo = (ArchiveInfo)info.GetValue("archiveInfo", typeof(ArchiveInfo));
			name = info.GetString("name");
			path = info.GetString("path");
			initialized = info.GetBoolean("initialized");
			exists = info.GetBoolean("exists");
			archiveNumber = info.GetInt32("archiveNumber");
			attributes = (FileAttributes)info.GetValue("attributes", typeof(FileAttributes));
			lastWriteTime = info.GetDateTime("lastWriteTime");
			length = info.GetInt64("length");
		}

		[SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
		public override void GetObjectData(SerializationInfo info, StreamingContext context)
		{
			base.GetObjectData(info, context);
			info.AddValue("archiveInfo", archiveInfo);
			info.AddValue("name", name);
			info.AddValue("path", path);
			info.AddValue("initialized", initialized);
			info.AddValue("exists", exists);
			info.AddValue("archiveNumber", archiveNumber);
			info.AddValue("attributes", attributes);
			info.AddValue("lastWriteTime", lastWriteTime);
			info.AddValue("length", length);
		}

		public override string ToString()
		{
			return FullName;
		}

		public override void Delete()
		{
			throw new NotSupportedException();
		}

		public new void Refresh()
		{
			base.Refresh();
			if (Archive != null)
			{
				string fileName = System.IO.Path.Combine(Path, Name);
				ArchiveFileInfo file = Archive.GetFile(fileName);
				if (file == null)
				{
					throw new FileNotFoundException("File not found in archive.", fileName);
				}
				Refresh(file);
			}
		}

		public void CopyTo(string destFileName)
		{
			CopyTo(destFileName, overwrite: false);
		}

		public void CopyTo(string destFileName, bool overwrite)
		{
			if (destFileName == null)
			{
				throw new ArgumentNullException("destFileName");
			}
			if (!overwrite && File.Exists(destFileName))
			{
				throw new IOException();
			}
			if (Archive == null)
			{
				throw new InvalidOperationException();
			}
			Archive.UnpackFile(System.IO.Path.Combine(Path, Name), destFileName);
		}

		public Stream OpenRead()
		{
			return Archive.OpenRead(System.IO.Path.Combine(Path, Name));
		}

		public StreamReader OpenText()
		{
			return Archive.OpenText(System.IO.Path.Combine(Path, Name));
		}

		protected virtual void Refresh(ArchiveFileInfo newFileInfo)
		{
			exists = newFileInfo.exists;
			length = newFileInfo.length;
			attributes = newFileInfo.attributes;
			lastWriteTime = newFileInfo.lastWriteTime;
		}
	}
	[Serializable]
	public abstract class ArchiveInfo : FileSystemInfo
	{
		public DirectoryInfo Directory => new DirectoryInfo(Path.GetDirectoryName(FullName));

		public string DirectoryName => Path.GetDirectoryName(FullName);

		public long Length => new FileInfo(FullName).Length;

		public override string Name => Path.GetFileName(FullName);

		public override bool Exists => File.Exists(FullName);

		protected ArchiveInfo(string path)
		{
			if (path == null)
			{
				throw new ArgumentNullException("path");
			}
			OriginalPath = path;
			FullPath = Path.GetFullPath(path);
		}

		protected ArchiveInfo(SerializationInfo info, StreamingContext context)
			: base(info, context)
		{
		}

		public override string ToString()
		{
			return FullName;
		}

		public override void Delete()
		{
			File.Delete(FullName);
		}

		public void CopyTo(string destFileName)
		{
			File.Copy(FullName, destFileName);
		}

		public void CopyTo(string destFileName, bool overwrite)
		{
			File.Copy(FullName, destFileName, overwrite);
		}

		public void MoveTo(string destFileName)
		{
			File.Move(FullName, destFileName);
			FullPath = Path.GetFullPath(destFileName);
		}

		public bool IsValid()
		{
			using Stream stream = File.OpenRead(FullName);
			using CompressionEngine compressionEngine = CreateCompressionEngine();
			return compressionEngine.FindArchiveOffset(stream) >= 0;
		}

		public IList<ArchiveFileInfo> GetFiles()
		{
			return InternalGetFiles(null);
		}

		public IList<ArchiveFileInfo> GetFiles(string searchPattern)
		{
			if (searchPattern == null)
			{
				throw new ArgumentNullException("searchPattern");
			}
			string pattern = string.Format(CultureInfo.InvariantCulture, "^{0}$", new object[1] { Regex.Escape(searchPattern).Replace("\\*", ".*").Replace("\\?", ".") });
			Regex regex = new Regex(pattern, RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
			return InternalGetFiles((string match) => regex.IsMatch(match));
		}

		public void Unpack(string destDirectory)
		{
			Unpack(destDirectory, null);
		}

		public void Unpack(string destDirectory, EventHandler<ArchiveProgressEventArgs> progressHandler)
		{
			using CompressionEngine compressionEngine = CreateCompressionEngine();
			compressionEngine.Progress += progressHandler;
			ArchiveFileStreamContext archiveFileStreamContext = new ArchiveFileStreamContext(FullName, destDirectory, null);
			archiveFileStreamContext.EnableOffsetOpen = true;
			compressionEngine.Unpack(archiveFileStreamContext, null);
		}

		public void UnpackFile(string fileName, string destFileName)
		{
			if (fileName == null)
			{
				throw new ArgumentNullException("fileName");
			}
			if (destFileName == null)
			{
				throw new ArgumentNullException("destFileName");
			}
			UnpackFiles(new string[1] { fileName }, null, new string[1] { destFileName });
		}

		public void UnpackFiles(IList<string> fileNames, string destDirectory, IList<string> destFileNames)
		{
			UnpackFiles(fileNames, destDirectory, destFileNames, null);
		}

		public void UnpackFiles(IList<string> fileNames, string destDirectory, IList<string> destFileNames, EventHandler<ArchiveProgressEventArgs> progressHandler)
		{
			if (fileNames == null)
			{
				throw new ArgumentNullException("fileNames");
			}
			if (destFileNames == null)
			{
				if (destDirectory == null)
				{
					throw new ArgumentNullException("destFileNames");
				}
				destFileNames = fileNames;
			}
			if (destFileNames.Count != fileNames.Count)
			{
				throw new ArgumentOutOfRangeException("destFileNames");
			}
			IDictionary<string, string> fileNames2 = CreateStringDictionary(fileNames, destFileNames);
			UnpackFileSet(fileNames2, destDirectory, progressHandler);
		}

		public void UnpackFileSet(IDictionary<string, string> fileNames, string destDirectory)
		{
			UnpackFileSet(fileNames, destDirectory, null);
		}

		public void UnpackFileSet(IDictionary<string, string> fileNames, string destDirectory, EventHandler<ArchiveProgressEventArgs> progressHandler)
		{
			if (fileNames == null)
			{
				throw new ArgumentNullException("fileNames");
			}
			using CompressionEngine compressionEngine = CreateCompressionEngine();
			compressionEngine.Progress += progressHandler;
			ArchiveFileStreamContext archiveFileStreamContext = new ArchiveFileStreamContext(FullName, destDirectory, fileNames);
			archiveFileStreamContext.EnableOffsetOpen = true;
			compressionEngine.Unpack(archiveFileStreamContext, (string match) => fileNames.ContainsKey(match));
		}

		public Stream OpenRead(string fileName)
		{
			Stream stream = File.OpenRead(FullName);
			CompressionEngine compressionEngine = CreateCompressionEngine();
			return new CargoStream(compressionEngine.Unpack(stream, fileName), stream, compressionEngine);
		}

		public StreamReader OpenText(string fileName)
		{
			return new StreamReader(OpenRead(fileName));
		}

		public void Pack(string sourceDirectory)
		{
			Pack(sourceDirectory, includeSubdirectories: false, CompressionLevel.Max, null);
		}

		public void Pack(string sourceDirectory, bool includeSubdirectories, CompressionLevel compLevel, EventHandler<ArchiveProgressEventArgs> progressHandler)
		{
			IList<string> relativeFilePathsInDirectoryTree = GetRelativeFilePathsInDirectoryTree(sourceDirectory, includeSubdirectories);
			PackFiles(sourceDirectory, relativeFilePathsInDirectoryTree, relativeFilePathsInDirectoryTree, compLevel, progressHandler);
		}

		public void PackFiles(string sourceDirectory, IList<string> sourceFileNames, IList<string> fileNames)
		{
			PackFiles(sourceDirectory, sourceFileNames, fileNames, CompressionLevel.Max, null);
		}

		public void PackFiles(string sourceDirectory, IList<string> sourceFileNames, IList<string> fileNames, CompressionLevel compLevel, EventHandler<ArchiveProgressEventArgs> progressHandler)
		{
			if (sourceFileNames == null)
			{
				throw new ArgumentNullException("sourceFileNames");
			}
			if (fileNames == null)
			{
				string[] array = new string[sourceFileNames.Count];
				for (int i = 0; i < sourceFileNames.Count; i = checked(i + 1))
				{
					array[i] = Path.GetFileName(sourceFileNames[i]);
				}
				fileNames = array;
			}
			else if (fileNames.Count != sourceFileNames.Count)
			{
				throw new ArgumentOutOfRangeException("fileNames");
			}
			using CompressionEngine compressionEngine = CreateCompressionEngine();
			compressionEngine.Progress += progressHandler;
			IDictionary<string, string> files = CreateStringDictionary(fileNames, sourceFileNames);
			ArchiveFileStreamContext archiveFileStreamContext = new ArchiveFileStreamContext(FullName, sourceDirectory, files);
			archiveFileStreamContext.EnableOffsetOpen = true;
			compressionEngine.CompressionLevel = compLevel;
			compressionEngine.Pack(archiveFileStreamContext, fileNames);
		}

		public void PackFileSet(string sourceDirectory, IDictionary<string, string> fileNames)
		{
			PackFileSet(sourceDirectory, fileNames, CompressionLevel.Max, null);
		}

		public void PackFileSet(string sourceDirectory, IDictionary<string, string> fileNames, CompressionLevel compLevel, EventHandler<ArchiveProgressEventArgs> progressHandler)
		{
			if (fileNames == null)
			{
				throw new ArgumentNullException("fileNames");
			}
			string[] array = new string[fileNames.Count];
			fileNames.Keys.CopyTo(array, 0);
			using CompressionEngine compressionEngine = CreateCompressionEngine();
			compressionEngine.Progress += progressHandler;
			ArchiveFileStreamContext archiveFileStreamContext = new ArchiveFileStreamContext(FullName, sourceDirectory, fileNames);
			archiveFileStreamContext.EnableOffsetOpen = true;
			compressionEngine.CompressionLevel = compLevel;
			compressionEngine.Pack(archiveFileStreamContext, array);
		}

		internal IList<string> GetRelativeFilePathsInDirectoryTree(string dir, bool includeSubdirectories)
		{
			IList<string> list = new List<string>();
			RecursiveGetRelativeFilePathsInDirectoryTree(dir, string.Empty, includeSubdirectories, list);
			return list;
		}

		internal ArchiveFileInfo GetFile(string path)
		{
			IList<ArchiveFileInfo> list = InternalGetFiles((string match) => string.Compare(match, path, ignoreCase: true, CultureInfo.InvariantCulture) == 0);
			if (list == null || list.Count <= 0)
			{
				return null;
			}
			return list[0];
		}

		protected abstract CompressionEngine CreateCompressionEngine();

		private static IDictionary<string, string> CreateStringDictionary(IList<string> keys, IList<string> values)
		{
			IDictionary<string, string> dictionary = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
			for (int i = 0; i < keys.Count; i = checked(i + 1))
			{
				dictionary.Add(keys[i], values[i]);
			}
			return dictionary;
		}

		private void RecursiveGetRelativeFilePathsInDirectoryTree(string dir, string relativeDir, bool includeSubdirectories, IList<string> fileList)
		{
			string[] files = System.IO.Directory.GetFiles(dir);
			for (int i = 0; i < files.Length; i++)
			{
				string fileName = Path.GetFileName(files[i]);
				fileList.Add(Path.Combine(relativeDir, fileName));
			}
			if (includeSubdirectories)
			{
				files = System.IO.Directory.GetDirectories(dir);
				for (int i = 0; i < files.Length; i++)
				{
					string fileName2 = Path.GetFileName(files[i]);
					RecursiveGetRelativeFilePathsInDirectoryTree(Path.Combine(dir, fileName2), Path.Combine(relativeDir, fileName2), includeSubdirectories, fileList);
				}
			}
		}

		private IList<ArchiveFileInfo> InternalGetFiles(Predicate<string> fileFilter)
		{
			using CompressionEngine compressionEngine = CreateCompressionEngine();
			ArchiveFileStreamContext archiveFileStreamContext = new ArchiveFileStreamContext(FullName, null, null);
			archiveFileStreamContext.EnableOffsetOpen = true;
			IList<ArchiveFileInfo> fileInfo = compressionEngine.GetFileInfo(archiveFileStreamContext, fileFilter);
			for (int i = 0; i < fileInfo.Count; i = checked(i + 1))
			{
				fileInfo[i].Archive = this;
			}
			return fileInfo;
		}
	}
	public class ArchiveProgressEventArgs : EventArgs
	{
		private ArchiveProgressType progressType;

		private string currentFileName;

		private int currentFileNumber;

		private int totalFiles;

		private long currentFileBytesProcessed;

		private long currentFileTotalBytes;

		private string currentArchiveName;

		private short currentArchiveNumber;

		private short totalArchives;

		private long currentArchiveBytesProcessed;

		private long currentArchiveTotalBytes;

		private long fileBytesProcessed;

		private long totalFileBytes;

		public ArchiveProgressType ProgressType => progressType;

		public string CurrentFileName => currentFileName;

		public int CurrentFileNumber => currentFileNumber;

		public int TotalFiles => totalFiles;

		public long CurrentFileBytesProcessed => currentFileBytesProcessed;

		public long CurrentFileTotalBytes => currentFileTotalBytes;

		public string CurrentArchiveName => currentArchiveName;

		public int CurrentArchiveNumber => currentArchiveNumber;

		public int TotalArchives => totalArchives;

		public long CurrentArchiveBytesProcessed => currentArchiveBytesProcessed;

		public long CurrentArchiveTotalBytes => currentArchiveTotalBytes;

		public long FileBytesProcessed => fileBytesProcessed;

		public long TotalFileBytes => totalFileBytes;

		public ArchiveProgressEventArgs(ArchiveProgressType progressType, string currentFileName, int currentFileNumber, int totalFiles, long currentFileBytesProcessed, long currentFileTotalBytes, string currentArchiveName, int currentArchiveNumber, int totalArchives, long currentArchiveBytesProcessed, long currentArchiveTotalBytes, long fileBytesProcessed, long totalFileBytes)
		{
			this.progressType = progressType;
			this.currentFileName = currentFileName;
			this.currentFileNumber = currentFileNumber;
			this.totalFiles = totalFiles;
			this.currentFileBytesProcessed = currentFileBytesProcessed;
			this.currentFileTotalBytes = currentFileTotalBytes;
			this.currentArchiveName = currentArchiveName;
			checked
			{
				this.currentArchiveNumber = (short)currentArchiveNumber;
				this.totalArchives = (short)totalArchives;
				this.currentArchiveBytesProcessed = currentArchiveBytesProcessed;
				this.currentArchiveTotalBytes = currentArchiveTotalBytes;
				this.fileBytesProcessed = fileBytesProcessed;
				this.totalFileBytes = totalFileBytes;
			}
		}
	}
	public enum ArchiveProgressType
	{
		StartFile,
		PartialFile,
		FinishFile,
		StartArchive,
		PartialArchive,
		FinishArchive
	}
	public class ArchiveFileStreamContext : IPackStreamContext, IUnpackStreamContext
	{
		private IList<string> archiveFiles;

		private string directory;

		private IDictionary<string, string> files;

		private bool extractOnlyNewerFiles;

		private bool enableOffsetOpen;

		public IList<string> ArchiveFiles => archiveFiles;

		public string Directory => directory;

		public IDictionary<string, string> Files => files;

		public bool ExtractOnlyNewerFiles
		{
			get
			{
				return extractOnlyNewerFiles;
			}
			set
			{
				extractOnlyNewerFiles = value;
			}
		}

		public bool EnableOffsetOpen
		{
			get
			{
				return enableOffsetOpen;
			}
			set
			{
				enableOffsetOpen = value;
			}
		}

		public ArchiveFileStreamContext(string archiveFile)
			: this(archiveFile, null, null)
		{
		}

		public ArchiveFileStreamContext(string archiveFile, string directory, IDictionary<string, string> files)
			: this(new string[1] { archiveFile }, directory, files)
		{
			if (archiveFile == null)
			{
				throw new ArgumentNullException("archiveFile");
			}
		}

		public ArchiveFileStreamContext(IList<string> archiveFiles, string directory, IDictionary<string, string> files)
		{
			if (archiveFiles == null || archiveFiles.Count == 0)
			{
				throw new ArgumentNullException("archiveFiles");
			}
			this.archiveFiles = archiveFiles;
			this.directory = directory;
			this.files = files;
		}

		public virtual string GetArchiveName(int archiveNumber)
		{
			if (archiveNumber < archiveFiles.Count)
			{
				return Path.GetFileName(archiveFiles[archiveNumber]);
			}
			return string.Empty;
		}

		public virtual Stream OpenArchiveWriteStream(int archiveNumber, string archiveName, bool truncate, CompressionEngine compressionEngine)
		{
			if (archiveNumber >= archiveFiles.Count)
			{
				return null;
			}
			if (string.IsNullOrEmpty(archiveName))
			{
				throw new ArgumentNullException("archiveName");
			}
			Stream stream = File.Open(Path.Combine(Path.GetDirectoryName(archiveFiles[0]), archiveName), truncate ? FileMode.OpenOrCreate : FileMode.Open, FileAccess.ReadWrite);
			if (enableOffsetOpen)
			{
				long num = compressionEngine.FindArchiveOffset(new DuplicateStream(stream));
				if (num < 0)
				{
					num = stream.Length;
				}
				if (num > 0)
				{
					stream = new OffsetStream(stream, num);
				}
				stream.Seek(0L, SeekOrigin.Begin);
			}
			if (truncate)
			{
				stream.SetLength(0L);
			}
			return stream;
		}

		public virtual void CloseArchiveWriteStream(int archiveNumber, string archiveName, Stream stream)
		{
			if (stream == null)
			{
				return;
			}
			stream.Close();
			if (!(stream is FileStream fileStream))
			{
				return;
			}
			string name = fileStream.Name;
			if (!string.IsNullOrEmpty(archiveName) && archiveName != Path.GetFileName(name))
			{
				string text = Path.Combine(Path.GetDirectoryName(archiveFiles[0]), archiveName);
				if (File.Exists(text))
				{
					File.Delete(text);
				}
				File.Move(name, text);
			}
		}

		public virtual Stream OpenFileReadStream(string path, out FileAttributes attributes, out DateTime lastWriteTime)
		{
			string text = TranslateFilePath(path);
			if (text == null)
			{
				attributes = FileAttributes.Normal;
				lastWriteTime = DateTime.Now;
				return null;
			}
			attributes = File.GetAttributes(text);
			lastWriteTime = File.GetLastWriteTime(text);
			return File.Open(text, FileMode.Open, FileAccess.Read, FileShare.Read);
		}

		public virtual void CloseFileReadStream(string path, Stream stream)
		{
			stream?.Close();
		}

		public virtual object GetOption(string optionName, object[] parameters)
		{
			return null;
		}

		public virtual Stream OpenArchiveReadStream(int archiveNumber, string archiveName, CompressionEngine compressionEngine)
		{
			if (archiveNumber >= archiveFiles.Count)
			{
				return null;
			}
			Stream stream = File.Open(archiveFiles[archiveNumber], FileMode.Open, FileAccess.Read, FileShare.Read);
			if (enableOffsetOpen)
			{
				long num = compressionEngine.FindArchiveOffset(new DuplicateStream(stream));
				if (num > 0)
				{
					stream = new OffsetStream(stream, num);
				}
				else
				{
					stream.Seek(0L, SeekOrigin.Begin);
				}
			}
			return stream;
		}

		public virtual void CloseArchiveReadStream(int archiveNumber, string archiveName, Stream stream)
		{
			stream?.Close();
		}

		public virtual Stream OpenFileWriteStream(string path, long fileSize, DateTime lastWriteTime)
		{
			string text = TranslateFilePath(path);
			if (text == null)
			{
				return null;
			}
			FileInfo fileInfo = new FileInfo(text);
			if (fileInfo.Exists)
			{
				if (extractOnlyNewerFiles && lastWriteTime != DateTime.MinValue && fileInfo.LastWriteTime >= lastWriteTime)
				{
					return null;
				}
				FileAttributes fileAttributes = FileAttributes.ReadOnly | FileAttributes.Hidden | FileAttributes.System;
				if ((fileInfo.Attributes & fileAttributes) != 0)
				{
					fileInfo.Attributes &= ~fileAttributes;
				}
			}
			if (!fileInfo.Directory.Exists)
			{
				fileInfo.Directory.Create();
			}
			return File.Open(text, FileMode.Create, FileAccess.Write, FileShare.None);
		}

		public virtual void CloseFileWriteStream(string path, Stream stream, FileAttributes attributes, DateTime lastWriteTime)
		{
			stream?.Close();
			string text = TranslateFilePath(path);
			if (text == null)
			{
				return;
			}
			FileInfo fileInfo = new FileInfo(text);
			if (lastWriteTime != DateTime.MinValue)
			{
				try
				{
					fileInfo.LastWriteTime = lastWriteTime;
				}
				catch (ArgumentException)
				{
				}
				catch (IOException)
				{
				}
			}
			try
			{
				fileInfo.Attributes = attributes;
			}
			catch (IOException)
			{
			}
		}

		private string TranslateFilePath(string path)
		{
			string text = ((files == null) ? path : files[path]);
			if (text != null && directory != null)
			{
				text = Path.Combine(directory, text);
			}
			return text;
		}
	}
	public class BasicUnpackStreamContext : IUnpackStreamContext
	{
		private Stream archiveStream;

		private Stream fileStream;

		public Stream FileStream => fileStream;

		public BasicUnpackStreamContext(Stream archiveStream)
		{
			this.archiveStream = archiveStream;
		}

		public Stream OpenArchiveReadStream(int archiveNumber, string archiveName, CompressionEngine compressionEngine)
		{
			return new DuplicateStream(archiveStream);
		}

		public void CloseArchiveReadStream(int archiveNumber, string archiveName, Stream stream)
		{
		}

		public Stream OpenFileWriteStream(string path, long fileSize, DateTime lastWriteTime)
		{
			fileStream = new MemoryStream(new byte[fileSize], 0, checked((int)fileSize), writable: true, publiclyVisible: true);
			return fileStream;
		}

		public void CloseFileWriteStream(string path, Stream stream, FileAttributes attributes, DateTime lastWriteTime)
		{
		}
	}
	public abstract class CompressionEngine : IDisposable
	{
		private CompressionLevel compressionLevel;

		private bool dontUseTempFiles;

		public bool UseTempFiles
		{
			get
			{
				return !dontUseTempFiles;
			}
			set
			{
				dontUseTempFiles = !value;
			}
		}

		public CompressionLevel CompressionLevel
		{
			get
			{
				return compressionLevel;
			}
			set
			{
				compressionLevel = value;
			}
		}

		public event EventHandler<ArchiveProgressEventArgs> Progress;

		protected CompressionEngine()
		{
			compressionLevel = CompressionLevel.Normal;
		}

		~CompressionEngine()
		{
			Dispose(disposing: false);
		}

		public void Dispose()
		{
			Dispose(disposing: true);
			GC.SuppressFinalize(this);
		}

		public void Pack(IPackStreamContext streamContext, IEnumerable<string> files)
		{
			if (files == null)
			{
				throw new ArgumentNullException("files");
			}
			Pack(streamContext, files, 0L);
		}

		public abstract void Pack(IPackStreamContext streamContext, IEnumerable<string> files, long maxArchiveSize);

		public abstract bool IsArchive(Stream stream);

		public virtual long FindArchiveOffset(Stream stream)
		{
			if (stream == null)
			{
				throw new ArgumentNullException("stream");
			}
			long num = 4L;
			long length = stream.Length;
			checked
			{
				for (long num2 = 0L; num2 <= length - num; num2 += num)
				{
					stream.Seek(num2, SeekOrigin.Begin);
					if (IsArchive(stream))
					{
						return num2;
					}
				}
				return -1L;
			}
		}

		public IList<ArchiveFileInfo> GetFileInfo(Stream stream)
		{
			return GetFileInfo(new BasicUnpackStreamContext(stream), null);
		}

		public abstract IList<ArchiveFileInfo> GetFileInfo(IUnpackStreamContext streamContext, Predicate<string> fileFilter);

		public IList<string> GetFiles(Stream stream)
		{
			return GetFiles(new BasicUnpackStreamContext(stream), null);
		}

		public IList<string> GetFiles(IUnpackStreamContext streamContext, Predicate<string> fileFilter)
		{
			if (streamContext == null)
			{
				throw new ArgumentNullException("streamContext");
			}
			IList<ArchiveFileInfo> fileInfo = GetFileInfo(streamContext, fileFilter);
			IList<string> list = new List<string>(fileInfo.Count);
			for (int i = 0; i < fileInfo.Count; i = checked(i + 1))
			{
				list.Add(fileInfo[i].Name);
			}
			return list;
		}

		public Stream Unpack(Stream stream, string path)
		{
			if (stream == null)
			{
				throw new ArgumentNullException("stream");
			}
			if (path == null)
			{
				throw new ArgumentNullException("path");
			}
			BasicUnpackStreamContext basicUnpackStreamContext = new BasicUnpackStreamContext(stream);
			Unpack(basicUnpackStreamContext, (string match) => string.Compare(match, path, ignoreCase: true, CultureInfo.InvariantCulture) == 0);
			Stream fileStream = basicUnpackStreamContext.FileStream;
			if (fileStream != null)
			{
				fileStream.Position = 0L;
			}
			return fileStream;
		}

		public abstract void Unpack(IUnpackStreamContext streamContext, Predicate<string> fileFilter);

		protected void OnProgress(ArchiveProgressEventArgs e)
		{
			if (this.Progress != null)
			{
				this.Progress(this, e);
			}
		}

		protected virtual void Dispose(bool disposing)
		{
		}

		public static void DosDateAndTimeToDateTime(short dosDate, short dosTime, out DateTime dateTime)
		{
			if (dosDate == 0 && dosTime == 0)
			{
				dateTime = DateTime.MinValue;
				return;
			}
			SafeNativeMethods.DosDateTimeToFileTime(dosDate, dosTime, out var fileTime);
			dateTime = DateTime.FromFileTimeUtc(fileTime);
			dateTime = new DateTime(dateTime.Ticks, DateTimeKind.Local);
		}

		public static void DateTimeToDosDateAndTime(DateTime dateTime, out short dosDate, out short dosTime)
		{
			dateTime = new DateTime(dateTime.Ticks, DateTimeKind.Utc);
			long fileTime = dateTime.ToFileTimeUtc();
			SafeNativeMethods.FileTimeToDosDateTime(ref fileTime, out dosDate, out dosTime);
		}
	}
	public enum CompressionLevel
	{
		None = 0,
		Min = 1,
		Normal = 6,
		Max = 10
	}
	public class CargoStream : Stream
	{
		private Stream source;

		private List<IDisposable> cargo;

		public Stream Source => source;

		public IList<IDisposable> Cargo => cargo;

		public override bool CanRead => source.CanRead;

		public override bool CanWrite => source.CanWrite;

		public override bool CanSeek => source.CanSeek;

		public override long Length => source.Length;

		public override long Position
		{
			get
			{
				return source.Position;
			}
			set
			{
				source.Position = value;
			}
		}

		public CargoStream(Stream source, params IDisposable[] cargo)
		{
			if (source == null)
			{
				throw new ArgumentNullException("source");
			}
			this.source = source;
			this.cargo = new List<IDisposable>(cargo);
		}

		public override void Flush()
		{
			source.Flush();
		}

		public override void SetLength(long value)
		{
			source.SetLength(value);
		}

		public override void Close()
		{
			source.Close();
			foreach (IDisposable item in cargo)
			{
				item.Dispose();
			}
		}

		public override int Read(byte[] buffer, int offset, int count)
		{
			return source.Read(buffer, offset, count);
		}

		public override void Write(byte[] buffer, int offset, int count)
		{
			source.Write(buffer, offset, count);
		}

		public override long Seek(long offset, SeekOrigin origin)
		{
			return source.Seek(offset, origin);
		}
	}
	public class DuplicateStream : Stream
	{
		private Stream source;

		private long position;

		public Stream Source => source;

		public override bool CanRead => source.CanRead;

		public override bool CanWrite => source.CanWrite;

		public override bool CanSeek => source.CanSeek;

		public override long Length => source.Length;

		public override long Position
		{
			get
			{
				return position;
			}
			set
			{
				position = value;
			}
		}

		public DuplicateStream(Stream source)
		{
			if (source == null)
			{
				throw new ArgumentNullException("source");
			}
			this.source = OriginalStream(source);
		}

		public static Stream OriginalStream(Stream stream)
		{
			if (!(stream is DuplicateStream duplicateStream))
			{
				return stream;
			}
			return duplicateStream.Source;
		}

		public override void Flush()
		{
			source.Flush();
		}

		public override void SetLength(long value)
		{
			source.SetLength(value);
		}

		public override void Close()
		{
			source.Close();
		}

		public override int Read(byte[] buffer, int offset, int count)
		{
			long num = source.Position;
			source.Position = position;
			int result = source.Read(buffer, offset, count);
			position = source.Position;
			source.Position = num;
			return result;
		}

		public override void Write(byte[] buffer, int offset, int count)
		{
			long num = source.Position;
			source.Position = position;
			source.Write(buffer, offset, count);
			position = source.Position;
			source.Position = num;
		}

		public override long Seek(long offset, SeekOrigin origin)
		{
			long num = 0L;
			switch (origin)
			{
			case SeekOrigin.Current:
				num = position;
				break;
			case SeekOrigin.End:
				num = Length;
				break;
			}
			position = checked(num + offset);
			return position;
		}
	}
	public interface IPackStreamContext
	{
		string GetArchiveName(int archiveNumber);

		Stream OpenArchiveWriteStream(int archiveNumber, string archiveName, bool truncate, CompressionEngine compressionEngine);

		void CloseArchiveWriteStream(int archiveNumber, string archiveName, Stream stream);

		Stream OpenFileReadStream(string path, out FileAttributes attributes, out DateTime lastWriteTime);

		void CloseFileReadStream(string path, Stream stream);

		object GetOption(string optionName, object[] parameters);
	}
	public interface IUnpackStreamContext
	{
		Stream OpenArchiveReadStream(int archiveNumber, string archiveName, CompressionEngine compressionEngine);

		void CloseArchiveReadStream(int archiveNumber, string archiveName, Stream stream);

		Stream OpenFileWriteStream(string path, long fileSize, DateTime lastWriteTime);

		void CloseFileWriteStream(string path, Stream stream, FileAttributes attributes, DateTime lastWriteTime);
	}
	public class OffsetStream : Stream
	{
		private Stream source;

		private long sourceOffset;

		public Stream Source => source;

		public long Offset => sourceOffset;

		public override bool CanRead => source.CanRead;

		public override bool CanWrite => source.CanWrite;

		public override bool CanSeek => source.CanSeek;

		public override long Length => checked(source.Length - sourceOffset);

		public override long Position
		{
			get
			{
				return checked(source.Position - sourceOffset);
			}
			set
			{
				source.Position = checked(value + sourceOffset);
			}
		}

		public OffsetStream(Stream source, long offset)
		{
			if (source == null)
			{
				throw new ArgumentNullException("source");
			}
			this.source = source;
			sourceOffset = offset;
			this.source.Seek(sourceOffset, SeekOrigin.Current);
		}

		public override int Read(byte[] buffer, int offset, int count)
		{
			return source.Read(buffer, offset, count);
		}

		public override void Write(byte[] buffer, int offset, int count)
		{
			source.Write(buffer, offset, count);
		}

		public override int ReadByte()
		{
			return source.ReadByte();
		}

		public override void WriteByte(byte value)
		{
			source.WriteByte(value);
		}

		public override void Flush()
		{
			source.Flush();
		}

		public override long Seek(long offset, SeekOrigin origin)
		{
			return checked(source.Seek(offset + ((origin == SeekOrigin.Begin) ? sourceOffset : 0), origin) - sourceOffset);
		}

		public override void SetLength(long value)
		{
			source.SetLength(checked(value + sourceOffset));
		}

		public override void Close()
		{
			source.Close();
		}
	}
	[SuppressUnmanagedCodeSecurity]
	internal static class SafeNativeMethods
	{
		[DllImport("kernel32.dll", SetLastError = true)]
		[return: MarshalAs(UnmanagedType.Bool)]
		internal static extern bool DosDateTimeToFileTime(short wFatDate, short wFatTime, out long fileTime);

		[DllImport("kernel32.dll", SetLastError = true)]
		[return: MarshalAs(UnmanagedType.Bool)]
		internal static extern bool FileTimeToDosDateTime(ref long fileTime, out short wFatDate, out short wFatTime);
	}
}