Decompiled source of CompressSave v1.3.6

plugins/CompressSave.dll

Decompiled 11 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Threading;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using CompressSave.Wrapper;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using MonoMod.Utils;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("CompressSave")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("DSP MOD - CompressSave")]
[assembly: AssemblyFileVersion("1.3.6.0")]
[assembly: AssemblyInformationalVersion("1.3.6+aae3d7df4c74cff3c07d9925034f833f5c701f1a")]
[assembly: AssemblyProduct("CompressSave")]
[assembly: AssemblyTitle("CompressSave")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.3.6.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
public static class I18N
{
	private static bool _initialized;

	private static bool _dirty;

	private static readonly List<Tuple<string, string, int>> Keys = new List<Tuple<string, string, int>>();

	private static readonly Dictionary<int, List<string>> Strings = new Dictionary<int, List<string>>();

	public static void Init()
	{
		Harmony.CreateAndPatchAll(typeof(I18N), (string)null);
	}

	public static bool Initialized()
	{
		return _initialized;
	}

	public static void Add(string key, string enus, string zhcn = null)
	{
		if (zhcn != null || !(key == enus))
		{
			Keys.Add(Tuple.Create(key, enus, -1));
			if (Strings.TryGetValue(2052, out var value))
			{
				value.Add(string.IsNullOrEmpty(zhcn) ? enus : zhcn);
			}
			else
			{
				Strings.Add(2052, new List<string>(1) { string.IsNullOrEmpty(zhcn) ? enus : zhcn });
			}
			_dirty = true;
		}
	}

	private static void ApplyIndexers()
	{
		Dictionary<string, int> namesIndexer = Localization.namesIndexer;
		int num = namesIndexer.Count;
		int count = Keys.Count;
		for (int i = 0; i < count; i++)
		{
			var (text3, item, num3) = Keys[i];
			if (num3 < 0)
			{
				if (namesIndexer.TryGetValue(text3, out var value))
				{
					Keys[i] = Tuple.Create(text3, item, value);
					continue;
				}
				namesIndexer[text3] = num;
				Keys[i] = Tuple.Create(text3, item, num);
				num++;
			}
		}
		_dirty = false;
		string[][] strings = Localization.strings;
		if (strings == null)
		{
			return;
		}
		int num4 = strings.Length;
		for (int j = 0; j < num4; j++)
		{
			ApplyLanguage(j);
			if (j == Localization.currentLanguageIndex)
			{
				Localization.currentStrings = Localization.strings[j];
				Localization.currentFloats = Localization.floats[j];
			}
		}
	}

	private static void ApplyLanguage(int index)
	{
		int count = Localization.namesIndexer.Count;
		string[] array = Localization.strings[index];
		if (array == null)
		{
			return;
		}
		if (array.Length < count)
		{
			string[] array2 = new string[count];
			Array.Copy(array, array2, array.Length);
			array = array2;
			Localization.strings[index] = array;
		}
		float[] array3 = Localization.floats[index];
		if (array3 != null && array3.Length < count)
		{
			float[] array4 = new float[count];
			Array.Copy(array3, array4, array3.Length);
			array3 = array4;
			Localization.floats[index] = array3;
		}
		int count2 = Keys.Count;
		if (Strings.TryGetValue(Localization.Languages[index].lcId, out var value))
		{
			for (int i = 0; i < count2; i++)
			{
				array[Keys[i].Item3] = value[i];
			}
		}
		else
		{
			for (int j = 0; j < count2; j++)
			{
				array[Keys[j].Item3] = Keys[j].Item2;
			}
		}
	}

	public static void Apply()
	{
		if (_initialized && Keys.Count != 0 && _dirty)
		{
			ApplyIndexers();
		}
	}

	[HarmonyPostfix]
	[HarmonyPriority(0)]
	[HarmonyPatch(typeof(Localization), "LoadSettings")]
	private static void Localization_LoadSettings_Postfix()
	{
		if (!_initialized)
		{
			_initialized = true;
			Apply();
		}
	}

	[HarmonyPostfix]
	[HarmonyPriority(0)]
	[HarmonyPatch(typeof(Localization), "LoadLanguage")]
	private static void Localization_LoadLanguage_Postfix(int index)
	{
		if (_initialized)
		{
			ApplyLanguage(index);
		}
	}
}
namespace CompressSave
{
	public enum CompressionType
	{
		None,
		LZ4,
		Zstd
	}
	[BepInPlugin("org.soardev.compresssave", "CompressSave", "1.3.6")]
	public class CompressSave : BaseUnityPlugin
	{
		private Harmony _patchSave;

		private Harmony _patchUISave;

		private Harmony _patchUILoad;

		public static string StringFromCompresstionType(CompressionType type)
		{
			return type switch
			{
				CompressionType.LZ4 => "lz4", 
				CompressionType.Zstd => "zstd", 
				CompressionType.None => "none", 
				_ => throw new ArgumentException("Unknown compression type."), 
			};
		}

		private static CompressionType CompressionTypeFromString(string str)
		{
			if (!(str == "lz4"))
			{
				if (str == "zstd")
				{
					return CompressionType.Zstd;
				}
				return CompressionType.None;
			}
			return CompressionType.LZ4;
		}

		public void Awake()
		{
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Expected O, but got Unknown
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Expected O, but got Unknown
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			SaveUtil.Logger = ((BaseUnityPlugin)this).Logger;
			if (LZ4API.Avaliable && ZstdAPI.Avaliable)
			{
				PatchSave.CompressionTypeForSavesConfig = ((BaseUnityPlugin)this).Config.Bind<string>("Compression", "Type", StringFromCompresstionType(PatchSave.CompressionTypeForSaves), new ConfigDescription("Set default compression type for manual saves.", (AcceptableValueBase)(object)new AcceptableValueList<string>(new string[3] { "lz4", "zstd", "none" }), new object[1]
				{
					new { }
				}));
				PatchSave.CompressionTypeForSaves = CompressionTypeFromString(PatchSave.CompressionTypeForSavesConfig.Value);
				PatchSave.CompressionTypeForAutoSavesConfig = ((BaseUnityPlugin)this).Config.Bind<string>("Compression", "TypeForAuto", StringFromCompresstionType(PatchSave.CompressionTypeForAutoSaves), new ConfigDescription("Set default compression type for auto saves and last-exit save.", (AcceptableValueBase)(object)new AcceptableValueList<string>(new string[3] { "lz4", "zstd", "none" }), new object[1]
				{
					new { }
				}));
				PatchSave.CompressionTypeForAutoSaves = CompressionTypeFromString(PatchSave.CompressionTypeForAutoSavesConfig.Value);
				PatchSave.CompressionLevelForSaves = ((BaseUnityPlugin)this).Config.Bind<int>("Compression", "Level", PatchSave.CompressionLevelForSaves, "Set default compression level for manual saves.\n0 for default level.\n3 ~ 12 for lz4, -5 ~ 22 for zstd.\nSmaller level leads to faster speed and less compression ratio.").Value;
				PatchSave.CompressionLevelForAutoSaves = ((BaseUnityPlugin)this).Config.Bind<int>("Compression", "LevelForAuto", PatchSave.CompressionLevelForAutoSaves, "Set default compression level for auto saves and last-exit save.\n0 for default level.\n3 ~ 12 for lz4, -5 ~ 22 for zstd.\nSmaller level leads to faster speed and less compression ratio.").Value;
				PatchSave.EnableForAutoSaves = ((BaseUnityPlugin)this).Config.Bind<bool>("Compression", "EnableForAutoSaves", true, "Enable the feature for auto saves and last-exit save.");
				PatchSave.CreateCompressBuffer();
				if (GameConfig.gameVersion != SaveUtil.VerifiedVersion)
				{
					SaveUtil.Logger.LogWarning((object)$"Save version mismatch. Expect:{SaveUtil.VerifiedVersion}, Current:{GameConfig.gameVersion}. MOD may not work as expected.");
				}
				_patchSave = Harmony.CreateAndPatchAll(typeof(PatchSave), (string)null);
				if (PatchSave.EnableCompress)
				{
					_patchUISave = Harmony.CreateAndPatchAll(typeof(PatchUISaveGame), (string)null);
				}
				_patchUILoad = Harmony.CreateAndPatchAll(typeof(PatchUILoadGame), (string)null);
			}
			else
			{
				SaveUtil.Logger.LogWarning((object)"Either nonewrap.dll, lz4warp.dll or zstdwrap.dll is not avaliable.");
			}
			I18N.Init();
			I18N.Add("Store", "Store (No Compression)", "存储(不压缩)");
			I18N.Add("Decompress", "Decompress", "解压存档");
			I18N.Add("Save with Compression", "Save (Compress)", "压缩保存");
			I18N.Add("Compression for auto saves", "Compression for auto saves", "\u3000\u3000自动存档压缩方式");
			I18N.Add("Compression for manual saves", "Compression for manual saves", "\u3000\u3000手动存档压缩方式");
			I18N.Apply();
		}

		public void OnDestroy()
		{
			if (_patchUISave != null)
			{
				PatchUISaveGame.OnDestroy();
				_patchUISave.UnpatchSelf();
				_patchUISave = null;
			}
			if (_patchUILoad != null)
			{
				PatchUILoadGame.OnDestroy();
				_patchUILoad.UnpatchSelf();
				_patchUILoad = null;
			}
			Harmony patchSave = _patchSave;
			if (patchSave != null)
			{
				patchSave.UnpatchSelf();
			}
			_patchSave = null;
		}
	}
	public class PatchSave
	{
		public static readonly WrapperDefines LZ4Wrapper = new LZ4API();

		public static readonly WrapperDefines ZstdWrapper = new ZstdAPI();

		private static readonly WrapperDefines NoneWrapper = new NoneAPI();

		private static CompressionStream.CompressBuffer _compressBuffer;

		public static bool UseCompressSave;

		private static CompressionType _compressionTypeForLoading = CompressionType.None;

		private static CompressionType _compressionTypeForSaving = CompressionType.Zstd;

		private static int _compressionLevelForSaving;

		public static CompressionType CompressionTypeForSaves = CompressionType.Zstd;

		public static CompressionType CompressionTypeForAutoSaves = CompressionType.Zstd;

		public static ConfigEntry<string> CompressionTypeForSavesConfig;

		public static ConfigEntry<string> CompressionTypeForAutoSavesConfig;

		public static int CompressionLevelForSaves;

		public static int CompressionLevelForAutoSaves;

		public static ConfigEntry<bool> EnableForAutoSaves;

		private static Stream _compressionStream;

		public static bool EnableCompress;

		public static void CreateCompressBuffer()
		{
			_compressBuffer = CompressionStream.CreateBuffer((int)Math.Max(Math.Max(LZ4Wrapper.CompressBufferBound(1048576L), ZstdWrapper.CompressBufferBound(1048576L)), NoneWrapper.CompressBufferBound(1048576L)), 1048576);
			_compressionTypeForSaving = CompressionTypeForSaves;
			_compressionLevelForSaving = CompressionLevelForSaves;
		}

		private static void WriteHeader(FileStream fileStream)
		{
			if (fileStream == null)
			{
				throw new ArgumentNullException("fileStream");
			}
			switch (_compressionTypeForSaving)
			{
			case CompressionType.Zstd:
			{
				for (int j = 0; j < 3; j++)
				{
					fileStream.WriteByte(204);
				}
				fileStream.WriteByte(205);
				break;
			}
			case CompressionType.LZ4:
			{
				for (int i = 0; i < 4; i++)
				{
					fileStream.WriteByte(204);
				}
				break;
			}
			default:
				throw new ArgumentException("Unknown compression type.");
			case CompressionType.None:
				break;
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(GameSave), "AutoSave")]
		[HarmonyPatch(typeof(GameSave), "SaveAsLastExit")]
		private static void BeforeAutoSave()
		{
			UseCompressSave = EnableForAutoSaves.Value && EnableCompress;
			if (UseCompressSave)
			{
				_compressionTypeForSaving = CompressionTypeForAutoSaves;
				_compressionLevelForSaving = CompressionLevelForAutoSaves;
			}
		}

		[HarmonyTranspiler]
		[HarmonyPatch(typeof(GameSave), "SaveCurrentGame")]
		private static IEnumerable<CodeInstruction> SaveCurrentGame_Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Expected O, but got Unknown
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Expected O, but got Unknown
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Expected O, but got Unknown
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Expected O, but got Unknown
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Expected O, but got Unknown
			//IL_01da: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e0: Expected O, but got Unknown
			CodeMatcher val = new CodeMatcher(instructions, generator);
			try
			{
				val.MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
				{
					new CodeMatch((OpCode?)OpCodes.Newobj, (object)AccessTools.Constructor(typeof(BinaryWriter), new Type[1] { typeof(FileStream) }, false), (string)null)
				}).Set(OpCodes.Call, (object)AccessTools.Method(typeof(PatchSave), "CreateBinaryWriter", (Type[])null, (Type[])null)).MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
				{
					new CodeMatch((OpCode?)OpCodes.Call, (object)AccessTools.Method(typeof(PerformanceMonitor), "BeginStream", (Type[])null, (Type[])null), (string)null)
				})
					.Set(OpCodes.Call, (object)AccessTools.Method(typeof(PatchSave), "MonitorStream", (Type[])null, (Type[])null))
					.MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
					{
						new CodeMatch((OpCode?)OpCodes.Callvirt, (object)AccessTools.Method(typeof(Stream), "Seek", (Type[])null, (Type[])null), (string)null)
					})
					.Set(OpCodes.Call, (object)AccessTools.Method(typeof(PatchSave), "FileLengthWrite0", (Type[])null, (Type[])null))
					.MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
					{
						new CodeMatch((OpCode?)OpCodes.Callvirt, (object)AccessTools.Method(typeof(BinaryWriter), "Write", new Type[1] { typeof(long) }, (Type[])null), (string)null)
					})
					.Set(OpCodes.Call, (object)AccessTools.Method(typeof(PatchSave), "FileLengthWrite1", (Type[])null, (Type[])null))
					.MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
					{
						new CodeMatch((OpCode?)OpCodes.Callvirt, (object)AccessTools.Method(typeof(IDisposable), "Dispose", (Type[])null, (Type[])null), (string)null)
					})
					.Advance(1)
					.Insert((CodeInstruction[])(object)new CodeInstruction[1]
					{
						new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(PatchSave), "DisposeCompressionStream", (Type[])null, (Type[])null))
					});
				EnableCompress = true;
				return val.InstructionEnumeration();
			}
			catch (Exception ex)
			{
				SaveUtil.Logger.LogError((object)"SaveCurrentGame_Transpiler failed. Mod version not compatible with game version.");
				SaveUtil.Logger.LogError((object)ex);
			}
			return val.InstructionEnumeration();
		}

		public static void MonitorStream(Stream fileStream)
		{
			PerformanceMonitor.BeginStream(UseCompressSave ? _compressionStream : fileStream);
		}

		public static BinaryWriter CreateBinaryWriter(FileStream fileStream)
		{
			if (UseCompressSave)
			{
				SaveUtil.Logger.LogDebug((object)"Begin compress save");
				WriteHeader(fileStream);
				_compressionStream = _compressionTypeForSaving switch
				{
					CompressionType.LZ4 => new CompressionStream(LZ4Wrapper, _compressionLevelForSaving, fileStream, _compressBuffer, multiThread: true), 
					CompressionType.Zstd => new CompressionStream(ZstdWrapper, _compressionLevelForSaving, fileStream, _compressBuffer, multiThread: true), 
					CompressionType.None => new CompressionStream(NoneWrapper, 0, fileStream, _compressBuffer, multiThread: true), 
					_ => _compressionStream, 
				};
				return ((CompressionStream)_compressionStream).BufferWriter;
			}
			SaveUtil.Logger.LogDebug((object)"Begin normal save");
			return new BinaryWriter(fileStream);
		}

		public static long FileLengthWrite0(FileStream fileStream, long offset, SeekOrigin origin)
		{
			if (!UseCompressSave)
			{
				return fileStream.Seek(offset, origin);
			}
			return 0L;
		}

		public static void FileLengthWrite1(BinaryWriter binaryWriter, long value)
		{
			if (!UseCompressSave)
			{
				binaryWriter.Write(value);
			}
		}

		public static void DisposeCompressionStream()
		{
			if (!UseCompressSave)
			{
				return;
			}
			if (_compressionStream == null)
			{
				UseCompressSave = false;
				return;
			}
			bool canWrite = _compressionStream.CanWrite;
			Stream stream = null;
			if (canWrite && _compressionTypeForSaving == CompressionType.None)
			{
				stream = ((CompressionStream)_compressionStream).OutStream;
			}
			_compressionStream.Dispose();
			_compressionStream = null;
			if (canWrite)
			{
				if (stream != null)
				{
					long value = stream.Seek(0L, SeekOrigin.End);
					stream.Seek(6L, SeekOrigin.Begin);
					BinaryWriter binaryWriter = new BinaryWriter(stream);
					binaryWriter.Write(value);
					binaryWriter.Dispose();
				}
				_compressionTypeForSaving = CompressionTypeForSaves;
				_compressionLevelForSaving = CompressionLevelForSaves;
				UseCompressSave = false;
			}
		}

		[HarmonyTranspiler]
		[HarmonyPatch(typeof(GameSave), "LoadCurrentGame")]
		[HarmonyPatch(typeof(GameSave), "LoadGameDesc")]
		[HarmonyPatch(typeof(GameSave), "ReadHeader")]
		[HarmonyPatch(typeof(GameSave), "ReadHeaderAndDescAndProperty")]
		[HarmonyPatch(typeof(GameSave), "ReadModes")]
		private static IEnumerable<CodeInstruction> LoadCurrentGame_Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Expected O, but got Unknown
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Expected O, but got Unknown
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Expected O, but got Unknown
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Expected O, but got Unknown
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Expected O, but got Unknown
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: Expected O, but got Unknown
			CodeMatcher val = new CodeMatcher(instructions, generator);
			try
			{
				val.MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
				{
					new CodeMatch((OpCode?)OpCodes.Newobj, (object)AccessTools.Constructor(typeof(BinaryReader), new Type[1] { typeof(FileStream) }, false), (string)null)
				}).Set(OpCodes.Call, (object)AccessTools.Method(typeof(PatchSave), "CreateBinaryReader", (Type[])null, (Type[])null)).MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
				{
					new CodeMatch((OpCode?)OpCodes.Call, (object)AccessTools.Method(typeof(PerformanceMonitor), "BeginStream", (Type[])null, (Type[])null), (string)null)
				});
				if (val.IsValid)
				{
					val.Set(OpCodes.Call, (object)AccessTools.Method(typeof(PatchSave), "MonitorStream", (Type[])null, (Type[])null));
				}
				val.Start().MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
				{
					new CodeMatch((OpCode?)OpCodes.Callvirt, (object)AccessTools.Method(typeof(BinaryReader), "ReadInt64", (Type[])null, (Type[])null), (string)null)
				}).Set(OpCodes.Call, (object)AccessTools.Method(typeof(PatchSave), "FileLengthRead", (Type[])null, (Type[])null))
					.MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
					{
						new CodeMatch((OpCode?)OpCodes.Callvirt, (object)AccessTools.Method(typeof(IDisposable), "Dispose", (Type[])null, (Type[])null), (string)null)
					})
					.Advance(1)
					.Insert((CodeInstruction[])(object)new CodeInstruction[1]
					{
						new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(PatchSave), "DisposeCompressionStream", (Type[])null, (Type[])null))
					})
					.MatchBack(false, (CodeMatch[])(object)new CodeMatch[1]
					{
						new CodeMatch((OpCode?)OpCodes.Callvirt, (object)AccessTools.Method(typeof(Stream), "Seek", (Type[])null, (Type[])null), (string)null)
					});
				if (val.IsValid)
				{
					val.Set(OpCodes.Call, (object)AccessTools.Method(typeof(PatchSave), "ReadSeek", (Type[])null, (Type[])null));
				}
				return val.InstructionEnumeration();
			}
			catch (Exception ex)
			{
				SaveUtil.Logger.LogError((object)"LoadCurrentGame_Transpiler failed. Mod version not compatible with game version.");
				SaveUtil.Logger.LogError((object)ex);
			}
			return val.InstructionEnumeration();
		}

		public static BinaryReader CreateBinaryReader(FileStream fileStream)
		{
			switch (_compressionTypeForLoading = SaveUtil.SaveGetCompressType(fileStream))
			{
			case CompressionType.LZ4:
				UseCompressSave = true;
				_compressionStream = new DecompressionStream(LZ4Wrapper, fileStream);
				return new PeekableReader((DecompressionStream)_compressionStream);
			case CompressionType.Zstd:
				UseCompressSave = true;
				_compressionStream = new DecompressionStream(ZstdWrapper, fileStream);
				return new PeekableReader((DecompressionStream)_compressionStream);
			case CompressionType.None:
				UseCompressSave = false;
				fileStream.Seek(0L, SeekOrigin.Begin);
				return new BinaryReader(fileStream);
			default:
				throw new ArgumentOutOfRangeException();
			}
		}

		public static long FileLengthRead(BinaryReader binaryReader)
		{
			switch (_compressionTypeForLoading)
			{
			case CompressionType.LZ4:
			case CompressionType.Zstd:
				binaryReader.ReadInt64();
				return _compressionStream.Length;
			case CompressionType.None:
				return binaryReader.ReadInt64();
			default:
				throw new ArgumentOutOfRangeException();
			}
		}

		public static long ReadSeek(FileStream fileStream, long offset, SeekOrigin origin)
		{
			switch (_compressionTypeForLoading)
			{
			case CompressionType.LZ4:
			case CompressionType.Zstd:
				while (offset > 0)
				{
					offset -= _compressionStream.Read(_compressBuffer.OutBuffer, 0, (int)offset);
				}
				return _compressionStream.Position;
			case CompressionType.None:
				return fileStream.Seek(offset, origin);
			default:
				throw new ArgumentOutOfRangeException();
			}
		}
	}
	internal class PatchUILoadGame
	{
		private static UIButton _decompressButton;

		[HarmonyPatch(typeof(UILoadGameWindow), "OnSelectedChange")]
		[HarmonyPostfix]
		private static void OnSelectedChange(UILoadGameWindow __instance)
		{
			UIGameSaveEntry selected = __instance.selected;
			CompressionType compressionType = SaveUtil.SaveGetCompressType(((Object)(object)selected == (Object)null) ? null : selected._saveName);
			Text prop3Text = __instance.prop3Text;
			Text val = prop3Text;
			val.text = compressionType switch
			{
				CompressionType.LZ4 => "(LZ4)" + prop3Text.text, 
				CompressionType.Zstd => "(ZSTD)" + prop3Text.text, 
				_ => "(N)" + prop3Text.text, 
			};
			if (Object.op_Implicit((Object)(object)_decompressButton))
			{
				((Selectable)_decompressButton.button).interactable = compressionType != CompressionType.None;
				((Component)_decompressButton).gameObject.SetActive(compressionType != CompressionType.None);
			}
		}

		[HarmonyPatch(typeof(UILoadGameWindow), "_OnOpen")]
		[HarmonyPostfix]
		private static void _OnOpen(UILoadGameWindow __instance)
		{
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)_decompressButton))
			{
				return;
			}
			UIButton loadButton = __instance.loadButton;
			bool flag = false;
			Transform obj = ((Component)__instance).transform.Find("button-decompress");
			GameObject val = ((obj != null) ? ((Component)obj).gameObject : null);
			if ((Object)(object)val == (Object)null)
			{
				val = Object.Instantiate<GameObject>(((Component)loadButton).gameObject, ((Component)loadButton).transform.parent);
				flag = true;
			}
			_decompressButton = val.GetComponent<UIButton>();
			if (flag)
			{
				Vector3 anchoredPosition3D = ((RectTransform)__instance.loadSandboxGroup.transform).anchoredPosition3D;
				((Object)((Component)_decompressButton).gameObject).name = "button-decompress";
				RectTransform val2 = (RectTransform)((Component)_decompressButton).transform;
				Vector3 val3 = anchoredPosition3D;
				((Vector3)(ref anchoredPosition3D))..ctor(val3.x - 230f, val3.y, val3.z);
				val2.anchoredPosition3D = anchoredPosition3D;
				((Graphic)((Selectable)_decompressButton.button).image).color = Color32.op_Implicit(new Color32((byte)0, (byte)244, (byte)146, (byte)119));
				Transform obj2 = ((Component)_decompressButton).transform.Find("button-text");
				((Component)obj2).GetComponent<Text>().text = Localization.Translate("Decompress");
				Localizer component = ((Component)obj2).GetComponent<Localizer>();
				if (Object.op_Implicit((Object)(object)component))
				{
					component.stringKey = "Decompress";
					component.translation = Localization.Translate("Decompress");
				}
				_decompressButton.onClick += delegate
				{
					if (SaveUtil.DecompressSave(__instance.selected._saveName, out var newfileName))
					{
						__instance.RefreshList();
						__instance.selected = __instance.entries.First((UIGameSaveEntry e) => e._saveName == newfileName);
					}
				};
			}
			((Selectable)_decompressButton.button).interactable = false;
			((Component)_decompressButton).gameObject.SetActive(false);
		}

		public static void OnDestroy()
		{
			if (Object.op_Implicit((Object)(object)_decompressButton))
			{
				Object.Destroy((Object)(object)((Component)_decompressButton).gameObject);
			}
			_decompressButton = null;
		}
	}
	internal static class PatchUISaveGame
	{
		private class UIContext
		{
			public UIButton ButtonCompress;

			public UIButton SaveButton;

			public GameObject ManualSaveTypeComboBox;

			public GameObject AutoSaveTypeComboBox;

			public Text ButtonCompressText;

			public Text SaveButtonText;

			public UISaveGameWindow Window;
		}

		private static UIContext _context = new UIContext();

		public static void OnDestroy()
		{
			if (Object.op_Implicit((Object)(object)_context.ButtonCompress))
			{
				Object.Destroy((Object)(object)((Component)_context.ButtonCompress).gameObject);
			}
			if (Object.op_Implicit((Object)(object)_context.Window))
			{
				_context.SaveButton.onClick -= WrapClick;
				_context.SaveButton.onClick += _context.Window.OnSaveClick;
			}
			_OnDestroy();
		}

		[HarmonyPatch(typeof(UISaveGameWindow), "OnSelectedChange")]
		[HarmonyPostfix]
		private static void OnSelectedChange(UISaveGameWindow __instance)
		{
			UIGameSaveEntry selected = __instance.selected;
			CompressionType compressionType = SaveUtil.SaveGetCompressType(((Object)(object)selected == (Object)null) ? null : selected._saveName);
			Text prop3Text = __instance.prop3Text;
			Text val = prop3Text;
			val.text = compressionType switch
			{
				CompressionType.LZ4 => "(LZ4)" + prop3Text.text, 
				CompressionType.Zstd => "(ZSTD)" + prop3Text.text, 
				_ => "(N)" + prop3Text.text, 
			};
		}

		[HarmonyPatch(typeof(UISaveGameWindow), "_OnDestroy")]
		[HarmonyPostfix]
		private static void _OnDestroy()
		{
			_context = new UIContext();
		}

		[HarmonyPatch(typeof(UISaveGameWindow), "OnSaveClick")]
		[HarmonyReversePatch(/*Could not decode attribute arguments.*/)]
		private static void OSaveGameAs(this UISaveGameWindow ui, int data)
		{
		}

		[HarmonyPatch(typeof(UISaveGameWindow), "CheckAndSetSaveButtonEnable")]
		[HarmonyPostfix]
		private static void CheckAndSetSaveButtonEnable(UISaveGameWindow __instance)
		{
			_OnOpen(__instance);
			if (Object.op_Implicit((Object)(object)_context.SaveButton))
			{
				((Selectable)_context.ButtonCompress.button).interactable = ((Selectable)_context.SaveButton.button).interactable;
			}
		}

		[HarmonyPatch(typeof(UISaveGameWindow), "OnSaveClick")]
		[HarmonyPrefix]
		private static void OnSaveClick()
		{
			PatchSave.UseCompressSave = true;
		}

		[HarmonyPatch(typeof(UISaveGameWindow), "_OnOpen")]
		[HarmonyPostfix]
		private static void _OnOpen(UISaveGameWindow __instance)
		{
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_0279: Unknown result type (might be due to invalid IL or missing references)
			//IL_028d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0294: Expected O, but got Unknown
			//IL_0296: Unknown result type (might be due to invalid IL or missing references)
			//IL_029b: Unknown result type (might be due to invalid IL or missing references)
			//IL_029c: Unknown result type (might be due to invalid IL or missing references)
			//IL_029f: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0406: Unknown result type (might be due to invalid IL or missing references)
			//IL_0410: Expected O, but got Unknown
			//IL_041c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0421: Unknown result type (might be due to invalid IL or missing references)
			//IL_0422: Unknown result type (might be due to invalid IL or missing references)
			//IL_0427: Unknown result type (might be due to invalid IL or missing references)
			//IL_0428: Unknown result type (might be due to invalid IL or missing references)
			//IL_0429: Unknown result type (might be due to invalid IL or missing references)
			//IL_0435: Unknown result type (might be due to invalid IL or missing references)
			//IL_043b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0441: Unknown result type (might be due to invalid IL or missing references)
			//IL_044b: Unknown result type (might be due to invalid IL or missing references)
			//IL_044c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0451: Unknown result type (might be due to invalid IL or missing references)
			//IL_0458: Unknown result type (might be due to invalid IL or missing references)
			//IL_045f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0534: Unknown result type (might be due to invalid IL or missing references)
			//IL_0548: Unknown result type (might be due to invalid IL or missing references)
			//IL_054f: Expected O, but got Unknown
			//IL_0551: Unknown result type (might be due to invalid IL or missing references)
			//IL_0556: Unknown result type (might be due to invalid IL or missing references)
			//IL_0557: Unknown result type (might be due to invalid IL or missing references)
			//IL_055a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0564: Unknown result type (might be due to invalid IL or missing references)
			//IL_0567: Unknown result type (might be due to invalid IL or missing references)
			//IL_0571: Unknown result type (might be due to invalid IL or missing references)
			//IL_0574: Unknown result type (might be due to invalid IL or missing references)
			//IL_057e: Unknown result type (might be due to invalid IL or missing references)
			//IL_057f: Unknown result type (might be due to invalid IL or missing references)
			//IL_058b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0597: Unknown result type (might be due to invalid IL or missing references)
			//IL_059d: Unknown result type (might be due to invalid IL or missing references)
			//IL_06e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_06ec: Expected O, but got Unknown
			//IL_06f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_06fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_06fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0703: Unknown result type (might be due to invalid IL or missing references)
			//IL_0704: Unknown result type (might be due to invalid IL or missing references)
			//IL_0705: Unknown result type (might be due to invalid IL or missing references)
			//IL_0711: Unknown result type (might be due to invalid IL or missing references)
			//IL_0717: Unknown result type (might be due to invalid IL or missing references)
			//IL_071d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0727: Unknown result type (might be due to invalid IL or missing references)
			//IL_0728: Unknown result type (might be due to invalid IL or missing references)
			//IL_072d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0734: Unknown result type (might be due to invalid IL or missing references)
			//IL_073b: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)_context.ButtonCompress))
			{
				return;
			}
			_context.SaveButton = __instance.saveButton;
			_context.SaveButtonText = __instance.saveButtonText;
			_context.Window = __instance;
			Transform obj = ((Component)__instance).transform.Find("button-compress");
			GameObject val = ((obj != null) ? ((Component)obj).gameObject : null);
			bool flag = false;
			if ((Object)(object)val == (Object)null)
			{
				val = Object.Instantiate<GameObject>(((Component)__instance.saveButton).gameObject, ((Component)__instance.saveButton).transform.parent);
				flag = true;
			}
			_context.ButtonCompress = val.GetComponent<UIButton>();
			Vector3 anchoredPosition3D;
			if (flag)
			{
				((Object)((Component)_context.ButtonCompress).gameObject).name = "button-compress";
				RectTransform val2 = (RectTransform)((Component)_context.ButtonCompress).transform;
				anchoredPosition3D = val2.anchoredPosition3D;
				val2.anchoredPosition3D = new Vector3(anchoredPosition3D.x - 180f, anchoredPosition3D.y, anchoredPosition3D.z);
				((Graphic)((Selectable)_context.ButtonCompress.button).image).color = Color32.op_Implicit(new Color32((byte)252, (byte)111, (byte)0, (byte)119));
				Transform val3 = ((Component)_context.ButtonCompress).transform.Find("button-text");
				_context.ButtonCompressText = ((Component)val3).GetComponent<Text>();
				_context.ButtonCompress.onClick += __instance.OnSaveClick;
				_context.SaveButton.onClick -= __instance.OnSaveClick;
				_context.SaveButton.onClick += WrapClick;
				_context.ButtonCompressText.text = Localization.Translate("Save with Compression");
				Localizer component = ((Component)val3).GetComponent<Localizer>();
				if (Object.op_Implicit((Object)(object)component))
				{
					component.stringKey = "Save with Compression";
					component.translation = Localization.Translate("Save with Compression");
				}
			}
			flag = false;
			Transform obj2 = ((Component)__instance).transform.Find("manual-save-type-combobox");
			val = ((obj2 != null) ? ((Component)obj2).gameObject : null);
			if ((Object)(object)val == (Object)null)
			{
				val = Object.Instantiate<GameObject>(((Component)((Component)UIRoot.instance.optionWindow.resolutionComp).transform.parent).gameObject, ((Component)__instance.saveButton).transform.parent);
				flag = true;
			}
			_context.ManualSaveTypeComboBox = val;
			if (flag)
			{
				((Object)val).name = "manual-save-type-combobox";
				RectTransform val4 = (RectTransform)val.transform;
				RectTransform val5 = (RectTransform)((Component)_context.ButtonCompress).transform;
				anchoredPosition3D = val5.anchoredPosition3D;
				val4.anchorMin = val5.anchorMin;
				val4.anchorMax = val5.anchorMax;
				val4.pivot = val5.pivot;
				val4.anchoredPosition3D = new Vector3(anchoredPosition3D.x + 100f, anchoredPosition3D.y + 45f, anchoredPosition3D.z);
				Transform val6 = ((Component)val4).transform.Find("ComboBox");
				Transform obj3 = val6.Find("Dropdown List ScrollBox");
				object obj4;
				if (obj3 == null)
				{
					obj4 = null;
				}
				else
				{
					Transform obj5 = obj3.Find("Mask");
					obj4 = ((obj5 != null) ? obj5.Find("Content Panel") : null);
				}
				Transform val7 = (Transform)obj4;
				if ((Object)(object)val7 != (Object)null)
				{
					for (int num = val7.childCount - 1; num >= 0; num--)
					{
						Transform child = val7.GetChild(num);
						if (((Object)child).name == "Item Button(Clone)")
						{
							Object.Destroy((Object)(object)((Component)child).gameObject);
						}
					}
				}
				UIComboBox cb2 = ((Component)val6).GetComponent<UIComboBox>();
				((UnityEventBase)cb2.onSubmit).RemoveAllListeners();
				((UnityEventBase)cb2.onItemIndexChange).RemoveAllListeners();
				cb2.Items = new List<string>(3)
				{
					Localization.Translate("Store"),
					"LZ4",
					"Zstd"
				};
				cb2.itemIndex = (int)PatchSave.CompressionTypeForSaves;
				((UnityEvent)cb2.onItemIndexChange).AddListener((UnityAction)delegate
				{
					PatchSave.CompressionTypeForSaves = (CompressionType)cb2.itemIndex;
					PatchSave.CompressionTypeForSavesConfig.Value = CompressSave.StringFromCompresstionType(PatchSave.CompressionTypeForSaves);
				});
				RectTransform val8 = (RectTransform)((Component)cb2).transform;
				anchoredPosition3D = val8.anchoredPosition3D;
				val8.anchoredPosition3D = new Vector3(anchoredPosition3D.x - 50f, anchoredPosition3D.y, anchoredPosition3D.z);
				Vector2 sizeDelta = val8.sizeDelta;
				val8.sizeDelta = new Vector2(150f, sizeDelta.y);
				val.GetComponent<Text>().text = Localization.Translate("Compression for manual saves");
				Localizer component2 = val.GetComponent<Localizer>();
				if ((Object)(object)component2 != (Object)null)
				{
					component2.stringKey = "Compression for manual saves";
					component2.translation = Localization.Translate("Compression for manual saves");
				}
			}
			flag = false;
			Transform obj6 = ((Component)__instance).transform.Find("auto-save-type-combobox");
			val = ((obj6 != null) ? ((Component)obj6).gameObject : null);
			if ((Object)(object)val == (Object)null)
			{
				val = Object.Instantiate<GameObject>(((Component)((Component)UIRoot.instance.optionWindow.resolutionComp).transform.parent).gameObject, ((Component)__instance.saveButton).transform.parent);
				flag = true;
			}
			_context.AutoSaveTypeComboBox = val;
			if (!flag)
			{
				return;
			}
			((Object)val).name = "auto-save-type-combobox";
			RectTransform val9 = (RectTransform)val.transform;
			RectTransform val10 = (RectTransform)((Component)_context.ButtonCompress).transform;
			anchoredPosition3D = val10.anchoredPosition3D;
			val9.anchorMin = val10.anchorMin;
			val9.anchorMax = val10.anchorMax;
			val9.pivot = val10.pivot;
			val9.anchoredPosition3D = new Vector3(anchoredPosition3D.x + 510f, anchoredPosition3D.y + 45f, anchoredPosition3D.z);
			Transform val11 = ((Component)val9).transform.Find("ComboBox");
			Transform obj7 = val11.Find("Dropdown List ScrollBox");
			object obj8;
			if (obj7 == null)
			{
				obj8 = null;
			}
			else
			{
				Transform obj9 = obj7.Find("Mask");
				obj8 = ((obj9 != null) ? obj9.Find("Content Panel") : null);
			}
			Transform val12 = (Transform)obj8;
			if ((Object)(object)val12 != (Object)null)
			{
				for (int num2 = val12.childCount - 1; num2 >= 0; num2--)
				{
					Transform child2 = val12.GetChild(num2);
					if (((Object)child2).name == "Item Button(Clone)")
					{
						Object.Destroy((Object)(object)((Component)child2).gameObject);
					}
				}
			}
			UIComboBox cb = ((Component)val11).GetComponent<UIComboBox>();
			((UnityEventBase)cb.onSubmit).RemoveAllListeners();
			((UnityEventBase)cb.onItemIndexChange).RemoveAllListeners();
			cb.Items = new List<string>(4)
			{
				Localization.Translate("已停用"),
				Localization.Translate("Store"),
				"LZ4",
				"Zstd"
			};
			cb.itemIndex = (int)(PatchSave.EnableForAutoSaves.Value ? (PatchSave.CompressionTypeForAutoSaves + 1) : CompressionType.None);
			((UnityEvent)cb.onItemIndexChange).AddListener((UnityAction)delegate
			{
				int itemIndex = cb.itemIndex;
				if (itemIndex == 0)
				{
					PatchSave.EnableForAutoSaves.Value = false;
				}
				else
				{
					PatchSave.EnableForAutoSaves.Value = true;
					PatchSave.CompressionTypeForAutoSaves = (CompressionType)(itemIndex - 1);
					PatchSave.CompressionTypeForAutoSavesConfig.Value = CompressSave.StringFromCompresstionType(PatchSave.CompressionTypeForAutoSaves);
				}
			});
			RectTransform val13 = (RectTransform)((Component)cb).transform;
			anchoredPosition3D = val13.anchoredPosition3D;
			val13.anchoredPosition3D = new Vector3(anchoredPosition3D.x - 50f, anchoredPosition3D.y, anchoredPosition3D.z);
			Vector2 sizeDelta2 = val13.sizeDelta;
			val13.sizeDelta = new Vector2(150f, sizeDelta2.y);
			val.GetComponent<Text>().text = Localization.Translate("Compression for auto saves");
			Localizer component3 = val.GetComponent<Localizer>();
			if ((Object)(object)component3 != (Object)null)
			{
				component3.stringKey = "Compression for auto saves";
				component3.translation = Localization.Translate("Compression for auto saves");
			}
		}

		private static void WrapClick(int data)
		{
			PatchSave.UseCompressSave = false;
			_context.Window.OSaveGameAs(data);
		}
	}
	public static class SaveUtil
	{
		public static ManualLogSource Logger;

		public static readonly Version VerifiedVersion = new Version
		{
			Major = 0,
			Minor = 10,
			Release = 28
		};

		private static string UnzipToFile(DecompressionStream lzStream, string fullPath)
		{
			lzStream.ResetStream();
			string directoryName = Path.GetDirectoryName(fullPath);
			string text = "[Recovery]-" + Path.GetFileNameWithoutExtension(fullPath);
			fullPath = text + GameSave.saveExt;
			if (directoryName != null)
			{
				fullPath = Path.Combine(directoryName, fullPath);
			}
			int num = 0;
			while (File.Exists(fullPath))
			{
				fullPath = $"{text}[{num++}]{GameSave.saveExt}";
				if (directoryName != null)
				{
					fullPath = Path.Combine(directoryName, fullPath);
				}
			}
			byte[] array = new byte[1048576];
			using (FileStream fileStream = new FileStream(fullPath, FileMode.Create))
			{
				using BinaryWriter binaryWriter = new BinaryWriter(fileStream);
				for (int num2 = lzStream.Read(array, 0, array.Length); num2 > 0; num2 = lzStream.Read(array, 0, array.Length))
				{
					fileStream.Write(array, 0, num2);
				}
				fileStream.Seek(6L, SeekOrigin.Begin);
				binaryWriter.Write(fileStream.Length);
			}
			return Path.GetFileNameWithoutExtension(fullPath);
		}

		public static bool DecompressSave(string saveName, out string newSaveName)
		{
			newSaveName = string.Empty;
			string text = GameConfig.gameSaveFolder + saveName + GameSave.saveExt;
			try
			{
				using FileStream fileStream = new FileStream(text, FileMode.Open, FileAccess.Read);
				CompressionType compressionType = SaveGetCompressType(fileStream);
				if (compressionType != 0)
				{
					if ((uint)(compressionType - 1) <= 1u)
					{
						using (DecompressionStream lzStream = new DecompressionStream((compressionType == CompressionType.LZ4) ? PatchSave.LZ4Wrapper : PatchSave.ZstdWrapper, fileStream))
						{
							newSaveName = UnzipToFile(lzStream, text);
						}
						return true;
					}
					throw new ArgumentOutOfRangeException();
				}
				return false;
			}
			catch (Exception ex)
			{
				Logger.LogError((object)ex);
				return false;
			}
		}

		public static CompressionType SaveGetCompressType(FileStream fs)
		{
			for (int i = 0; i < 3; i++)
			{
				if (204 != fs.ReadByte())
				{
					return CompressionType.None;
				}
			}
			return fs.ReadByte() switch
			{
				204 => CompressionType.LZ4, 
				205 => CompressionType.Zstd, 
				_ => CompressionType.None, 
			};
		}

		internal static CompressionType SaveGetCompressType(string saveName)
		{
			if (string.IsNullOrEmpty(saveName))
			{
				return CompressionType.None;
			}
			try
			{
				using FileStream fs = new FileStream(GetFullSavePath(saveName), FileMode.Open);
				return SaveGetCompressType(fs);
			}
			catch (Exception ex)
			{
				Logger.LogWarning((object)ex);
				return CompressionType.None;
			}
		}

		private static string GetFullSavePath(string saveName)
		{
			return GameConfig.gameSaveFolder + saveName + GameSave.saveExt;
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "org.soardev.compresssave";

		public const string PLUGIN_NAME = "CompressSave";

		public const string PLUGIN_VERSION = "1.3.6";
	}
}
namespace CompressSave.Wrapper
{
	internal class BlackHoleStream : Stream
	{
		private long _length;

		private readonly byte[] _testBuffer = new byte[1048576];

		public override bool CanRead => true;

		public override bool CanSeek => false;

		public override bool CanWrite => true;

		public override long Length => _length;

		public override long Position { get; set; }

		public override void Flush()
		{
		}

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

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

		public override void SetLength(long value)
		{
			_length = value;
		}

		public override void Write(byte[] buffer, int offset, int count)
		{
			Array.Copy(buffer, offset, _testBuffer, 0, Math.Min(count, _testBuffer.Length));
		}
	}
	public class BufferWriter : BinaryWriter
	{
		private readonly DoubleBuffer _doubleBuffer;

		private readonly Encoding _encoding;

		private readonly int _maxBytesPerChar;

		private long _swapedBytes;

		private unsafe byte* _curPos;

		private unsafe byte* _endPos;

		private unsafe byte* _startPos;

		private readonly Stream _baseStream;

		private ByteSpan CurrentBuffer => _doubleBuffer.WriteBuffer;

		private byte[] Buffer => CurrentBuffer.Buffer;

		private unsafe long SuplusCapacity => _endPos - _curPos;

		public unsafe long WriteSum => _swapedBytes + _curPos - _startPos;

		public override Stream BaseStream => _baseStream;

		public override void Write(char[] chars, int index, int count)
		{
			if (chars == null)
			{
				throw new ArgumentNullException("chars");
			}
			byte[] bytes = _encoding.GetBytes(chars, index, count);
			Write(bytes);
		}

		public BufferWriter(DoubleBuffer doubleBuffer, CompressionStream outStream)
			: this(doubleBuffer, new UTF8Encoding(encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: true), outStream)
		{
		}

		private BufferWriter(DoubleBuffer buffer, UTF8Encoding encoding, CompressionStream outStream)
			: base(Stream.Null, encoding)
		{
			_baseStream = outStream;
			_swapedBytes = 0L;
			_doubleBuffer = buffer;
			RefreshStatus();
			_encoding = encoding;
			_maxBytesPerChar = _encoding.GetMaxByteCount(1);
		}

		private unsafe void SwapBuffer()
		{
			CurrentBuffer.Position = 0;
			CurrentBuffer.Length = (int)(_curPos - _startPos);
			_swapedBytes += CurrentBuffer.Length;
			_doubleBuffer.SwapBuffer();
			RefreshStatus();
		}

		private unsafe void RefreshStatus()
		{
			_startPos = (byte*)System.Runtime.CompilerServices.Unsafe.AsPointer<byte>(ref Buffer[0]);
			_curPos = _startPos;
			_endPos = (byte*)System.Runtime.CompilerServices.Unsafe.AsPointer<byte>(ref Buffer[Buffer.Length - 1]) + 1;
		}

		private void CheckCapacityAndSwap(int requiredCapacity)
		{
			if (SuplusCapacity < requiredCapacity)
			{
				SwapBuffer();
			}
		}

		public unsafe override void Write(byte value)
		{
			CheckCapacityAndSwap(1);
			*(_curPos++) = value;
		}

		public override void Write(bool value)
		{
			Write(value ? ((byte)1) : ((byte)0));
		}

		protected override void Dispose(bool disposing)
		{
			if (disposing)
			{
				SwapBuffer();
			}
			base.Dispose(disposing);
		}

		public override void Close()
		{
			Dispose(disposing: true);
		}

		public override void Flush()
		{
			SwapBuffer();
		}

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

		public override void Write(sbyte value)
		{
			Write((byte)value);
		}

		public override void Write(byte[] buffer)
		{
			Write(buffer, 0, buffer.Length);
		}

		public unsafe override void Write(byte[] buffer, int index, int count)
		{
			if (buffer == null)
			{
				throw new ArgumentNullException("buffer");
			}
			fixed (byte* ptr = buffer)
			{
				byte* ptr2 = ptr + index;
				while (SuplusCapacity <= count)
				{
					int num = (int)SuplusCapacity;
					System.Runtime.CompilerServices.Unsafe.CopyBlock((void*)_curPos, (void*)ptr2, (uint)num);
					count -= num;
					ptr2 += num;
					_curPos = _endPos;
					SwapBuffer();
				}
				System.Runtime.CompilerServices.Unsafe.CopyBlock((void*)_curPos, (void*)ptr2, (uint)count);
				_curPos += count;
			}
		}

		public unsafe override void Write(char ch)
		{
			if (char.IsSurrogate(ch))
			{
				throw new ArgumentException("Arg_SurrogatesNotAllowedAsSingleChar");
			}
			CheckCapacityAndSwap(_maxBytesPerChar);
			_curPos += _encoding.GetBytes(&ch, 1, _curPos, (int)SuplusCapacity);
		}

		public override void Write(char[] chars)
		{
			if (chars == null)
			{
				throw new ArgumentNullException("chars");
			}
			byte[] bytes = _encoding.GetBytes(chars, 0, chars.Length);
			Write(bytes);
		}

		public unsafe override void Write(double value)
		{
			CheckCapacityAndSwap(8);
			ulong num = *(ulong*)(&value);
			*(_curPos++) = (byte)num;
			*(_curPos++) = (byte)(num >> 8);
			*(_curPos++) = (byte)(num >> 16);
			*(_curPos++) = (byte)(num >> 24);
			*(_curPos++) = (byte)(num >> 32);
			*(_curPos++) = (byte)(num >> 40);
			*(_curPos++) = (byte)(num >> 48);
			*(_curPos++) = (byte)(num >> 56);
		}

		public override void Write(decimal d)
		{
			CheckCapacityAndSwap(16);
			int[] bits = decimal.GetBits(d);
			Write(bits[0]);
			Write(bits[1]);
			Write(bits[2]);
			Write(bits[3]);
		}

		public unsafe override void Write(short value)
		{
			CheckCapacityAndSwap(2);
			*(_curPos++) = (byte)value;
			*(_curPos++) = (byte)(value >> 8);
		}

		public unsafe override void Write(ushort value)
		{
			CheckCapacityAndSwap(2);
			*(_curPos++) = (byte)value;
			*(_curPos++) = (byte)(value >> 8);
		}

		public unsafe override void Write(int value)
		{
			if (SuplusCapacity < 4)
			{
				SwapBuffer();
			}
			*(_curPos++) = (byte)value;
			*(_curPos++) = (byte)(value >> 8);
			*(_curPos++) = (byte)(value >> 16);
			*(_curPos++) = (byte)(value >> 24);
		}

		public unsafe override void Write(uint value)
		{
			CheckCapacityAndSwap(4);
			*(_curPos++) = (byte)value;
			*(_curPos++) = (byte)(value >> 8);
			*(_curPos++) = (byte)(value >> 16);
			*(_curPos++) = (byte)(value >> 24);
		}

		public unsafe override void Write(long value)
		{
			CheckCapacityAndSwap(8);
			*(_curPos++) = (byte)value;
			*(_curPos++) = (byte)(value >> 8);
			*(_curPos++) = (byte)(value >> 16);
			*(_curPos++) = (byte)(value >> 24);
			*(_curPos++) = (byte)(value >> 32);
			*(_curPos++) = (byte)(value >> 40);
			*(_curPos++) = (byte)(value >> 48);
			*(_curPos++) = (byte)(value >> 56);
		}

		public unsafe override void Write(ulong value)
		{
			CheckCapacityAndSwap(8);
			*(_curPos++) = (byte)value;
			*(_curPos++) = (byte)(value >> 8);
			*(_curPos++) = (byte)(value >> 16);
			*(_curPos++) = (byte)(value >> 24);
			*(_curPos++) = (byte)(value >> 32);
			*(_curPos++) = (byte)(value >> 40);
			*(_curPos++) = (byte)(value >> 48);
			*(_curPos++) = (byte)(value >> 56);
		}

		public unsafe override void Write(float value)
		{
			CheckCapacityAndSwap(4);
			uint num = *(uint*)(&value);
			*(_curPos++) = (byte)num;
			*(_curPos++) = (byte)(num >> 8);
			*(_curPos++) = (byte)(num >> 16);
			*(_curPos++) = (byte)(num >> 24);
		}

		public override void Write(string value)
		{
			if (value == null)
			{
				throw new ArgumentNullException("value");
			}
			byte[] bytes = _encoding.GetBytes(value);
			Write7BitEncodedInt(bytes.Length);
			Write(bytes);
		}

		private new void Write7BitEncodedInt(int value)
		{
			uint num;
			for (num = (uint)value; num >= 128; num >>= 7)
			{
				Write((byte)(num | 0x80u));
			}
			Write((byte)num);
		}
	}
	public class CompressionStream : Stream
	{
		public struct CompressBuffer
		{
			public byte[] ReadBuffer;

			public byte[] WriteBuffer;

			public byte[] OutBuffer;
		}

		private readonly WrapperDefines _wrapper;

		public const int Mb = 1048576;

		public readonly Stream OutStream;

		private long _totalWrite;

		private readonly bool _useMultiThread;

		private DoubleBuffer _doubleBuffer;

		private byte[] _outBuffer;

		private IntPtr _cctx;

		private long _lastError;

		private bool _stopWorker = true;

		private bool _closed;

		public override bool CanRead => false;

		public override bool CanSeek => false;

		public override bool CanWrite => true;

		public override long Length => _totalWrite;

		public override long Position
		{
			get
			{
				return BufferWriter.WriteSum;
			}
			set
			{
				throw new NotImplementedException();
			}
		}

		public BufferWriter BufferWriter { get; private set; }

		public bool HasError()
		{
			return _lastError != 0;
		}

		private void HandleError(long errorCode)
		{
			if (errorCode < 0)
			{
				_wrapper.CompressContextFree(_cctx);
				_cctx = IntPtr.Zero;
				_lastError = errorCode;
				throw new Exception(errorCode.ToString());
			}
		}

		public static CompressBuffer CreateBuffer(int outBufferSize, int exBufferSize = 4194304)
		{
			try
			{
				CompressBuffer result = default(CompressBuffer);
				result.OutBuffer = new byte[outBufferSize];
				result.ReadBuffer = new byte[exBufferSize];
				result.WriteBuffer = new byte[exBufferSize];
				return result;
			}
			catch (Exception ex)
			{
				Console.WriteLine(ex.ToString());
			}
			return default(CompressBuffer);
		}

		public CompressionStream(WrapperDefines wrap, int compressionLevel, Stream outputStream, CompressBuffer compressBuffer, bool multiThread)
		{
			_wrapper = wrap;
			OutStream = outputStream;
			InitBuffer(compressBuffer.ReadBuffer, compressBuffer.WriteBuffer, compressBuffer.OutBuffer);
			long num = _wrapper.CompressBegin(out _cctx, compressionLevel, _outBuffer, _outBuffer.Length, null, 0L);
			HandleError(num);
			outputStream.Write(_outBuffer, 0, (int)num);
			_useMultiThread = multiThread;
			if (multiThread)
			{
				_stopWorker = false;
				new Thread(CompressAsync).Start();
			}
		}

		private void InitBuffer(byte[] readBuffer, byte[] writeBuffer, byte[] outputBuffer)
		{
			_doubleBuffer = new DoubleBuffer(readBuffer ?? new byte[4194304], writeBuffer ?? new byte[4194304], Compress);
			_outBuffer = outputBuffer ?? new byte[_wrapper.CompressBufferBound((writeBuffer != null) ? writeBuffer.Length : 4194304)];
			BufferWriter = new BufferWriter(_doubleBuffer, this);
		}

		public override void Flush()
		{
			_doubleBuffer.SwapBuffer();
			if (_useMultiThread)
			{
				_doubleBuffer.WaitReadEnd();
			}
			lock (_outBuffer)
			{
				OutStream.Flush();
			}
		}

		private void Compress()
		{
			if (!_useMultiThread)
			{
				Compress_Internal();
			}
		}

		private void Compress_Internal()
		{
			ByteSpan byteSpan = _doubleBuffer.ReadBegin();
			if (byteSpan.Length > 0)
			{
				lock (_outBuffer)
				{
					long num;
					try
					{
						num = _wrapper.CompressUpdateEx(_cctx, _outBuffer, 0L, byteSpan.Buffer, 0L, byteSpan.Length);
						HandleError(num);
					}
					finally
					{
						_doubleBuffer.ReadEnd();
					}
					OutStream.Write(_outBuffer, 0, (int)num);
					_totalWrite += num;
					return;
				}
			}
			_doubleBuffer.ReadEnd();
		}

		private void CompressAsync()
		{
			while (!_stopWorker)
			{
				Compress_Internal();
			}
		}

		public override int Read(byte[] buffer, int offset, int count)
		{
			throw new NotImplementedException();
		}

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

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

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

		private void FreeContext()
		{
			_wrapper.CompressContextFree(_cctx);
			_cctx = IntPtr.Zero;
		}

		public override void Close()
		{
			if (!_closed)
			{
				BufferWriter.Close();
				_closed = true;
				Flush();
				_stopWorker = true;
				_doubleBuffer.SwapBuffer();
				long num = _wrapper.CompressEnd(_cctx, _outBuffer, _outBuffer.Length);
				OutStream.Write(_outBuffer, 0, (int)num);
				base.Close();
			}
		}

		protected override void Dispose(bool disposing)
		{
			FreeContext();
			base.Dispose(disposing);
		}
	}
	public class DecompressionStream : Stream
	{
		private readonly WrapperDefines _wrapper;

		private readonly Stream _inStream;

		private IntPtr _dctx = IntPtr.Zero;

		private readonly ByteSpan _srcBuffer;

		private readonly ByteSpan _dcmpBuffer;

		private bool _decompressFinish;

		private readonly long _startPos;

		private long _readPos;

		public override bool CanRead => true;

		public override bool CanSeek => false;

		public override bool CanWrite => false;

		public override long Length => _inStream.Length;

		public override long Position
		{
			get
			{
				return _readPos;
			}
			set
			{
				if (value < _readPos)
				{
					ResetStream();
				}
				else
				{
					value -= _readPos;
				}
				byte[] buffer = new byte[1024];
				while (value > 0)
				{
					value -= Read(buffer, 0, (int)((value < 1024) ? value : 1024));
				}
			}
		}

		public DecompressionStream(WrapperDefines wrap, Stream inputStream, int extraBufferSize = 524288)
		{
			_wrapper = wrap;
			_inStream = inputStream;
			_startPos = inputStream.Position;
			_srcBuffer = new ByteSpan(new byte[extraBufferSize]);
			int inBufferSize = Fill();
			int blockSize;
			long num = _wrapper.DecompressBegin(ref _dctx, _srcBuffer.Buffer, ref inBufferSize, out blockSize, null, 0L);
			_srcBuffer.Position += inBufferSize;
			if (num < 0)
			{
				throw new Exception(num.ToString());
			}
			_dcmpBuffer = new ByteSpan(new byte[blockSize]);
		}

		public void ResetStream()
		{
			_inStream.Seek(_startPos, SeekOrigin.Begin);
			_decompressFinish = false;
			_srcBuffer.Clear();
			_dcmpBuffer.Clear();
			_wrapper.DecompressContextReset(_dctx);
			_readPos = 0L;
		}

		private int Fill()
		{
			int num = _srcBuffer.Length - _srcBuffer.Position;
			if (_srcBuffer.Length > 0 && _srcBuffer.Position >= num)
			{
				Array.Copy((byte[])_srcBuffer, _srcBuffer.Position, (byte[])_srcBuffer, 0, num);
				_srcBuffer.Length -= _srcBuffer.Position;
				_srcBuffer.Position = 0;
			}
			if (_srcBuffer.IdleCapacity > 0)
			{
				int num2 = _inStream.Read(_srcBuffer, _srcBuffer.Length, _srcBuffer.IdleCapacity);
				_srcBuffer.Length += num2;
			}
			return _srcBuffer.Length - _srcBuffer.Position;
		}

		public override void Flush()
		{
		}

		protected override void Dispose(bool disposing)
		{
			_wrapper.DecompressEnd(_dctx);
			_dctx = IntPtr.Zero;
			base.Dispose(disposing);
		}

		public override int Read(byte[] buffer, int offset, int count)
		{
			int num = 0;
			while (count > (num += _dcmpBuffer.Read(buffer, offset + num, count - num)) && !_decompressFinish)
			{
				int num2 = Fill();
				if (num2 <= 0)
				{
					return num;
				}
				DecompressStatus decompressStatus = _wrapper.DecompressUpdateEx(_dctx, _dcmpBuffer, 0, _dcmpBuffer.Capacity, _srcBuffer, _srcBuffer.Position, num2);
				if (decompressStatus.Expect < 0)
				{
					throw new Exception(decompressStatus.Expect.ToString());
				}
				if (decompressStatus.Expect == 0L)
				{
					_decompressFinish = true;
				}
				_srcBuffer.Position += (int)decompressStatus.ReadLen;
				_dcmpBuffer.Position = 0;
				_dcmpBuffer.Length = (int)decompressStatus.WriteLen;
			}
			_readPos += num;
			return num;
		}

		public int PeekByte()
		{
			if (_dcmpBuffer.Length <= _dcmpBuffer.Position)
			{
				int num = Fill();
				if (num <= 0)
				{
					return -1;
				}
				DecompressStatus decompressStatus = _wrapper.DecompressUpdateEx(_dctx, _dcmpBuffer, 0, _dcmpBuffer.Capacity, _srcBuffer, _srcBuffer.Position, num);
				if (decompressStatus.Expect < 0)
				{
					throw new Exception(decompressStatus.Expect.ToString());
				}
				if (decompressStatus.Expect == 0L)
				{
					_decompressFinish = true;
				}
				_srcBuffer.Position += (int)decompressStatus.ReadLen;
				_dcmpBuffer.Position = 0;
				_dcmpBuffer.Length = (int)decompressStatus.WriteLen;
			}
			return _dcmpBuffer.Buffer[_dcmpBuffer.Position];
		}

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

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

		public override void Write(byte[] buffer, int offset, int count)
		{
			throw new NotImplementedException();
		}
	}
	public class ByteSpan
	{
		public int Length;

		public readonly int Capacity;

		public int Position;

		public byte[] Buffer { get; }

		public int IdleCapacity => Capacity - Length;

		public ByteSpan(byte[] buffer)
		{
			Buffer = buffer;
			Capacity = Buffer.Length;
		}

		public void Clear()
		{
			Length = 0;
			Position = 0;
		}

		public int Write(byte[] src, int offset, int count)
		{
			int num = Math.Min(Capacity - Length, count);
			Array.Copy(src, offset, Buffer, Length, num);
			Length += num;
			return num;
		}

		public int Read(byte[] dst, int offset, int count)
		{
			count = Math.Min(Length - Position, count);
			Array.Copy(Buffer, Position, dst, offset, count);
			Position += count;
			return count;
		}

		public static implicit operator byte[](ByteSpan bs)
		{
			return bs.Buffer;
		}
	}
	public struct ReadOnlySpan
	{
		[CompilerGenerated]
		private int <length>P;

		private readonly byte[] _buffer;

		private int _position;

		public ReadOnlySpan(byte[] buffer, int length)
		{
			<length>P = length;
			_buffer = buffer;
			_position = 0;
		}

		public int Read(byte[] dst, int offset, int count)
		{
			count = Math.Min(<length>P - _position, count);
			Array.Copy(_buffer, _position, dst, offset, count);
			_position += count;
			return count;
		}

		public static implicit operator byte[](ReadOnlySpan s)
		{
			return s._buffer;
		}
	}
	public class DoubleBuffer
	{
		[CompilerGenerated]
		private Action <onReadBufferReadyAction>P;

		public const int Mb = 1048576;

		public ByteSpan WriteBuffer;

		private ByteSpan _readBuffer;

		private ByteSpan _midBuffer;

		private readonly Semaphore _readEnd;

		private readonly Semaphore _writeEnd;

		public DoubleBuffer(byte[] readingBuffer, byte[] writingBuffer, Action onReadBufferReadyAction)
		{
			<onReadBufferReadyAction>P = onReadBufferReadyAction;
			WriteBuffer = new ByteSpan(writingBuffer);
			_midBuffer = new ByteSpan(readingBuffer);
			_readEnd = new Semaphore(1, 1);
			_writeEnd = new Semaphore(0, 1);
			base..ctor();
		}

		public ByteSpan ReadBegin()
		{
			_writeEnd.WaitOne();
			return _readBuffer;
		}

		public void ReadEnd()
		{
			_readBuffer.Clear();
			_midBuffer = _readBuffer;
			_readBuffer = null;
			_readEnd.Release();
		}

		public ByteSpan SwapBuffer(bool triggerEvent = true)
		{
			ByteSpan result = SwapBegin();
			SwapEnd();
			Action action = <onReadBufferReadyAction>P;
			if (action != null)
			{
				action();
				return result;
			}
			return result;
		}

		public void WaitReadEnd()
		{
			_readEnd.WaitOne();
			_readEnd.Release();
		}

		private ByteSpan SwapBegin()
		{
			_readEnd.WaitOne();
			_readBuffer = WriteBuffer;
			WriteBuffer = _midBuffer;
			_midBuffer = null;
			return WriteBuffer;
		}

		private void SwapEnd()
		{
			_writeEnd.Release();
		}
	}
	public class LZ4API : WrapperDefines
	{
		public static readonly bool Avaliable;

		[DynDllImport("lz4wrap.dll", new string[] { "CompressBufferBound" })]
		protected static CompressBufferBoundFunc CompressBufferBound_;

		[DynDllImport("lz4wrap.dll", new string[] { "CompressBegin" })]
		protected static CompressBeginFunc CompressBegin_;

		[DynDllImport("lz4wrap.dll", new string[] { "CompressEnd" })]
		protected static CompressEndFunc CompressEnd_;

		[DynDllImport("lz4wrap.dll", new string[] { "CompressUpdate" })]
		protected static CompressUpdateFunc CompressUpdate_;

		[DynDllImport("lz4wrap.dll", new string[] { "CompressContextFree" })]
		protected static CompressContextFreeFunc CompressContextFree_;

		[DynDllImport("lz4wrap.dll", new string[] { "DecompressBegin" })]
		protected static DecompressBeginFunc DecompressBegin_;

		[DynDllImport("lz4wrap.dll", new string[] { "DecompressEnd" })]
		protected static DecompressEndFunc DecompressEnd_;

		[DynDllImport("lz4wrap.dll", new string[] { "DecompressUpdate" })]
		protected static DecompressUpdateFunc DecompressUpdate_;

		[DynDllImport("lz4wrap.dll", new string[] { "DecompressContextReset" })]
		protected static DecompressContextResetFunc DecompressContextReset_;

		static LZ4API()
		{
			Avaliable = true;
			string location = Assembly.GetAssembly(typeof(LZ4API)).Location;
			string path = string.Empty;
			try
			{
				if (!string.IsNullOrEmpty(location))
				{
					path = Path.GetDirectoryName(location) ?? string.Empty;
				}
				Dictionary<string, List<DynDllMapping>> dictionary = new Dictionary<string, List<DynDllMapping>> { 
				{
					"lz4wrap.dll",
					new List<DynDllMapping>(7)
					{
						DynDllMapping.op_Implicit("lz4wrap.dll"),
						DynDllMapping.op_Implicit("x64/lz4wrap.dll"),
						DynDllMapping.op_Implicit("plugins/x64/lz4wrap.dll"),
						DynDllMapping.op_Implicit("BepInEx/scripts/x64/lz4wrap.dll"),
						DynDllMapping.op_Implicit(Path.Combine(path, "lz4wrap.dll")),
						DynDllMapping.op_Implicit(Path.Combine(path, "x64/lz4wrap.dll")),
						DynDllMapping.op_Implicit(Path.Combine(path, "plugins/x64/lz4wrap.dll"))
					}
				} };
				DynDll.ResolveDynDllImports(typeof(LZ4API), dictionary);
			}
			catch (Exception arg)
			{
				Avaliable = false;
				Console.WriteLine($"Error: {arg}");
			}
		}

		public LZ4API()
		{
			CompressBufferBound = CompressBufferBound_;
			CompressBegin = CompressBegin_;
			CompressEnd = CompressEnd_;
			CompressUpdate = CompressUpdate_;
			CompressContextFree = CompressContextFree_;
			DecompressBegin = DecompressBegin_;
			DecompressEnd = DecompressEnd_;
			DecompressUpdate = DecompressUpdate_;
			DecompressContextReset = DecompressContextReset_;
		}
	}
	public class NoneAPI : WrapperDefines
	{
		public static readonly bool Avaliable;

		[DynDllImport("nonewrap.dll", new string[] { "CompressBufferBound" })]
		protected static CompressBufferBoundFunc CompressBufferBound_;

		[DynDllImport("nonewrap.dll", new string[] { "CompressBegin" })]
		protected static CompressBeginFunc CompressBegin_;

		[DynDllImport("nonewrap.dll", new string[] { "CompressEnd" })]
		protected static CompressEndFunc CompressEnd_;

		[DynDllImport("nonewrap.dll", new string[] { "CompressUpdate" })]
		protected static CompressUpdateFunc CompressUpdate_;

		[DynDllImport("nonewrap.dll", new string[] { "CompressContextFree" })]
		protected static CompressContextFreeFunc CompressContextFree_;

		[DynDllImport("nonewrap.dll", new string[] { "DecompressBegin" })]
		protected static DecompressBeginFunc DecompressBegin_;

		[DynDllImport("nonewrap.dll", new string[] { "DecompressEnd" })]
		protected static DecompressEndFunc DecompressEnd_;

		[DynDllImport("nonewrap.dll", new string[] { "DecompressUpdate" })]
		protected static DecompressUpdateFunc DecompressUpdate_;

		[DynDllImport("nonewrap.dll", new string[] { "DecompressContextReset" })]
		protected static DecompressContextResetFunc DecompressContextReset_;

		static NoneAPI()
		{
			Avaliable = true;
			string location = Assembly.GetAssembly(typeof(NoneAPI)).Location;
			string path = string.Empty;
			try
			{
				if (!string.IsNullOrEmpty(location))
				{
					path = Path.GetDirectoryName(location) ?? string.Empty;
				}
				Dictionary<string, List<DynDllMapping>> dictionary = new Dictionary<string, List<DynDllMapping>> { 
				{
					"nonewrap.dll",
					new List<DynDllMapping>(7)
					{
						DynDllMapping.op_Implicit("nonewrap.dll"),
						DynDllMapping.op_Implicit("x64/nonewrap.dll"),
						DynDllMapping.op_Implicit("plugins/x64/nonewrap.dll"),
						DynDllMapping.op_Implicit("BepInEx/scripts/x64/nonewrap.dll"),
						DynDllMapping.op_Implicit(Path.Combine(path, "nonewrap.dll")),
						DynDllMapping.op_Implicit(Path.Combine(path, "x64/nonewrap.dll")),
						DynDllMapping.op_Implicit(Path.Combine(path, "plugins/x64/nonewrap.dll"))
					}
				} };
				DynDll.ResolveDynDllImports(typeof(NoneAPI), dictionary);
			}
			catch (Exception arg)
			{
				Avaliable = false;
				Console.WriteLine($"Error: {arg}");
			}
		}

		public NoneAPI()
		{
			CompressBufferBound = CompressBufferBound_;
			CompressBegin = CompressBegin_;
			CompressEnd = CompressEnd_;
			CompressUpdate = CompressUpdate_;
			CompressContextFree = CompressContextFree_;
			DecompressBegin = DecompressBegin_;
			DecompressEnd = DecompressEnd_;
			DecompressUpdate = DecompressUpdate_;
			DecompressContextReset = DecompressContextReset_;
		}
	}
	internal class PeekableReader : BinaryReader
	{
		[CompilerGenerated]
		private DecompressionStream <input>P;

		public PeekableReader(DecompressionStream input)
		{
			<input>P = input;
			base..ctor(<input>P);
		}

		public override int PeekChar()
		{
			return <input>P.PeekByte();
		}
	}
	public struct DecompressStatus
	{
		public long WriteLen;

		public long ReadLen;

		public long Expect;
	}
	public class WrapperDefines
	{
		public delegate long CompressBufferBoundFunc(long inBufferSize);

		public delegate long CompressBeginFunc(out IntPtr ctx, int compressionLevel, byte[] outBuff, long outCapacity, byte[] dictBuffer = null, long dictSize = 0L);

		public delegate long CompressEndFunc(IntPtr ctx, byte[] dstBuffer, long dstCapacity);

		public delegate void CompressContextFreeFunc(IntPtr ctx);

		public delegate long DecompressBeginFunc(ref IntPtr pdctx, byte[] inBuffer, ref int inBufferSize, out int blockSize, byte[] dict = null, long dictSize = 0L);

		public delegate long DecompressEndFunc(IntPtr dctx);

		public delegate void DecompressContextResetFunc(IntPtr dctx);

		protected unsafe delegate long CompressUpdateFunc(IntPtr ctx, byte* dstBuffer, long dstCapacity, byte* srcBuffer, long srcSize);

		protected unsafe delegate long DecompressUpdateFunc(IntPtr dctx, byte* dstBuffer, ref long dstCapacity, byte* srcBuffer, ref long srcSize);

		public CompressBufferBoundFunc CompressBufferBound;

		public CompressBeginFunc CompressBegin;

		public CompressEndFunc CompressEnd;

		public CompressContextFreeFunc CompressContextFree;

		public DecompressBeginFunc DecompressBegin;

		public DecompressEndFunc DecompressEnd;

		public DecompressContextResetFunc DecompressContextReset;

		protected CompressUpdateFunc CompressUpdate;

		protected DecompressUpdateFunc DecompressUpdate;

		public unsafe long CompressUpdateEx(IntPtr ctx, byte[] dstBuffer, long dstOffset, byte[] srcBuffer, long srcOffset, long srcLen)
		{
			fixed (byte* ptr = dstBuffer)
			{
				fixed (byte* ptr2 = srcBuffer)
				{
					return CompressUpdate(ctx, ptr + dstOffset, dstBuffer.Length - dstOffset, ptr2 + srcOffset, srcLen - srcOffset);
				}
			}
		}

		public unsafe DecompressStatus DecompressUpdateEx(IntPtr dctx, byte[] dstBuffer, int dstOffset, int dstCount, byte[] srcBuffer, long srcOffset, long count)
		{
			long dstCapacity = Math.Min(dstCount, dstBuffer.Length - dstOffset);
			long expect;
			fixed (byte* ptr = dstBuffer)
			{
				fixed (byte* ptr2 = srcBuffer)
				{
					expect = DecompressUpdate(dctx, ptr + dstOffset, ref dstCapacity, ptr2 + srcOffset, ref count);
				}
			}
			DecompressStatus result = default(DecompressStatus);
			result.Expect = expect;
			result.ReadLen = count;
			result.WriteLen = dstCapacity;
			return result;
		}
	}
	public class ZstdAPI : WrapperDefines
	{
		public static readonly bool Avaliable;

		[DynDllImport("zstdwrap.dll", new string[] { "CompressBufferBound" })]
		protected static CompressBufferBoundFunc CompressBufferBound_;

		[DynDllImport("zstdwrap.dll", new string[] { "CompressBegin" })]
		protected static CompressBeginFunc CompressBegin_;

		[DynDllImport("zstdwrap.dll", new string[] { "CompressEnd" })]
		protected static CompressEndFunc CompressEnd_;

		[DynDllImport("zstdwrap.dll", new string[] { "CompressUpdate" })]
		protected static CompressUpdateFunc CompressUpdate_;

		[DynDllImport("zstdwrap.dll", new string[] { "CompressContextFree" })]
		protected static CompressContextFreeFunc CompressContextFree_;

		[DynDllImport("zstdwrap.dll", new string[] { "DecompressBegin" })]
		protected static DecompressBeginFunc DecompressBegin_;

		[DynDllImport("zstdwrap.dll", new string[] { "DecompressEnd" })]
		protected static DecompressEndFunc DecompressEnd_;

		[DynDllImport("zstdwrap.dll", new string[] { "DecompressUpdate" })]
		protected static DecompressUpdateFunc DecompressUpdate_;

		[DynDllImport("zstdwrap.dll", new string[] { "DecompressContextReset" })]
		protected static DecompressContextResetFunc DecompressContextReset_;

		static ZstdAPI()
		{
			Avaliable = true;
			string location = Assembly.GetAssembly(typeof(ZstdAPI)).Location;
			string path = string.Empty;
			try
			{
				if (!string.IsNullOrEmpty(location))
				{
					path = Path.GetDirectoryName(location) ?? string.Empty;
				}
				Dictionary<string, List<DynDllMapping>> dictionary = new Dictionary<string, List<DynDllMapping>> { 
				{
					"zstdwrap.dll",
					new List<DynDllMapping>(7)
					{
						DynDllMapping.op_Implicit("zstdwrap.dll"),
						DynDllMapping.op_Implicit("x64/zstdwrap.dll"),
						DynDllMapping.op_Implicit("plugins/x64/zstdwrap.dll"),
						DynDllMapping.op_Implicit("BepInEx/scripts/x64/zstdwrap.dll"),
						DynDllMapping.op_Implicit(Path.Combine(path, "zstdwrap.dll")),
						DynDllMapping.op_Implicit(Path.Combine(path, "x64/zstdwrap.dll")),
						DynDllMapping.op_Implicit(Path.Combine(path, "plugins/x64/zstdwrap.dll"))
					}
				} };
				DynDll.ResolveDynDllImports(typeof(ZstdAPI), dictionary);
			}
			catch (Exception arg)
			{
				Avaliable = false;
				Console.WriteLine($"Error: {arg}");
			}
		}

		public ZstdAPI()
		{
			CompressBufferBound = CompressBufferBound_;
			CompressBegin = CompressBegin_;
			CompressEnd = CompressEnd_;
			CompressUpdate = CompressUpdate_;
			CompressContextFree = CompressContextFree_;
			DecompressBegin = DecompressBegin_;
			DecompressEnd = DecompressEnd_;
			DecompressUpdate = DecompressUpdate_;
			DecompressContextReset = DecompressContextReset_;
		}
	}
}

plugins/System.Runtime.CompilerServices.Unsafe.dll

Decompiled 11 months ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using Microsoft.CodeAnalysis;

[assembly: AssemblyProduct("Microsoft® .NET Framework")]
[assembly: CLSCompliant(false)]
[assembly: AssemblyMetadata(".NETFrameworkAssembly", "")]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: CompilationRelaxations(8)]
[assembly: AssemblyDescription("System.Runtime.CompilerServices.Unsafe")]
[assembly: AssemblyFileVersion("6.0.21.52210")]
[assembly: AssemblyInformationalVersion("6.0.0")]
[assembly: AssemblyTitle("System.Runtime.CompilerServices.Unsafe")]
[assembly: AssemblyMetadata("Serviceable", "True")]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: AssemblyMetadata("IsTrimmable", "True")]
[assembly: AssemblyCopyright("© Microsoft Corporation.  All rights reserved.")]
[assembly: AssemblyCompany("Microsoft Corporation")]
[assembly: AssemblyVersion("6.0.0.0")]
namespace System.Runtime.CompilerServices
{
	public static class Unsafe
	{
		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static T Read<T>(void* source)
		{
			return Unsafe.Read<T>(source);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static T ReadUnaligned<T>(void* source)
		{
			return Unsafe.ReadUnaligned<T>(source);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static T ReadUnaligned<T>(ref byte source)
		{
			return Unsafe.ReadUnaligned<T>(ref source);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static void Write<T>(void* destination, T value)
		{
			Unsafe.Write(destination, value);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static void WriteUnaligned<T>(void* destination, T value)
		{
			Unsafe.WriteUnaligned(destination, value);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static void WriteUnaligned<T>(ref byte destination, T value)
		{
			Unsafe.WriteUnaligned(ref destination, value);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static void Copy<T>(void* destination, ref T source)
		{
			Unsafe.Write(destination, source);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static void Copy<T>(ref T destination, void* source)
		{
			destination = Unsafe.Read<T>(source);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static void* AsPointer<T>(ref T value)
		{
			return Unsafe.AsPointer(ref value);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static void SkipInit<T>(out T value)
		{
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static int SizeOf<T>()
		{
			return Unsafe.SizeOf<T>();
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static void CopyBlock(void* destination, void* source, uint byteCount)
		{
			// IL cpblk instruction
			Unsafe.CopyBlock(destination, source, byteCount);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static void CopyBlock(ref byte destination, ref byte source, uint byteCount)
		{
			// IL cpblk instruction
			Unsafe.CopyBlock(ref destination, ref source, byteCount);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static void CopyBlockUnaligned(void* destination, void* source, uint byteCount)
		{
			// IL cpblk instruction
			Unsafe.CopyBlockUnaligned(destination, source, byteCount);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static void CopyBlockUnaligned(ref byte destination, ref byte source, uint byteCount)
		{
			// IL cpblk instruction
			Unsafe.CopyBlockUnaligned(ref destination, ref source, byteCount);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static void InitBlock(void* startAddress, byte value, uint byteCount)
		{
			// IL initblk instruction
			Unsafe.InitBlock(startAddress, value, byteCount);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static void InitBlock(ref byte startAddress, byte value, uint byteCount)
		{
			// IL initblk instruction
			Unsafe.InitBlock(ref startAddress, value, byteCount);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static void InitBlockUnaligned(void* startAddress, byte value, uint byteCount)
		{
			// IL initblk instruction
			Unsafe.InitBlockUnaligned(startAddress, value, byteCount);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static void InitBlockUnaligned(ref byte startAddress, byte value, uint byteCount)
		{
			// IL initblk instruction
			Unsafe.InitBlockUnaligned(ref startAddress, value, byteCount);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static T As<T>(object o) where T : class
		{
			return (T)o;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static ref T AsRef<T>(void* source)
		{
			return ref *(T*)source;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static ref T AsRef<T>(in T source)
		{
			return ref source;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static ref TTo As<TFrom, TTo>(ref TFrom source)
		{
			return ref Unsafe.As<TFrom, TTo>(ref source);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static ref T Unbox<T>(object box) where T : struct
		{
			return ref (T)box;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static ref T Add<T>(ref T source, int elementOffset)
		{
			return ref Unsafe.Add(ref source, elementOffset);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static void* Add<T>(void* source, int elementOffset)
		{
			return (byte*)source + (nint)elementOffset * (nint)Unsafe.SizeOf<T>();
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static ref T Add<T>(ref T source, IntPtr elementOffset)
		{
			return ref Unsafe.Add(ref source, elementOffset);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static ref T Add<T>(ref T source, [System.Runtime.Versioning.NonVersionable] nuint elementOffset)
		{
			return ref Unsafe.Add(ref source, elementOffset);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static ref T AddByteOffset<T>(ref T source, IntPtr byteOffset)
		{
			return ref Unsafe.AddByteOffset(ref source, byteOffset);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static ref T AddByteOffset<T>(ref T source, [System.Runtime.Versioning.NonVersionable] nuint byteOffset)
		{
			return ref Unsafe.AddByteOffset(ref source, byteOffset);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static ref T Subtract<T>(ref T source, int elementOffset)
		{
			return ref Unsafe.Subtract(ref source, elementOffset);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static void* Subtract<T>(void* source, int elementOffset)
		{
			return (byte*)source - (nint)elementOffset * (nint)Unsafe.SizeOf<T>();
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static ref T Subtract<T>(ref T source, IntPtr elementOffset)
		{
			return ref Unsafe.Subtract(ref source, elementOffset);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static ref T Subtract<T>(ref T source, [System.Runtime.Versioning.NonVersionable] nuint elementOffset)
		{
			return ref Unsafe.Subtract(ref source, elementOffset);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static ref T SubtractByteOffset<T>(ref T source, IntPtr byteOffset)
		{
			return ref Unsafe.SubtractByteOffset(ref source, byteOffset);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static ref T SubtractByteOffset<T>(ref T source, [System.Runtime.Versioning.NonVersionable] nuint byteOffset)
		{
			return ref Unsafe.SubtractByteOffset(ref source, byteOffset);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static IntPtr ByteOffset<T>(ref T origin, ref T target)
		{
			return Unsafe.ByteOffset(target: ref target, origin: ref origin);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static bool AreSame<T>(ref T left, ref T right)
		{
			return Unsafe.AreSame(ref left, ref right);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static bool IsAddressGreaterThan<T>(ref T left, ref T right)
		{
			return Unsafe.IsAddressGreaterThan(ref left, ref right);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static bool IsAddressLessThan<T>(ref T left, ref T right)
		{
			return Unsafe.IsAddressLessThan(ref left, ref right);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static bool IsNullRef<T>(ref T source)
		{
			return Unsafe.AsPointer(ref source) == null;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static ref T NullRef<T>()
		{
			return ref *(T*)null;
		}
	}
}
namespace System.Runtime.Versioning
{
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Constructor | AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
	internal sealed class NonVersionableAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	internal sealed class IsReadOnlyAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	[Microsoft.CodeAnalysis.Embedded]
	[CompilerGenerated]
	internal sealed class NativeIntegerAttribute : Attribute
	{
		public readonly bool[] TransformFlags;

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

		public NativeIntegerAttribute(bool[] A_0)
		{
			TransformFlags = A_0;
		}
	}
}
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}