Decompiled source of OdinEyeClient v1.2.31

plugins/OdinEye.Client.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
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;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using OdinEye.Client.Counters;
using OdinEye.Client.Events;
using OdinEye.Client.Hud;
using OdinEye.Client.Patches;
using OdinEye.Client.Stats;
using OdinEye.Client.Submission;
using OdinEye.Models;
using OdinEye.Models.Api;
using Steamworks;
using UnityEngine;
using Utf8Json;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("OdinEye.Client")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("OdinEye.Client")]
[assembly: AssemblyCopyright("Copyright ©  2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("2f6e4b8e-6a3f-4b1a-9b0e-8f6c5b4a3d2e")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8.1", FrameworkDisplayName = ".NET Framework 4.8.1")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace OdinEye.Client
{
	[BepInPlugin("org.bepinex.plugins.odineye.client", "odineye.client", "1.0.0.0")]
	public class OdinEyeClientPlugin : BaseUnityPlugin
	{
		private static readonly TimeSpan CheckInterval = TimeSpan.FromSeconds(30.0);

		private static readonly TimeSpan HeartbeatInterval = TimeSpan.FromMinutes(5.0);

		private static readonly TimeSpan EventFlushInterval = TimeSpan.FromSeconds(5.0);

		private static readonly TimeSpan OutpostScanInterval = TimeSpan.FromSeconds(60.0);

		private static readonly TimeSpan SeedTimeout = TimeSpan.FromSeconds(10.0);

		private static readonly TimeSpan ClockUpdateInterval = TimeSpan.FromSeconds(1.0);

		private IPlayerStatsSource statsSource;

		private IStatsSubmitter statsSubmitter;

		private ICheatStatusSubmitter cheatStatusSubmitter;

		private ChangeDrivenPolicy policy;

		private Guid? currentPlayerId;

		private Uri serverBaseUri;

		private HttpClient seedClient;

		private HttpEventSubmitter eventSubmitter;

		private CustomCounterStore counters;

		private OutpostAnchorStore outpostAnchors;

		private DateTime nextOutpostScanUtc;

		private IPlayerStatsSource fullStatsSource;

		private volatile bool seeded;

		private DateTime seedDeadlineUtc;

		private bool loginSubmitted;

		private DateTime nextEventFlushUtc;

		private volatile IReadOnlyDictionary<string, float> lastSubmittedStats;

		private ConfigEntry<bool> showClock;

		private ClockHudElement clockHud;

		private DateTime nextClockUpdateUtc;

		private void Awake()
		{
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Expected O, but got Unknown
			showClock = ((BaseUnityPlugin)this).Config.Bind<bool>("Hud", "ShowClock", true, "Show a small in-game clock just below the minimap (VALSER-40/41's own \"temporal hours\" reading -- dawn is always 6:00 AM, dusk always 6:00 PM). Purely local/visual -- reads nothing from your character and sends nothing anywhere, unaffected by ServerUrl below.");
			clockHud = new ClockHudElement();
			ConfigEntry<string> val = ((BaseUnityPlugin)this).Config.Bind<string>("Server", "ServerUrl", string.Empty, "The OdinEye server's base URL to submit this character's lifetime stats to (e.g. http://yourserver.com:2469/). Leave empty to disable stats/cheat-status submission -- nothing is read from your character or sent anywhere unless this is set. Does not affect the HUD clock above.");
			if (string.IsNullOrWhiteSpace(val.Value))
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)"OdinEye client: ServerUrl not configured, character-stats submission is disabled.");
				return;
			}
			if (!Uri.TryCreate(EnsureTrailingSlash(val.Value), UriKind.Absolute, out Uri result))
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("OdinEye client: ServerUrl '" + val.Value + "' is not a valid URL. Character-stats submission is disabled."));
				return;
			}
			serverBaseUri = result;
			statsSource = new PlayerProfileStatsSource();
			statsSubmitter = new HttpStatsSubmitter(result, delegate(string message)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)message);
			});
			cheatStatusSubmitter = new HttpCheatStatusSubmitter(result, delegate(string message)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)message);
			});
			policy = new ChangeDrivenPolicy(CheckInterval, HeartbeatInterval);
			seedClient = new HttpClient();
			eventSubmitter = new HttpEventSubmitter(result, delegate(string message)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)message);
			});
			ClientRuntime.LogWarning = delegate(string message)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)message);
			};
			ApplyPatches();
			((BaseUnityPlugin)this).Logger.LogInfo((object)$"OdinEye client: character-stats submission enabled, reporting to {result}");
		}

		private void ApplyPatches()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			Harmony val = new Harmony("org.bepinex.plugins.odineye.client");
			Type[] types = typeof(OdinEyeClientPlugin).Assembly.GetTypes();
			foreach (Type type in types)
			{
				if (type.IsDefined(typeof(HarmonyPatch), inherit: false))
				{
					try
					{
						val.CreateClassProcessor(type).Patch();
					}
					catch (Exception ex)
					{
						((BaseUnityPlugin)this).Logger.LogWarning((object)("OdinEye client: could not apply " + type.Name + " (" + ex.Message + "); the achievement it feeds will not progress until this is updated for the current game version."));
					}
				}
			}
		}

		private void OnDestroy()
		{
			EndSession();
			(statsSubmitter as IDisposable)?.Dispose();
			(cheatStatusSubmitter as IDisposable)?.Dispose();
			eventSubmitter?.Dispose();
			HttpClient obj = seedClient;
			if (obj != null)
			{
				((HttpMessageInvoker)obj).Dispose();
			}
		}

		private void EndSession()
		{
			ClientRuntime.Counters = null;
			counters?.Flush();
			counters = null;
			outpostAnchors?.Flush();
			outpostAnchors = null;
			fullStatsSource = null;
			currentPlayerId = null;
			loginSubmitted = false;
			lastSubmittedStats = null;
		}

		private void Update()
		{
			UpdateClock();
			if (statsSubmitter == null)
			{
				return;
			}
			if ((Object)(object)Player.m_localPlayer == (Object)null)
			{
				EndSession();
				return;
			}
			DateTime utcNow = DateTime.UtcNow;
			if (!currentPlayerId.HasValue)
			{
				currentPlayerId = ComputeLocalPlayerId();
				if (!currentPlayerId.HasValue)
				{
					return;
				}
				BeginSession(currentPlayerId.Value, utcNow);
			}
			Guid value = currentPlayerId.Value;
			if (utcNow >= nextEventFlushUtc)
			{
				nextEventFlushUtc = utcNow + EventFlushInterval;
				eventSubmitter.Flush(value, ClientRuntime.Events);
			}
			if (utcNow >= nextOutpostScanUtc)
			{
				nextOutpostScanUtc = utcNow + OutpostScanInterval;
				OutpostTracking.Scan(outpostAnchors);
				outpostAnchors.Flush();
			}
			if (!loginSubmitted)
			{
				if (seeded || !(utcNow < seedDeadlineUtc))
				{
					loginSubmitted = true;
					policy.OnLogin(utcNow);
					SubmitAll(value, utcNow);
				}
			}
			else if (policy.IsCheckDue(utcNow))
			{
				counters?.Flush();
				IReadOnlyDictionary<string, float> stats = fullStatsSource.GetStats();
				if (policy.ShouldSubmit(utcNow, StatsChange.HasChanged(lastSubmittedStats, stats)))
				{
					SubmitAll(value, utcNow);
				}
			}
		}

		private void BeginSession(Guid playerId, DateTime nowUtc)
		{
			counters = new CustomCounterStore(Path.Combine(Paths.ConfigPath, $"odineye.client.counters.{playerId:N}.json"), delegate(string message)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)message);
			});
			outpostAnchors = new OutpostAnchorStore(Path.Combine(Paths.ConfigPath, $"odineye.client.outposts.{playerId:N}.json"), delegate(string message)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)message);
			});
			fullStatsSource = new CounterAugmentedStatsSource(statsSource, counters, StationNames.Get, NorthTracking.CurrentNorthZ, NorthTracking.IsInDeepNorth, BoatTracking.IsOnBoat, SwampTracking.IsInSwamp, OvenTracking.IsNearOven);
			seeded = false;
			seedDeadlineUtc = nowUtc + SeedTimeout;
			loginSubmitted = false;
			lastSubmittedStats = null;
			nextEventFlushUtc = nowUtc + EventFlushInterval;
			nextOutpostScanUtc = nowUtc + OutpostScanInterval;
			CustomCounterStore store = counters;
			Task.Run(async delegate
			{
				Dictionary<string, float> serverValues = await StatsSeeder.FetchAsync(seedClient, serverBaseUri, playerId, SeedTimeout, delegate(string message)
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)message);
				}).ConfigureAwait(continueOnCapturedContext: false);
				store.SeedFrom(serverValues);
				if (counters == store)
				{
					seeded = true;
				}
			});
			ClientRuntime.Counters = counters;
		}

		private void SubmitAll(Guid playerId, DateTime nowUtc)
		{
			SubmitCurrentStats(playerId);
			SubmitCheatStatus(playerId);
			policy.MarkSubmitted(nowUtc);
		}

		private void UpdateClock()
		{
			if (!showClock.Value)
			{
				return;
			}
			DateTime utcNow = DateTime.UtcNow;
			if (!(utcNow < nextClockUpdateUtc))
			{
				nextClockUpdateUtc = utcNow + ClockUpdateInterval;
				double? totalSeconds = EnvManTimeReader.GetTotalSeconds();
				if (totalSeconds.HasValue)
				{
					clockHud.SetText(TemporalClock.Format(totalSeconds.Value));
				}
			}
		}

		private void SubmitCurrentStats(Guid playerId)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Expected O, but got Unknown
			IReadOnlyDictionary<string, float> stats = fullStatsSource.GetStats();
			if (stats.Count == 0)
			{
				return;
			}
			SubmissionMeta meta = new SubmissionMeta
			{
				PlayerId = ClientRuntime.LocalPlayerId().ToString(),
				ClientVersion = typeof(OdinEyeClientPlugin).Assembly.GetName().Version.ToString()
			};
			CharacterStatsSubmission val = CharacterStatsPayloadBuilder.Build(stats, meta);
			if (val.Stats.Count == 0)
			{
				return;
			}
			lastSubmittedStats = stats;
			statsSubmitter.Submit(playerId, val, delegate(bool accepted)
			{
				if (!accepted)
				{
					lastSubmittedStats = null;
				}
			});
		}

		private void SubmitCheatStatus(Guid playerId)
		{
			bool? flag = CheatStatusReader.IsCheated();
			if (flag.HasValue)
			{
				cheatStatusSubmitter.Submit(playerId, flag.Value, CheatBypassReader.IsEnabled());
			}
		}

		private static Guid? ComputeLocalPlayerId()
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			Game instance = Game.instance;
			PlayerProfile val = ((instance != null) ? instance.GetPlayerProfile() : null);
			if (val == null)
			{
				return null;
			}
			string name = val.GetName();
			if (string.IsNullOrEmpty(name))
			{
				return null;
			}
			return NameBasedGuid.NewPlayerGuid(SteamUser.GetSteamID().m_SteamID.ToString(), name);
		}

		private static string EnsureTrailingSlash(string url)
		{
			if (!url.EndsWith("/", StringComparison.Ordinal))
			{
				return url + "/";
			}
			return url;
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "OdinEye.Client";

		public const string PLUGIN_NAME = "";

		public const string PLUGIN_VERSION = "1.0.0.0";
	}
}
namespace OdinEye.Client.Patches
{
	[HarmonyPatch]
	public static class ArrowHitPatch
	{
		private static readonly FieldInfo OwnerField = AccessTools.Field(typeof(Projectile), "m_owner");

		private static readonly FieldInfo SkillField = AccessTools.Field(typeof(Projectile), "m_skill");

		[HarmonyPrepare]
		private static bool Prepare()
		{
			if (TargetMethod() != null && OwnerField != null)
			{
				return SkillField != null;
			}
			return false;
		}

		private static MethodBase TargetMethod()
		{
			return AccessTools.Method(typeof(Projectile), "OnHit", (Type[])null, (Type[])null);
		}

		[HarmonyPrefix]
		private static void Prefix(Projectile __instance, object[] __args)
		{
			ClientRuntime.Guard("arrow hit count", delegate
			{
				CustomCounterStore counters = ClientRuntime.Counters;
				if (counters != null && !((Object)(object)Player.m_localPlayer == (Object)null))
				{
					object obj = __args[0];
					object obj2 = ((obj is Component) ? obj : null);
					Character val = ((obj2 != null) ? ((Component)obj2).GetComponentInParent<Character>() : null);
					if (CounterRules.CountsAsArrowHitOnEnemy(OwnerField.GetValue(__instance) == Player.m_localPlayer, SkillField.GetValue(__instance)?.ToString(), (Object)(object)val != (Object)null, (Object)(object)val != (Object)null && val.IsPlayer(), (Object)(object)val != (Object)null && val.IsTamed(), (Object)(object)val != (Object)null && val.IsDead()))
					{
						counters.Increment("Custom:ArrowHitsEnemy");
					}
				}
			});
		}
	}
	public static class BedPatches
	{
		[HarmonyPatch(typeof(WearNTear), "Remove")]
		public static class BedRemovedPatch
		{
			private static readonly MethodInfo GetOwner = AccessTools.Method(typeof(Bed), "GetOwner", (Type[])null, (Type[])null);

			[HarmonyPrepare]
			private static bool Prepare()
			{
				return GetOwner != null;
			}

			[HarmonyPrefix]
			private static void Prefix(WearNTear __instance)
			{
				ClientRuntime.Guard("bed removal report", delegate
				{
					//IL_0037: Unknown result type (might be due to invalid IL or missing references)
					//IL_003c: Unknown result type (might be due to invalid IL or missing references)
					//IL_0053: Unknown result type (might be due to invalid IL or missing references)
					//IL_0059: Unknown result type (might be due to invalid IL or missing references)
					//IL_005f: Unknown result type (might be due to invalid IL or missing references)
					if (ClientRuntime.Counters != null)
					{
						Bed component = ((Component)__instance).GetComponent<Bed>();
						if (!((Object)(object)component == (Object)null))
						{
							ClientRuntime.Counters.Increment("Custom:BedsDestroyed");
							Vector3 spawnPoint = component.GetSpawnPoint();
							ClientEvent val = BedEvents.Removed((long)GetOwner.Invoke(component, null), ClientRuntime.LocalPlayerId(), spawnPoint.x, spawnPoint.y, spawnPoint.z);
							if (val != null)
							{
								ClientRuntime.Events.Enqueue(val);
							}
						}
					}
				});
			}
		}

		[HarmonyPatch(typeof(Game), "FindSpawnPoint")]
		public static class BedMissingPatch
		{
			[HarmonyPrefix]
			private static void Prefix(Game __instance, out object __state)
			{
				__state = null;
				object captured = null;
				ClientRuntime.Guard("respawn check", delegate
				{
					//IL_0022: Unknown result type (might be due to invalid IL or missing references)
					PlayerProfile playerProfile = __instance.GetPlayerProfile();
					if (ClientRuntime.Counters != null && playerProfile != null && playerProfile.HaveCustomSpawnPoint())
					{
						captured = playerProfile.GetCustomSpawnPoint();
					}
				});
				__state = captured;
			}

			[HarmonyPostfix]
			private static void Postfix(Game __instance, object __state)
			{
				if (__state == null)
				{
					return;
				}
				ClientRuntime.Guard("respawn report", delegate
				{
					//IL_001e: Unknown result type (might be due to invalid IL or missing references)
					//IL_0023: Unknown result type (might be due to invalid IL or missing references)
					//IL_0029: Unknown result type (might be due to invalid IL or missing references)
					//IL_002f: Unknown result type (might be due to invalid IL or missing references)
					//IL_0035: Unknown result type (might be due to invalid IL or missing references)
					PlayerProfile playerProfile = __instance.GetPlayerProfile();
					if (playerProfile != null && !playerProfile.HaveCustomSpawnPoint())
					{
						Vector3 val = (Vector3)__state;
						ClientRuntime.Events.Enqueue(BedEvents.MissingAtRespawn(val.x, val.y, val.z));
					}
				});
			}
		}
	}
	internal static class ClientRuntime
	{
		public static volatile CustomCounterStore Counters;

		public static readonly ClientEventQueue Events = new ClientEventQueue();

		public static Action<string> LogWarning = delegate
		{
		};

		public static long LocalPlayerId()
		{
			Game instance = Game.instance;
			long? obj;
			if (instance == null)
			{
				obj = null;
			}
			else
			{
				PlayerProfile playerProfile = instance.GetPlayerProfile();
				obj = ((playerProfile != null) ? new long?(playerProfile.GetPlayerID()) : ((long?)null));
			}
			long? num = obj;
			return num.GetValueOrDefault();
		}

		public static void Guard(string what, Action action)
		{
			try
			{
				action();
			}
			catch (Exception ex)
			{
				LogWarning("OdinEye client: " + what + " failed: " + ex.Message);
			}
		}
	}
	public static class CookingStationPatches
	{
		[HarmonyPatch(typeof(CookingStation), "OnInteract")]
		public static class OnInteractPatch
		{
			[HarmonyPrepare]
			private static bool Prepare()
			{
				return Available;
			}

			[HarmonyPrefix]
			private static void Prefix(CookingStation __instance, Humanoid user)
			{
				ClientRuntime.Guard("cooking station check", delegate
				{
					nextRemovalProductName = null;
					nextRemovalIsBurnt = false;
					if (ClientRuntime.Counters != null && (object)user == Player.m_localPlayer)
					{
						(string, string)? tuple = NextFinishedSlot(__instance);
						if (tuple.HasValue)
						{
							if (tuple.Value.Item1 == "Burnt")
							{
								nextRemovalIsBurnt = true;
							}
							else
							{
								nextRemovalProductName = tuple.Value.Item2;
							}
						}
					}
				});
			}

			[HarmonyPostfix]
			private static void Postfix()
			{
				nextRemovalProductName = null;
				nextRemovalIsBurnt = false;
			}
		}

		[HarmonyPatch(typeof(ZNetView), "InvokeRPC", new Type[]
		{
			typeof(string),
			typeof(object[])
		})]
		public static class RemoveDoneItemPatch
		{
			[HarmonyPrefix]
			private static void Prefix(object[] __args)
			{
				if (!(__args[0] is string text) || text != "RPC_RemoveDoneItem" || (nextRemovalProductName == null && !nextRemovalIsBurnt))
				{
					return;
				}
				string productName = nextRemovalProductName;
				bool isBurnt = nextRemovalIsBurnt;
				nextRemovalProductName = null;
				nextRemovalIsBurnt = false;
				ClientRuntime.Guard("cooking station count", delegate
				{
					int amountTaken = ((!(__args[1] is object[] array) || array.Length <= 1) ? 1 : Convert.ToInt32(array[1]));
					if (productName != null)
					{
						int num = CounterRules.BreadToCount(itemIsDone: true, productName, amountTaken);
						if (num > 0)
						{
							ClientRuntime.Counters?.Increment("Custom:BreadCollected", num);
						}
						int num2 = CounterRules.CookedChickenMeatToCount(itemIsDone: true, productName, amountTaken);
						if (num2 > 0)
						{
							ClientRuntime.Counters?.Increment("Custom:ChickenMeatCooked", num2);
						}
						int num3 = CounterRules.LoxPieToCount(itemIsDone: true, productName, amountTaken);
						if (num3 > 0)
						{
							ClientRuntime.Counters?.Increment("Custom:LoxPiesCooked", num3);
						}
					}
					if (isBurnt)
					{
						int num4 = CounterRules.FoodBurntToCoal(isBurntStatus: true, amountTaken);
						if (num4 > 0)
						{
							ClientRuntime.Counters?.Increment("Custom:FoodBurntToCoal", num4);
						}
					}
				});
			}
		}

		private static string nextRemovalProductName;

		private static bool nextRemovalIsBurnt;

		private static readonly MethodInfo GetSlot = AccessTools.Method(typeof(CookingStation), "GetSlot", (Type[])null, (Type[])null);

		private static readonly MethodInfo GetItemConversion = AccessTools.Method(typeof(CookingStation), "GetItemConversion", (Type[])null, (Type[])null);

		private static bool Available
		{
			get
			{
				if (GetSlot != null)
				{
					return GetItemConversion != null;
				}
				return false;
			}
		}

		private static (string Status, string ProductName)? NextFinishedSlot(CookingStation station)
		{
			for (int i = 0; i < station.m_slots.Length; i++)
			{
				object[] array = new object[5] { i, null, 0f, null, false };
				GetSlot.Invoke(station, array);
				string text = array[1] as string;
				string text2 = array[3]?.ToString();
				if (!string.IsNullOrEmpty(text) && (!(text2 != "Done") || !(text2 != "Burnt")))
				{
					if (text2 != "Done")
					{
						return ("Burnt", null);
					}
					object obj = GetItemConversion.Invoke(station, new object[1] { text });
					object? obj2 = obj?.GetType().GetField("m_to")?.GetValue(obj);
					Object val = (Object)((obj2 is Object) ? obj2 : null);
					return ("Done", (val != null) ? val.name : null);
				}
			}
			return null;
		}
	}
	[HarmonyPatch(typeof(Fermenter), "Interact")]
	public static class FermenterTapPatch
	{
		private static readonly MethodInfo GetStatus = AccessTools.Method(typeof(Fermenter), "GetStatus", (Type[])null, (Type[])null);

		private static readonly MethodInfo GetContent = AccessTools.Method(typeof(Fermenter), "GetContent", (Type[])null, (Type[])null);

		private static bool Available
		{
			get
			{
				if (GetStatus != null)
				{
					return GetContent != null;
				}
				return false;
			}
		}

		[HarmonyPrepare]
		private static bool Prepare()
		{
			return Available;
		}

		[HarmonyPrefix]
		private static void Prefix(Fermenter __instance, Humanoid user)
		{
			ClientRuntime.Guard("fermenter tap check", delegate
			{
				if (ClientRuntime.Counters != null && (object)user == Player.m_localPlayer)
				{
					bool flag = GetStatus.Invoke(__instance, null)?.ToString() == "Ready";
					int contentHash = (flag ? ((int)GetContent.Invoke(__instance, null)) : 0);
					int num = CounterRules.MeadsToCount(flag, ((contentHash == 0) ? null : __instance.m_conversion?.FirstOrDefault((Func<ItemConversion, bool>)((ItemConversion c) => (Object)(object)c?.m_from != (Object)null && StringExtensionMethods.GetStableHashCode(((Object)((Component)c.m_from).gameObject).name) == contentHash)))?.m_producedItems ?? 0);
					if (num > 0)
					{
						ClientRuntime.Counters.Increment("Custom:MeadsMade", num);
					}
				}
			});
		}
	}
	[HarmonyPatch(typeof(Character), "ApplyDamage")]
	public static class IncomingHitPatch
	{
		[HarmonyPostfix]
		private static void Postfix(Character __instance, HitData hit)
		{
			ClientRuntime.Guard("incoming hit count", delegate
			{
				if (ClientRuntime.Counters != null && hit != null && !((Object)(object)__instance == (Object)null) && (object)__instance == Player.m_localPlayer)
				{
					if (CounterRules.CountsAsPoisonDeath(targetIsLocalPlayer: true, __instance.IsDead(), hit.m_damage.m_poison))
					{
						ClientRuntime.Counters.Increment("Custom:PoisonDeaths");
					}
					Character attacker = hit.GetAttacker();
					string attackerPrefabName = (((Object)(object)attacker == (Object)null) ? null : Utils.GetPrefabName(((Component)attacker).gameObject));
					if (CounterRules.CountsAsLeechHit(targetIsLocalPlayer: true, attackerPrefabName))
					{
						ClientRuntime.Counters.Increment("Custom:LeechHits");
					}
				}
			});
		}
	}
	[HarmonyPatch(typeof(Humanoid), "Pickup")]
	public static class ItemPickupPatch
	{
		[HarmonyPrefix]
		private static void Prefix(Humanoid __instance, GameObject go, out object __state)
		{
			__state = null;
			object captured = null;
			ClientRuntime.Guard("item pickup check", delegate
			{
				if (ClientRuntime.Counters != null && (object)__instance == Player.m_localPlayer && !((Object)(object)go == (Object)null))
				{
					ItemData val = go.GetComponent<ItemDrop>()?.m_itemData;
					if ((Object)(object)val?.m_dropPrefab != (Object)null)
					{
						captured = (Utils.GetPrefabName(val.m_dropPrefab), val.m_stack);
					}
				}
			});
			__state = captured;
		}

		[HarmonyPostfix]
		private static void Postfix(bool __result, object __state)
		{
			ClientRuntime.Guard("item pickup count", delegate
			{
				if (__result && __state is ValueTuple<string, int>)
				{
					(string, int) tuple = ((string, int))__state;
					string item = tuple.Item1;
					int item2 = tuple.Item2;
					CustomCounterStore counters = ClientRuntime.Counters;
					int num = CounterRules.DwarfEyesToCount(byLocalPlayer: true, pickupSucceeded: true, item, item2);
					if (num > 0)
					{
						counters?.Increment("Custom:DwarfEyesTouched", num);
					}
					int num2 = CounterRules.GuckToCount(byLocalPlayer: true, pickupSucceeded: true, item, item2);
					if (num2 > 0)
					{
						counters?.Increment("Custom:GuckCollected", num2);
					}
					int num3 = CounterRules.BloodBagToCount(byLocalPlayer: true, pickupSucceeded: true, item, item2);
					if (num3 > 0)
					{
						counters?.Increment("Custom:BloodBagsCollected", num3);
					}
					int num4 = CounterRules.ElderBarkToCount(byLocalPlayer: true, pickupSucceeded: true, item, item2);
					if (num4 > 0)
					{
						counters?.Increment("Custom:ElderBarkCollected", num4);
					}
					int num5 = CounterRules.WoodToCount(byLocalPlayer: true, pickupSucceeded: true, item, item2);
					if (num5 > 0)
					{
						counters?.Increment("Custom:WoodCollected", num5);
					}
					int num6 = CounterRules.StoneToCount(byLocalPlayer: true, pickupSucceeded: true, item, item2);
					if (num6 > 0)
					{
						counters?.Increment("Custom:StoneCollected", num6);
					}
					int num7 = CounterRules.ResinToCount(byLocalPlayer: true, pickupSucceeded: true, item, item2);
					if (num7 > 0)
					{
						counters?.Increment("Custom:ResinHandled", num7);
					}
				}
			});
		}
	}
	[HarmonyPatch(typeof(MineRock5), "DamageArea")]
	public static class MudPilePatch
	{
		[HarmonyPostfix]
		private static void Postfix(MineRock5 __instance, HitData hit, bool ___m_allDestroyed)
		{
			ClientRuntime.Guard("mud pile count", delegate
			{
				if (ClientRuntime.Counters != null && hit != null && !((Object)(object)__instance == (Object)null) && ___m_allDestroyed)
				{
					bool byLocalPlayer = (object)hit.GetAttacker() == Player.m_localPlayer;
					string prefabName = Utils.GetPrefabName(((Component)__instance).gameObject);
					if (CounterRules.CountsAsMuddyScrapPileOpened(byLocalPlayer, nowFullyDestroyed: true, prefabName))
					{
						ClientRuntime.Counters.Increment("Custom:MuddyScrapPilesOpened");
					}
				}
			});
		}
	}
	[HarmonyPatch(typeof(Smelter), "OnEmpty")]
	public static class SmelterEmptyPatch
	{
		[HarmonyPrefix]
		private static void Prefix(Humanoid user, ZNetView ___m_nview)
		{
			ClientRuntime.Guard("smelter empty count", delegate
			{
				if (ClientRuntime.Counters != null && !((Object)(object)___m_nview == (Object)null) && (object)user == Player.m_localPlayer)
				{
					ZDO zDO = ___m_nview.GetZDO();
					if (zDO != null)
					{
						string queuedOreName = zDO.GetString(ZDOVars.s_spawnOre, "");
						int queuedAmount = zDO.GetInt(ZDOVars.s_spawnAmount, 0);
						int num = CounterRules.IronToProcess(queuedOreName, queuedAmount);
						if (num > 0)
						{
							ClientRuntime.Counters.Increment("Custom:IronProcessed", num);
						}
					}
				}
			});
		}
	}
	[HarmonyPatch(typeof(Tameable), "Tame")]
	public static class TameablePatch
	{
		[HarmonyPostfix]
		private static void Postfix(Character ___m_character)
		{
			ClientRuntime.Guard("tame count", delegate
			{
				if (ClientRuntime.Counters != null && !((Object)(object)___m_character == (Object)null))
				{
					string text = CounterRules.TamedSpeciesCounterKey(Utils.GetPrefabName(((Component)___m_character).gameObject));
					if (text != null)
					{
						ClientRuntime.Counters.Increment(text);
					}
				}
			});
		}
	}
	[HarmonyPatch(typeof(Player), "ConsumeItem")]
	public static class VomitBombPatch
	{
		[HarmonyPrefix]
		private static void Prefix(Player __instance, out object __state)
		{
			__state = null;
			object captured = null;
			ClientRuntime.Guard("vomit bomb pre-check", delegate
			{
				if (__instance == Player.m_localPlayer)
				{
					captured = __instance.GetFoods()?.Count ?? 0;
				}
			});
			__state = captured;
		}

		[HarmonyPostfix]
		private static void Postfix(ItemData item, bool __result, object __state)
		{
			ClientRuntime.Guard("vomit bomb count", delegate
			{
				if (ClientRuntime.Counters != null && __state is int)
				{
					int activeFoodCountBeforeEating = (int)__state;
					bool eatenSuccessfully = __result;
					ItemData obj = item;
					object itemSharedName;
					if (obj == null)
					{
						itemSharedName = null;
					}
					else
					{
						GameObject dropPrefab = obj.m_dropPrefab;
						itemSharedName = ((dropPrefab != null) ? ((Object)dropPrefab).name : null);
					}
					if (CounterRules.CountsAsVomitBomb(eatenSuccessfully, (string)itemSharedName, activeFoodCountBeforeEating))
					{
						ClientRuntime.Counters.Increment("Custom:VomitBombs");
					}
				}
			});
		}
	}
	[HarmonyPatch(typeof(Character), "ApplyDamage")]
	public static class WeaponKillPatch
	{
		[HarmonyPostfix]
		private static void Postfix(Character __instance, HitData hit)
		{
			ClientRuntime.Guard("weapon kill count", delegate
			{
				if (ClientRuntime.Counters != null && hit != null)
				{
					bool byLocalPlayer = (object)hit.GetAttacker() == Player.m_localPlayer;
					string skillName = ((object)Unsafe.As<SkillType, SkillType>(ref hit.m_skill)/*cast due to .constrained prefix*/).ToString();
					bool flag = (Object)(object)__instance != (Object)null;
					bool targetIsPlayer = flag && __instance.IsPlayer();
					bool targetIsTamed = flag && __instance.IsTamed();
					bool targetIsDeadNow = flag && __instance.IsDead();
					if (CounterRules.CountsAsWeaponKill(byLocalPlayer, skillName, "Unarmed", flag, targetIsPlayer, targetIsTamed, targetIsDeadNow))
					{
						ClientRuntime.Counters.Increment("Custom:FistKills");
					}
					if (CounterRules.CountsAsWeaponKill(byLocalPlayer, skillName, "Swords", flag, targetIsPlayer, targetIsTamed, targetIsDeadNow))
					{
						ClientRuntime.Counters.Increment("Custom:SwordKills");
					}
				}
			});
		}
	}
}
namespace OdinEye.Client.Events
{
	public static class BedEvents
	{
		public static ClientEvent Removed(long ownerPlayerId, long removerPlayerId, float x, float y, float z)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			if (ownerPlayerId == 0L || ownerPlayerId == removerPlayerId)
			{
				return null;
			}
			return new ClientEvent
			{
				Type = "BedRemoved",
				OwnerPlayerId = ownerPlayerId.ToString(),
				RemoverPlayerId = removerPlayerId.ToString(),
				X = x,
				Y = y,
				Z = z
			};
		}

		public static ClientEvent MissingAtRespawn(float x, float y, float z)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			return new ClientEvent
			{
				Type = "BedMissingAtRespawn",
				X = x,
				Y = y,
				Z = z
			};
		}
	}
	public sealed class ClientEventQueue
	{
		public const int DefaultCapacity = 100;

		private readonly object gate = new object();

		private readonly LinkedList<ClientEvent> items = new LinkedList<ClientEvent>();

		private readonly int capacity;

		public int Count
		{
			get
			{
				lock (gate)
				{
					return items.Count;
				}
			}
		}

		public ClientEventQueue(int capacity = 100)
		{
			this.capacity = ((capacity > 0) ? capacity : 100);
		}

		public void Enqueue(ClientEvent clientEvent)
		{
			if (clientEvent == null)
			{
				return;
			}
			lock (gate)
			{
				items.AddLast(clientEvent);
				Trim();
			}
		}

		public List<ClientEvent> TakeBatch(int max)
		{
			List<ClientEvent> list = new List<ClientEvent>();
			lock (gate)
			{
				while (items.Count > 0 && list.Count < max)
				{
					list.Add(items.First.Value);
					items.RemoveFirst();
				}
			}
			return list;
		}

		public void Requeue(List<ClientEvent> batch)
		{
			if (batch == null)
			{
				return;
			}
			lock (gate)
			{
				for (int num = batch.Count - 1; num >= 0; num--)
				{
					items.AddFirst(batch[num]);
				}
				Trim();
			}
		}

		private void Trim()
		{
			while (items.Count > capacity)
			{
				items.RemoveFirst();
			}
		}
	}
}
namespace OdinEye.Client.Submission
{
	public sealed class ChangeDrivenPolicy
	{
		private readonly TimeSpan checkInterval;

		private readonly TimeSpan heartbeatInterval;

		private DateTime? nextCheckAtUtc;

		private DateTime? lastSubmittedAtUtc;

		public ChangeDrivenPolicy(TimeSpan checkInterval, TimeSpan heartbeatInterval)
		{
			if (checkInterval <= TimeSpan.Zero)
			{
				throw new ArgumentOutOfRangeException("checkInterval", "Check interval must be positive.");
			}
			if (heartbeatInterval < checkInterval)
			{
				throw new ArgumentOutOfRangeException("heartbeatInterval", "The heartbeat cannot be more frequent than the change check.");
			}
			this.checkInterval = checkInterval;
			this.heartbeatInterval = heartbeatInterval;
		}

		public void OnLogin(DateTime nowUtc)
		{
			lastSubmittedAtUtc = nowUtc;
			nextCheckAtUtc = nowUtc + checkInterval;
		}

		public bool IsCheckDue(DateTime nowUtc)
		{
			if (nextCheckAtUtc.HasValue)
			{
				DateTime? dateTime = nextCheckAtUtc;
				if (!(nowUtc < dateTime))
				{
					nextCheckAtUtc = nowUtc + checkInterval;
					return true;
				}
			}
			return false;
		}

		public bool ShouldSubmit(DateTime nowUtc, bool changed)
		{
			if (lastSubmittedAtUtc.HasValue)
			{
				if (!changed)
				{
					return nowUtc - lastSubmittedAtUtc.Value >= heartbeatInterval;
				}
				return true;
			}
			return false;
		}

		public void MarkSubmitted(DateTime nowUtc)
		{
			lastSubmittedAtUtc = nowUtc;
		}
	}
	public sealed class HttpEventSubmitter : IDisposable
	{
		private const int BatchSize = 20;

		private readonly HttpClient httpClient = new HttpClient();

		private readonly Uri serverBaseUri;

		private readonly Action<string> logWarning;

		private int sending;

		public HttpEventSubmitter(Uri serverBaseUri, Action<string> logWarning)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			this.serverBaseUri = serverBaseUri ?? throw new ArgumentNullException("serverBaseUri");
			this.logWarning = logWarning ?? throw new ArgumentNullException("logWarning");
		}

		public async void Flush(Guid playerId, ClientEventQueue queue)
		{
			if (queue.Count == 0 || Interlocked.Exchange(ref sending, 1) == 1)
			{
				return;
			}
			try
			{
				while (queue.Count > 0)
				{
					List<ClientEvent> batch = queue.TakeBatch(20);
					if (!(await SendAsync(playerId, batch).ConfigureAwait(continueOnCapturedContext: false)))
					{
						queue.Requeue(batch);
						break;
					}
				}
			}
			finally
			{
				Interlocked.Exchange(ref sending, 0);
			}
		}

		private async Task<bool> SendAsync(Guid playerId, List<ClientEvent> batch)
		{
			try
			{
				byte[] array = JsonSerializer.Serialize<ClientEventsSubmission>(new ClientEventsSubmission
				{
					Events = batch
				});
				ByteArrayContent content = new ByteArrayContent(array);
				try
				{
					((HttpContent)content).Headers.ContentType = new MediaTypeHeaderValue("application/json")
					{
						CharSet = Encoding.UTF8.WebName
					};
					HttpResponseMessage val = await httpClient.PostAsync(new Uri(serverBaseUri, $"players/{playerId}/events"), (HttpContent)(object)content).ConfigureAwait(continueOnCapturedContext: false);
					if (val.IsSuccessStatusCode)
					{
						return true;
					}
					int statusCode = (int)val.StatusCode;
					logWarning($"OdinEye server did not accept {batch.Count} event(s): {statusCode} {val.ReasonPhrase}");
					return statusCode == 400;
				}
				finally
				{
					((IDisposable)content)?.Dispose();
				}
			}
			catch (Exception ex)
			{
				logWarning("Failed to send events to OdinEye server: " + ex.Message);
				return false;
			}
		}

		public void Dispose()
		{
			((HttpMessageInvoker)httpClient).Dispose();
		}
	}
	public static class StatsSeeder
	{
		public static Dictionary<string, float> ParseOwnStats(string json, Guid playerId)
		{
			Dictionary<string, float> dictionary = new Dictionary<string, float>();
			if (string.IsNullOrWhiteSpace(json))
			{
				return dictionary;
			}
			try
			{
				Dictionary<string, Dictionary<string, float>> dictionary2 = JsonSerializer.Deserialize<Dictionary<string, Dictionary<string, float>>>(json);
				if (dictionary2 != null && dictionary2.TryGetValue(playerId.ToString(), out var value) && value != null)
				{
					foreach (KeyValuePair<string, float> item in value)
					{
						dictionary[item.Key] = item.Value;
					}
				}
			}
			catch
			{
			}
			return dictionary;
		}

		public static async Task<Dictionary<string, float>> FetchAsync(HttpClient client, Uri serverBaseUri, Guid playerId, TimeSpan timeout, Action<string> logWarning)
		{
			_ = 1;
			try
			{
				using CancellationTokenSource cts = new CancellationTokenSource(timeout);
				HttpResponseMessage val = await client.GetAsync(new Uri(serverBaseUri, "players/stats"), cts.Token).ConfigureAwait(continueOnCapturedContext: false);
				if (!val.IsSuccessStatusCode)
				{
					logWarning($"OdinEye server would not share existing counters: {(int)val.StatusCode}");
					return new Dictionary<string, float>();
				}
				return ParseOwnStats(await val.Content.ReadAsStringAsync().ConfigureAwait(continueOnCapturedContext: false), playerId);
			}
			catch (Exception ex)
			{
				logWarning("Could not read existing counters from OdinEye server: " + ex.Message);
				return new Dictionary<string, float>();
			}
		}
	}
	public sealed class HttpCheatStatusSubmitter : ICheatStatusSubmitter, IDisposable
	{
		private readonly HttpClient httpClient;

		private readonly Uri serverBaseUri;

		private readonly Action<string> logWarning;

		public HttpCheatStatusSubmitter(Uri serverBaseUri, Action<string> logWarning)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Expected O, but got Unknown
			this.serverBaseUri = serverBaseUri ?? throw new ArgumentNullException("serverBaseUri");
			this.logWarning = logWarning ?? throw new ArgumentNullException("logWarning");
			httpClient = new HttpClient();
		}

		public async void Submit(Guid playerId, bool cheated, bool bypassEnabled)
		{
			try
			{
				byte[] array = JsonSerializer.Serialize<CheatStatusSubmission>(new CheatStatusSubmission
				{
					Cheated = cheated,
					BypassEnabled = bypassEnabled
				});
				Uri uri = new Uri(serverBaseUri, $"players/{playerId}/cheatStatus");
				ByteArrayContent content = new ByteArrayContent(array);
				try
				{
					((HttpContent)content).Headers.ContentType = new MediaTypeHeaderValue("application/json")
					{
						CharSet = Encoding.UTF8.WebName
					};
					HttpResponseMessage val = await httpClient.PostAsync(uri, (HttpContent)(object)content).ConfigureAwait(continueOnCapturedContext: false);
					if (!val.IsSuccessStatusCode)
					{
						logWarning($"OdinEye server rejected cheat-status submission: {(int)val.StatusCode} {val.ReasonPhrase}");
					}
				}
				finally
				{
					((IDisposable)content)?.Dispose();
				}
			}
			catch (Exception ex)
			{
				logWarning("Failed to submit cheat status to OdinEye server: " + ex.Message);
			}
		}

		public void Dispose()
		{
			((HttpMessageInvoker)httpClient).Dispose();
		}
	}
	public sealed class HttpStatsSubmitter : IStatsSubmitter, IDisposable
	{
		private readonly HttpClient httpClient;

		private readonly Uri serverBaseUri;

		private readonly Action<string> logWarning;

		public HttpStatsSubmitter(Uri serverBaseUri, Action<string> logWarning)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Expected O, but got Unknown
			this.serverBaseUri = serverBaseUri ?? throw new ArgumentNullException("serverBaseUri");
			this.logWarning = logWarning ?? throw new ArgumentNullException("logWarning");
			httpClient = new HttpClient();
		}

		public async void Submit(Guid playerId, CharacterStatsSubmission submission, Action<bool> onComplete = null)
		{
			bool accepted = false;
			try
			{
				byte[] array = JsonSerializer.Serialize<CharacterStatsSubmission>(submission);
				Uri uri = new Uri(serverBaseUri, $"players/{playerId}/stats");
				ByteArrayContent content = new ByteArrayContent(array);
				try
				{
					((HttpContent)content).Headers.ContentType = new MediaTypeHeaderValue("application/json")
					{
						CharSet = Encoding.UTF8.WebName
					};
					HttpResponseMessage val = await httpClient.PostAsync(uri, (HttpContent)(object)content).ConfigureAwait(continueOnCapturedContext: false);
					accepted = val.IsSuccessStatusCode;
					if (!accepted)
					{
						logWarning($"OdinEye server rejected character-stats submission: {(int)val.StatusCode} {val.ReasonPhrase}");
					}
				}
				finally
				{
					((IDisposable)content)?.Dispose();
				}
			}
			catch (Exception ex)
			{
				logWarning("Failed to submit character stats to OdinEye server: " + ex.Message);
			}
			try
			{
				onComplete?.Invoke(accepted);
			}
			catch
			{
			}
		}

		public void Dispose()
		{
			((HttpMessageInvoker)httpClient).Dispose();
		}
	}
	public interface ICheatStatusSubmitter
	{
		void Submit(Guid playerId, bool cheated, bool bypassEnabled);
	}
	public interface IStatsSubmitter
	{
		void Submit(Guid playerId, CharacterStatsSubmission submission, Action<bool> onComplete = null);
	}
	public sealed class SubmissionScheduler
	{
		private readonly TimeSpan interval;

		private DateTime? nextSubmissionAtUtc;

		public SubmissionScheduler(TimeSpan interval)
		{
			if (interval <= TimeSpan.Zero)
			{
				throw new ArgumentOutOfRangeException("interval", "Submission interval must be positive.");
			}
			this.interval = interval;
		}

		public void OnLogin(DateTime nowUtc)
		{
			nextSubmissionAtUtc = nowUtc + interval;
		}

		public bool IsDue(DateTime nowUtc)
		{
			if (nextSubmissionAtUtc.HasValue)
			{
				DateTime? dateTime = nextSubmissionAtUtc;
				if (!(nowUtc < dateTime))
				{
					nextSubmissionAtUtc = nowUtc + interval;
					return true;
				}
			}
			return false;
		}
	}
}
namespace OdinEye.Client.Stats
{
	public static class PieceStats
	{
		public const string PiecePlacedPrefix = "PiecePlaced:";

		public const string StationTotalKey = "Derived:StationOrUpgradePlaced";

		public static Dictionary<string, float> Prefix(IEnumerable<KeyValuePair<string, float>> placed)
		{
			Dictionary<string, float> dictionary = new Dictionary<string, float>();
			foreach (KeyValuePair<string, float> item in placed ?? Enumerable.Empty<KeyValuePair<string, float>>())
			{
				if (!string.IsNullOrEmpty(item.Key) && !float.IsNaN(item.Value) && !float.IsInfinity(item.Value) && item.Value >= 0f)
				{
					dictionary["PiecePlaced:" + item.Key] = item.Value;
				}
			}
			return dictionary;
		}

		public static float StationTotal(IEnumerable<KeyValuePair<string, float>> placed, ISet<string> stationNames)
		{
			if (placed == null || stationNames == null || stationNames.Count == 0)
			{
				return 0f;
			}
			return placed.Where((KeyValuePair<string, float> kv) => stationNames.Contains(kv.Key) && !float.IsNaN(kv.Value) && !float.IsInfinity(kv.Value) && kv.Value > 0f).Sum((KeyValuePair<string, float> kv) => kv.Value);
		}
	}
	public static class StatsChange
	{
		public static bool HasChanged(IReadOnlyDictionary<string, float> previous, IReadOnlyDictionary<string, float> current)
		{
			if (current == null)
			{
				return false;
			}
			if (previous == null || previous.Count != current.Count)
			{
				return true;
			}
			foreach (KeyValuePair<string, float> item in current)
			{
				if (!previous.TryGetValue(item.Key, out var value) || value != item.Value)
				{
					return true;
				}
			}
			return false;
		}
	}
	public static class BoatTracking
	{
		public static bool IsOnBoat()
		{
			return (Object)(object)Ship.GetLocalShip() != (Object)null;
		}
	}
	public sealed class CounterAugmentedStatsSource : IPlayerStatsSource
	{
		private static readonly TimeSpan MaxPlausibleBoatGap = TimeSpan.FromMinutes(5.0);

		private static readonly TimeSpan MaxPlausibleSwampGap = TimeSpan.FromMinutes(5.0);

		private static readonly TimeSpan MaxPlausibleBakeryGap = TimeSpan.FromMinutes(5.0);

		private readonly IPlayerStatsSource inner;

		private readonly CustomCounterStore store;

		private readonly Func<ISet<string>> stationNames;

		private readonly Func<float?> currentNorthZ;

		private readonly Func<bool> isInDeepNorth;

		private readonly Func<bool> isOnBoat;

		private readonly Func<bool> isInSwamp;

		private readonly Func<bool> isNearOven;

		private readonly Func<DateTime> nowUtc;

		private DateTime? lastBoatSampleUtc;

		private DateTime? lastSwampSampleUtc;

		private DateTime? lastBakerySampleUtc;

		public CounterAugmentedStatsSource(IPlayerStatsSource inner, CustomCounterStore store, Func<ISet<string>> stationNames, Func<float?> currentNorthZ = null, Func<bool> isInDeepNorth = null, Func<bool> isOnBoat = null, Func<bool> isInSwamp = null, Func<bool> isNearOven = null, Func<DateTime> nowUtc = null)
		{
			this.inner = inner ?? throw new ArgumentNullException("inner");
			this.store = store ?? throw new ArgumentNullException("store");
			this.stationNames = stationNames ?? ((Func<ISet<string>>)(() => (ISet<string>)null));
			this.currentNorthZ = currentNorthZ ?? ((Func<float?>)(() => (float?)null));
			this.isInDeepNorth = isInDeepNorth ?? ((Func<bool>)(() => false));
			this.isOnBoat = isOnBoat ?? ((Func<bool>)(() => false));
			this.isInSwamp = isInSwamp ?? ((Func<bool>)(() => false));
			this.isNearOven = isNearOven ?? ((Func<bool>)(() => false));
			this.nowUtc = nowUtc ?? ((Func<DateTime>)(() => DateTime.UtcNow));
		}

		public IReadOnlyDictionary<string, float> GetStats()
		{
			Dictionary<string, float> dictionary = new Dictionary<string, float>();
			foreach (KeyValuePair<string, float> stat in inner.GetStats())
			{
				dictionary[stat.Key] = stat.Value;
			}
			if (dictionary.Count == 0)
			{
				return dictionary;
			}
			float num = PieceStats.StationTotal(from kv in dictionary
				where kv.Key.StartsWith("PiecePlaced:", StringComparison.Ordinal)
				select new KeyValuePair<string, float>(kv.Key.Substring("PiecePlaced:".Length), kv.Value), stationNames());
			if (num > 0f)
			{
				store.RaiseTo("Derived:StationOrUpgradePlaced", num);
			}
			float? num2 = currentNorthZ();
			if (num2.HasValue)
			{
				store.RaiseTo("Derived:FurthestNorthZ", CounterRules.NorthDistanceToRaise(num2.Value));
			}
			if (isInDeepNorth())
			{
				store.RaiseTo("Custom:ReachedDeepNorth", 1f);
			}
			DateTime dateTime = nowUtc();
			if (lastBoatSampleUtc.HasValue)
			{
				float elapsedSeconds = (float)(dateTime - lastBoatSampleUtc.Value).TotalSeconds;
				bool num3 = isOnBoat();
				TimeSpan maxPlausibleBoatGap = MaxPlausibleBoatGap;
				float num4 = CounterRules.BoatSecondsToAdd(num3, elapsedSeconds, (float)maxPlausibleBoatGap.TotalSeconds);
				if (num4 > 0f)
				{
					store.Increment("Custom:TimeOnBoatSeconds", num4);
				}
			}
			lastBoatSampleUtc = dateTime;
			if (lastSwampSampleUtc.HasValue)
			{
				float elapsedSeconds2 = (float)(dateTime - lastSwampSampleUtc.Value).TotalSeconds;
				bool num5 = isInSwamp();
				TimeSpan maxPlausibleBoatGap = MaxPlausibleSwampGap;
				float num6 = CounterRules.SwampSecondsToAdd(num5, elapsedSeconds2, (float)maxPlausibleBoatGap.TotalSeconds);
				if (num6 > 0f)
				{
					store.Increment("Custom:TimeInSwampSeconds", num6);
				}
			}
			lastSwampSampleUtc = dateTime;
			if (lastBakerySampleUtc.HasValue)
			{
				float elapsedSeconds3 = (float)(dateTime - lastBakerySampleUtc.Value).TotalSeconds;
				bool num7 = isNearOven();
				TimeSpan maxPlausibleBoatGap = MaxPlausibleBakeryGap;
				float num8 = CounterRules.BakerySecondsToAdd(num7, elapsedSeconds3, (float)maxPlausibleBoatGap.TotalSeconds);
				if (num8 > 0f)
				{
					store.Increment("Custom:TimeInBakerySeconds", num8);
				}
			}
			lastBakerySampleUtc = dateTime;
			foreach (KeyValuePair<string, float> item in store.Snapshot())
			{
				dictionary[item.Key] = item.Value;
			}
			return dictionary;
		}
	}
	public static class NorthTracking
	{
		public static float? CurrentNorthZ()
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)Player.m_localPlayer != (Object)null))
			{
				return null;
			}
			return ((Component)Player.m_localPlayer).transform.position.z;
		}

		public static bool IsInDeepNorth()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Invalid comparison between Unknown and I4
			if ((Object)(object)Player.m_localPlayer != (Object)null)
			{
				return (int)Player.m_localPlayer.GetCurrentBiome() == 64;
			}
			return false;
		}
	}
	public sealed class OutpostAnchorStore
	{
		private readonly object gate = new object();

		private readonly string path;

		private readonly Action<string> logWarning;

		private readonly List<float[]> anchors = new List<float[]>();

		private bool dirty;

		public IReadOnlyList<(float X, float Z)> Anchors
		{
			get
			{
				lock (gate)
				{
					(float, float)[] array = new(float, float)[anchors.Count];
					for (int i = 0; i < anchors.Count; i++)
					{
						array[i] = (anchors[i][0], anchors[i][1]);
					}
					return array;
				}
			}
		}

		public OutpostAnchorStore(string path, Action<string> logWarning = null)
		{
			this.path = path ?? throw new ArgumentNullException("path");
			this.logWarning = logWarning ?? ((Action<string>)delegate
			{
			});
			Load();
		}

		public void Add(float x, float z)
		{
			if (float.IsNaN(x) || float.IsInfinity(x) || float.IsNaN(z) || float.IsInfinity(z))
			{
				return;
			}
			lock (gate)
			{
				anchors.Add(new float[2] { x, z });
				dirty = true;
			}
		}

		public bool Flush()
		{
			byte[] bytes;
			lock (gate)
			{
				if (!dirty)
				{
					return true;
				}
				bytes = JsonSerializer.Serialize<List<float[]>>(anchors);
			}
			try
			{
				string directoryName = Path.GetDirectoryName(path);
				if (!string.IsNullOrEmpty(directoryName))
				{
					Directory.CreateDirectory(directoryName);
				}
				string sourceFileName = path + ".tmp";
				File.WriteAllBytes(sourceFileName, bytes);
				if (File.Exists(path))
				{
					File.Delete(path);
				}
				File.Move(sourceFileName, path);
				lock (gate)
				{
					dirty = false;
				}
				return true;
			}
			catch (Exception ex)
			{
				logWarning("OdinEye client: could not save outpost anchors to '" + path + "': " + ex.Message);
				return false;
			}
		}

		private void Load()
		{
			string sourceFileName = path + ".tmp";
			try
			{
				if (!File.Exists(path) && File.Exists(sourceFileName))
				{
					File.Move(sourceFileName, path);
				}
				if (!File.Exists(path))
				{
					return;
				}
				foreach (float[] item in JsonSerializer.Deserialize<List<float[]>>(File.ReadAllBytes(path)) ?? throw new InvalidDataException("outpost anchor file was empty"))
				{
					if (item != null && item.Length == 2 && !float.IsNaN(item[0]) && !float.IsNaN(item[1]))
					{
						anchors.Add(item);
					}
				}
			}
			catch (Exception ex)
			{
				logWarning("OdinEye client: outpost anchor file '" + path + "' was unreadable (" + ex.Message + "); starting fresh");
				try
				{
					string destFileName = path + ".bad";
					if (File.Exists(destFileName))
					{
						File.Delete(destFileName);
					}
					File.Move(path, destFileName);
				}
				catch
				{
				}
				anchors.Clear();
			}
		}
	}
	public static class OutpostTracking
	{
		public const float OutpostRadius = 15f;

		private const int OceanSampleSteps = 20;

		private static readonly MethodInfo GetOwner = AccessTools.Method(typeof(Bed), "GetOwner", (Type[])null, (Type[])null);

		private static bool Available => GetOwner != null;

		public static void Scan(OutpostAnchorStore anchors)
		{
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			if (!Available || anchors == null || (Object)(object)Player.m_localPlayer == (Object)null || ClientRuntime.Counters == null)
			{
				return;
			}
			long num = ClientRuntime.LocalPlayerId();
			if (num == 0L)
			{
				return;
			}
			List<Piece> list = new List<Piece>();
			Bed[] array = Object.FindObjectsByType<Bed>((FindObjectsSortMode)0);
			foreach (Bed val in array)
			{
				if (!((Object)(object)val == (Object)null) && (long)GetOwner.Invoke(val, null) == num)
				{
					Vector3 pos = val.GetSpawnPoint();
					list.Clear();
					Piece.GetAllPiecesInRadius(pos, 15f, list);
					bool hasCraftingStationNearby = list.Any((Piece p) => (Object)(object)p != (Object)null && (Object)(object)((Component)p).GetComponent<CraftingStation>() != (Object)null);
					bool hasPortalNearby = list.Any((Piece p) => (Object)(object)p != (Object)null && (Object)(object)((Component)p).GetComponent<TeleportWorld>() != (Object)null);
					if (CounterRules.IsQualifyingOutpost(Cover.IsUnderRoof(pos), hasCraftingStationNearby, hasPortalNearby) && CounterRules.IsNewLandmass(anchors.Anchors.Select(((float X, float Z) a) => CrossesOcean(pos, a.X, a.Z))))
					{
						anchors.Add(pos.x, pos.z);
						ClientRuntime.Counters.Increment("Custom:OutpostLandmasses");
					}
				}
			}
		}

		private static bool CrossesOcean(Vector3 from, float toX, float toZ)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Invalid comparison between Unknown and I4
			if (WorldGenerator.instance == null)
			{
				return false;
			}
			Vector3 val = default(Vector3);
			((Vector3)(ref val))..ctor(toX, from.y, toZ);
			for (int i = 0; i <= 20; i++)
			{
				Vector3 val2 = Vector3.Lerp(from, val, (float)i / 20f);
				if ((int)WorldGenerator.instance.GetBiome(val2) == 256)
				{
					return true;
				}
			}
			return false;
		}
	}
	public static class OvenTracking
	{
		public const float OvenRadius = 10f;

		public const string OvenPieceName = "piece_oven";

		private static readonly List<Piece> nearby = new List<Piece>();

		public static bool IsNearOven()
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)Player.m_localPlayer == (Object)null)
			{
				return false;
			}
			nearby.Clear();
			Piece.GetAllPiecesInRadius(((Component)Player.m_localPlayer).transform.position, 10f, nearby);
			return nearby.Any((Piece p) => (Object)(object)p != (Object)null && Utils.GetPrefabName(((Component)p).gameObject) == "piece_oven");
		}
	}
	public static class StationNames
	{
		private static HashSet<string> cached;

		public static ISet<string> Get()
		{
			if (cached != null)
			{
				return cached;
			}
			ZNetScene instance = ZNetScene.instance;
			if ((Object)(object)instance == (Object)null || instance.m_prefabs == null || instance.m_prefabs.Count == 0)
			{
				return null;
			}
			HashSet<string> hashSet = new HashSet<string>();
			foreach (GameObject prefab in instance.m_prefabs)
			{
				if (!((Object)(object)prefab == (Object)null))
				{
					Piece component = prefab.GetComponent<Piece>();
					if ((Object)(object)component != (Object)null && !string.IsNullOrEmpty(component.m_name) && ((Object)(object)prefab.GetComponent<CraftingStation>() != (Object)null || (Object)(object)prefab.GetComponent<StationExtension>() != (Object)null))
					{
						hashSet.Add(component.m_name);
					}
				}
			}
			if (hashSet.Count > 0)
			{
				cached = hashSet;
			}
			if (hashSet.Count <= 0)
			{
				return null;
			}
			return hashSet;
		}
	}
	public static class SwampTracking
	{
		public static bool IsInSwamp()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Invalid comparison between Unknown and I4
			if ((Object)(object)Player.m_localPlayer != (Object)null)
			{
				return (int)Player.m_localPlayer.GetCurrentBiome() == 2;
			}
			return false;
		}
	}
	public static class CharacterStatsPayloadBuilder
	{
		public static CharacterStatsSubmission Build(IReadOnlyDictionary<string, float> rawStats, SubmissionMeta meta = null)
		{
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Expected O, but got Unknown
			if (rawStats == null)
			{
				throw new ArgumentNullException("rawStats");
			}
			Dictionary<string, float> stats = rawStats.Where((KeyValuePair<string, float> stat) => IsValidStatValue(stat.Value)).ToDictionary((KeyValuePair<string, float> stat) => stat.Key, (KeyValuePair<string, float> stat) => stat.Value);
			return new CharacterStatsSubmission
			{
				Stats = stats,
				Meta = meta
			};
		}

		private static bool IsValidStatValue(float value)
		{
			if (!float.IsNaN(value) && !float.IsInfinity(value))
			{
				return value >= 0f;
			}
			return false;
		}
	}
	public interface IPlayerStatsSource
	{
		IReadOnlyDictionary<string, float> GetStats();
	}
	public static class CheatBypassReader
	{
		private const string BypassKey = "bypasscheatchecks";

		public static bool IsEnabled()
		{
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				return false;
			}
			string text = default(string);
			if (localPlayer.TryGetUniqueKeyValue("bypasscheatchecks", ref text))
			{
				return text == "1";
			}
			return false;
		}
	}
	public static class CheatStatusReader
	{
		private static readonly Lazy<MethodInfo> IsCheatedAtAllMethod = new Lazy<MethodInfo>(() => typeof(PlayerProfile).Assembly.GetType("Achievements")?.GetMethod("IsCheatedAtAll", BindingFlags.Static | BindingFlags.Public));

		public static bool? IsCheated()
		{
			MethodInfo value = IsCheatedAtAllMethod.Value;
			if (value == null)
			{
				return null;
			}
			try
			{
				return (bool)value.Invoke(null, null);
			}
			catch
			{
				return null;
			}
		}
	}
	public sealed class PlayerProfileStatsSource : IPlayerStatsSource
	{
		public const string PlayTimeSecondsKey = "PlayTimeSeconds";

		public const string KnownWorldsCountKey = "KnownWorldsCount";

		public const string EnemyKillKeyPrefix = "EnemyKill:";

		private const int RawStatsIndex = 0;

		private static object GetFieldValue(object target, string fieldName)
		{
			return target?.GetType().GetField(fieldName, BindingFlags.Instance | BindingFlags.Public)?.GetValue(target);
		}

		private static object GetRawPlayerStats(object profile)
		{
			if (!(GetFieldValue(profile, "m_playerStats") is Array { Length: >0 } array))
			{
				return null;
			}
			return array.GetValue(0);
		}

		public IReadOnlyDictionary<string, float> GetStats()
		{
			Game instance = Game.instance;
			PlayerProfile val = ((instance != null) ? instance.GetPlayerProfile() : null);
			if (val == null)
			{
				return new Dictionary<string, float>();
			}
			Dictionary<string, float> dictionary = new Dictionary<string, float>();
			object rawPlayerStats = GetRawPlayerStats(val);
			if (GetFieldValue(rawPlayerStats, "m_stats") is IDictionary dictionary2)
			{
				foreach (DictionaryEntry item in dictionary2)
				{
					dictionary[item.Key.ToString()] = Convert.ToSingle(item.Value);
				}
			}
			float num = 0f;
			int num2 = 0;
			if (GetFieldValue(rawPlayerStats, "m_knownWorlds") is IDictionary dictionary3)
			{
				num2 = dictionary3.Count;
				foreach (object value in dictionary3.Values)
				{
					num += Convert.ToSingle(value);
				}
			}
			dictionary["PlayTimeSeconds"] = num;
			dictionary["KnownWorldsCount"] = num2;
			if (GetFieldValue(rawPlayerStats, "m_enemyStats") is Array { Length: >0 } array && array.GetValue(0) is IDictionary dictionary4)
			{
				foreach (DictionaryEntry item2 in dictionary4)
				{
					dictionary["EnemyKill:" + item2.Key] = Convert.ToSingle(item2.Value);
				}
			}
			if (GetFieldValue(rawPlayerStats, "m_piecesPlacedStats") is IDictionary dictionary5)
			{
				Dictionary<string, float> dictionary6 = new Dictionary<string, float>();
				foreach (DictionaryEntry item3 in dictionary5)
				{
					dictionary6[item3.Key.ToString()] = Convert.ToSingle(item3.Value);
				}
				foreach (KeyValuePair<string, float> item4 in PieceStats.Prefix(dictionary6))
				{
					dictionary[item4.Key] = item4.Value;
				}
			}
			return dictionary;
		}
	}
}
namespace OdinEye.Client.Counters
{
	public sealed class CustomCounterStore
	{
		public static readonly string[] SeedablePrefixes = new string[2] { "Custom:", "Derived:" };

		private readonly object gate = new object();

		private readonly string path;

		private readonly Action<string> logWarning;

		private readonly Dictionary<string, float> values = new Dictionary<string, float>();

		private bool dirty;

		public bool IsDirty
		{
			get
			{
				lock (gate)
				{
					return dirty;
				}
			}
		}

		public CustomCounterStore(string path, Action<string> logWarning = null)
		{
			this.path = path ?? throw new ArgumentNullException("path");
			this.logWarning = logWarning ?? ((Action<string>)delegate
			{
			});
			Load();
		}

		public void Increment(string key, float amount = 1f)
		{
			if (string.IsNullOrEmpty(key) || float.IsNaN(amount) || float.IsInfinity(amount) || amount <= 0f)
			{
				return;
			}
			lock (gate)
			{
				values.TryGetValue(key, out var value);
				values[key] = value + amount;
				dirty = true;
			}
		}

		public float Get(string key)
		{
			lock (gate)
			{
				float value;
				return values.TryGetValue(key, out value) ? value : 0f;
			}
		}

		public IReadOnlyDictionary<string, float> Snapshot()
		{
			lock (gate)
			{
				return new Dictionary<string, float>(values);
			}
		}

		public float RaiseTo(string key, float value)
		{
			if (string.IsNullOrEmpty(key) || float.IsNaN(value) || float.IsInfinity(value) || value < 0f)
			{
				return Get(key);
			}
			lock (gate)
			{
				values.TryGetValue(key, out var value2);
				if (value > value2 || !values.ContainsKey(key))
				{
					values[key] = Math.Max(value, value2);
					dirty = true;
				}
				return values[key];
			}
		}

		public void SeedFrom(IEnumerable<KeyValuePair<string, float>> serverValues)
		{
			if (serverValues == null)
			{
				return;
			}
			lock (gate)
			{
				foreach (KeyValuePair<string, float> kv in serverValues)
				{
					if (SeedablePrefixes.Any((string p) => kv.Key != null && kv.Key.StartsWith(p, StringComparison.Ordinal)) && !float.IsNaN(kv.Value) && !float.IsInfinity(kv.Value) && !(kv.Value < 0f))
					{
						values.TryGetValue(kv.Key, out var value);
						if (kv.Value > value)
						{
							values[kv.Key] = kv.Value;
							dirty = true;
						}
					}
				}
			}
		}

		public bool Flush()
		{
			byte[] bytes;
			lock (gate)
			{
				if (!dirty)
				{
					return true;
				}
				bytes = JsonSerializer.Serialize<Dictionary<string, float>>(values);
			}
			try
			{
				string directoryName = Path.GetDirectoryName(path);
				if (!string.IsNullOrEmpty(directoryName))
				{
					Directory.CreateDirectory(directoryName);
				}
				string sourceFileName = path + ".tmp";
				File.WriteAllBytes(sourceFileName, bytes);
				if (File.Exists(path))
				{
					File.Delete(path);
				}
				File.Move(sourceFileName, path);
				lock (gate)
				{
					dirty = false;
				}
				return true;
			}
			catch (Exception ex)
			{
				logWarning("OdinEye client: could not save counters to '" + path + "': " + ex.Message);
				return false;
			}
		}

		private void Load()
		{
			string sourceFileName = path + ".tmp";
			try
			{
				if (!File.Exists(path) && File.Exists(sourceFileName))
				{
					File.Move(sourceFileName, path);
				}
				if (!File.Exists(path))
				{
					return;
				}
				foreach (KeyValuePair<string, float> item in JsonSerializer.Deserialize<Dictionary<string, float>>(File.ReadAllBytes(path)) ?? throw new InvalidDataException("counter file was empty"))
				{
					if (!float.IsNaN(item.Value) && !float.IsInfinity(item.Value) && item.Value >= 0f)
					{
						values[item.Key] = item.Value;
					}
				}
			}
			catch (Exception ex)
			{
				logWarning("OdinEye client: counter file '" + path + "' was unreadable (" + ex.Message + "); starting fresh and keeping the old one as .bad");
				try
				{
					string destFileName = path + ".bad";
					if (File.Exists(destFileName))
					{
						File.Delete(destFileName);
					}
					File.Move(path, destFileName);
				}
				catch
				{
				}
				values.Clear();
			}
		}
	}
	public static class CounterRules
	{
		public const string ArrowHitsEnemyKey = "Custom:ArrowHitsEnemy";

		public const string BreadCollectedKey = "Custom:BreadCollected";

		public const string DwarfEyesTouchedKey = "Custom:DwarfEyesTouched";

		public const string FoodBurntToCoalKey = "Custom:FoodBurntToCoal";

		public const string TimeOnBoatSecondsKey = "Custom:TimeOnBoatSeconds";

		public const string VomitBombsKey = "Custom:VomitBombs";

		public const string FistKillsKey = "Custom:FistKills";

		public const string SwordKillsKey = "Custom:SwordKills";

		public const string ChickenMeatCookedKey = "Custom:ChickenMeatCooked";

		public const string LoxPiesCookedKey = "Custom:LoxPiesCooked";

		public const string MeadsMadeKey = "Custom:MeadsMade";

		public const string OutpostLandmassesKey = "Custom:OutpostLandmasses";

		public const string PoisonDeathsKey = "Custom:PoisonDeaths";

		public const string LeechHitsKey = "Custom:LeechHits";

		public const string GuckCollectedKey = "Custom:GuckCollected";

		public const string BloodBagsCollectedKey = "Custom:BloodBagsCollected";

		public const string MuddyScrapPilesOpenedKey = "Custom:MuddyScrapPilesOpened";

		public const string ElderBarkCollectedKey = "Custom:ElderBarkCollected";

		public const string IronProcessedKey = "Custom:IronProcessed";

		public const string TimeInSwampSecondsKey = "Custom:TimeInSwampSeconds";

		public const string WoodCollectedKey = "Custom:WoodCollected";

		public const string BedsDestroyedKey = "Custom:BedsDestroyed";

		public const string StoneCollectedKey = "Custom:StoneCollected";

		public const string TimeInBakerySecondsKey = "Custom:TimeInBakerySeconds";

		public const string ResinHandledKey = "Custom:ResinHandled";

		public const string TamedBoarKey = "Custom:TamedBoar";

		public const string TamedWolfKey = "Custom:TamedWolf";

		public const string TamedLoxKey = "Custom:TamedLox";

		public const string FurthestNorthZKey = "Derived:FurthestNorthZ";

		public const string ReachedDeepNorthKey = "Custom:ReachedDeepNorth";

		public const string BreadItemName = "Bread";

		public const string DwarfEyeItemName = "GreydwarfEye";

		public const string VomitBombItemName = "Pukeberries";

		public const string CookedChickenItemName = "CookedChickenMeat";

		public const string LoxMeatPieItemName = "LoxMeatPie";

		public const string GuckItemName = "Guck";

		public const string BloodBagItemName = "Bloodbag";

		public const string ElderBarkItemName = "ElderBark";

		public static readonly HashSet<string> LeechPrefabNames = new HashSet<string> { "Leech", "Leech_cave" };

		public static readonly HashSet<string> MudPilePrefabNames = new HashSet<string>(StringComparer.OrdinalIgnoreCase) { "MudPile", "MudPile2" };

		public const string IronScrapItemName = "IronScrap";

		public static readonly HashSet<string> WoodItemNames = new HashSet<string> { "Wood", "RoundLog", "FineWood", "Blackwood", "Frostwood", "YggdrasilWood" };

		public static readonly HashSet<string> StoneItemNames = new HashSet<string> { "Stone", "Flint" };

		public const string ResinItemName = "Resin";

		public static bool CountsAsArrowHitOnEnemy(bool firedByLocalPlayer, string skillName, bool targetIsCharacter, bool targetIsPlayer, bool targetIsTamed, bool targetIsDead)
		{
			if (firedByLocalPlayer && skillName == "Bows" && targetIsCharacter && !targetIsPlayer && !targetIsTamed)
			{
				return !targetIsDead;
			}
			return false;
		}

		public static int BreadToCount(bool itemIsDone, string producedItemName, int amountTaken)
		{
			if (!itemIsDone || !(producedItemName == "Bread") || amountTaken <= 0)
			{
				return 0;
			}
			return amountTaken;
		}

		public static int FoodBurntToCoal(bool isBurntStatus, int amountTaken)
		{
			if (!isBurntStatus || amountTaken <= 0)
			{
				return 0;
			}
			return amountTaken;
		}

		public static int CookedChickenMeatToCount(bool itemIsDone, string producedItemName, int amountTaken)
		{
			if (!itemIsDone || !(producedItemName == "CookedChickenMeat") || amountTaken <= 0)
			{
				return 0;
			}
			return amountTaken;
		}

		public static int LoxPieToCount(bool itemIsDone, string producedItemName, int amountTaken)
		{
			if (!itemIsDone || !(producedItemName == "LoxMeatPie") || amountTaken <= 0)
			{
				return 0;
			}
			return amountTaken;
		}

		public static string TamedSpeciesCounterKey(string prefabName)
		{
			return prefabName switch
			{
				"Boar" => "Custom:TamedBoar", 
				"Wolf" => "Custom:TamedWolf", 
				"Lox" => "Custom:TamedLox", 
				_ => null, 
			};
		}

		public static int MeadsToCount(bool statusIsReady, int producedItems)
		{
			if (!statusIsReady || producedItems <= 0)
			{
				return 0;
			}
			return producedItems;
		}

		public static int DwarfEyesToCount(bool byLocalPlayer, bool pickupSucceeded, string itemSharedName, int stack)
		{
			if (!(byLocalPlayer && pickupSucceeded) || !(itemSharedName == "GreydwarfEye") || stack <= 0)
			{
				return 0;
			}
			return stack;
		}

		public static float NorthDistanceToRaise(float positionZ)
		{
			if (!(positionZ > 0f))
			{
				return 0f;
			}
			return positionZ;
		}

		public static float BoatSecondsToAdd(bool isOnBoat, float elapsedSeconds, float maxPlausibleGapSeconds)
		{
			if (!isOnBoat || !(elapsedSeconds > 0f) || !(elapsedSeconds <= maxPlausibleGapSeconds))
			{
				return 0f;
			}
			return elapsedSeconds;
		}

		public static bool CountsAsVomitBomb(bool eatenSuccessfully, string itemSharedName, int activeFoodCountBeforeEating)
		{
			if (eatenSuccessfully && itemSharedName == "Pukeberries")
			{
				return activeFoodCountBeforeEating == 0;
			}
			return false;
		}

		public static bool IsQualifyingOutpost(bool bedIsCovered, bool hasCraftingStationNearby, bool hasPortalNearby)
		{
			return bedIsCovered && hasCraftingStationNearby && hasPortalNearby;
		}

		public static bool IsNewLandmass(IEnumerable<bool> oceanSeparatedFromEachKnownLandmass)
		{
			return oceanSeparatedFromEachKnownLandmass.All((bool separated) => separated);
		}

		public static bool CountsAsWeaponKill(bool byLocalPlayer, string skillName, string wantSkillName, bool targetIsCharacter, bool targetIsPlayer, bool targetIsTamed, bool targetIsDeadNow)
		{
			return byLocalPlayer && skillName == wantSkillName && targetIsCharacter && !targetIsPlayer && !targetIsTamed && targetIsDeadNow;
		}

		public static bool CountsAsPoisonDeath(bool targetIsLocalPlayer, bool targetIsDeadNow, float poisonDamageInHit)
		{
			if (targetIsLocalPlayer && targetIsDeadNow)
			{
				return poisonDamageInHit > 0f;
			}
			return false;
		}

		public static bool CountsAsLeechHit(bool targetIsLocalPlayer, string attackerPrefabName)
		{
			if (targetIsLocalPlayer && attackerPrefabName != null)
			{
				return LeechPrefabNames.Contains(attackerPrefabName);
			}
			return false;
		}

		public static int GuckToCount(bool byLocalPlayer, bool pickupSucceeded, string itemPrefabName, int stack)
		{
			if (!(byLocalPlayer && pickupSucceeded) || !(itemPrefabName == "Guck") || stack <= 0)
			{
				return 0;
			}
			return stack;
		}

		public static int BloodBagToCount(bool byLocalPlayer, bool pickupSucceeded, string itemPrefabName, int stack)
		{
			if (!(byLocalPlayer && pickupSucceeded) || !(itemPrefabName == "Bloodbag") || stack <= 0)
			{
				return 0;
			}
			return stack;
		}

		public static int ElderBarkToCount(bool byLocalPlayer, bool pickupSucceeded, string itemPrefabName, int stack)
		{
			if (!(byLocalPlayer && pickupSucceeded) || !(itemPrefabName == "ElderBark") || stack <= 0)
			{
				return 0;
			}
			return stack;
		}

		public static bool CountsAsMuddyScrapPileOpened(bool byLocalPlayer, bool nowFullyDestroyed, string prefabName)
		{
			if (byLocalPlayer && nowFullyDestroyed && prefabName != null)
			{
				return MudPilePrefabNames.Contains(prefabName);
			}
			return false;
		}

		public static int IronToProcess(string queuedOreName, int queuedAmount)
		{
			if (!(queuedOreName == "IronScrap") || queuedAmount <= 0)
			{
				return 0;
			}
			return queuedAmount;
		}

		public static float SwampSecondsToAdd(bool isInSwamp, float elapsedSeconds, float maxPlausibleGapSeconds)
		{
			if (!isInSwamp || !(elapsedSeconds > 0f) || !(elapsedSeconds <= maxPlausibleGapSeconds))
			{
				return 0f;
			}
			return elapsedSeconds;
		}

		public static int WoodToCount(bool byLocalPlayer, bool pickupSucceeded, string itemPrefabName, int stack)
		{
			if (!(byLocalPlayer && pickupSucceeded) || stack <= 0 || itemPrefabName == null || !WoodItemNames.Contains(itemPrefabName))
			{
				return 0;
			}
			return stack;
		}

		public static int StoneToCount(bool byLocalPlayer, bool pickupSucceeded, string itemPrefabName, int stack)
		{
			if (!(byLocalPlayer && pickupSucceeded) || stack <= 0 || itemPrefabName == null || !StoneItemNames.Contains(itemPrefabName))
			{
				return 0;
			}
			return stack;
		}

		public static float BakerySecondsToAdd(bool isNearOven, float elapsedSeconds, float maxPlausibleGapSeconds)
		{
			if (!isNearOven || !(elapsedSeconds > 0f) || !(elapsedSeconds <= maxPlausibleGapSeconds))
			{
				return 0f;
			}
			return elapsedSeconds;
		}

		public static int ResinToCount(bool byLocalPlayer, bool pickupSucceeded, string itemPrefabName, int stack)
		{
			if (!(byLocalPlayer && pickupSucceeded) || !(itemPrefabName == "Resin") || stack <= 0)
			{
				return 0;
			}
			return stack;
		}
	}
}
namespace OdinEye.Client.Hud
{
	public sealed class ClockHudElement
	{
		private static readonly Lazy<PropertyInfo> TmpTextProperty = new Lazy<PropertyInfo>(() => AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly a) => a.GetName().Name == "Unity.TextMeshPro")?.GetType("TMPro.TMP_Text")?.GetProperty("text"));

		private static readonly FieldInfo BiomeNameSmallField = typeof(Minimap).GetField("m_biomeNameSmall", BindingFlags.Instance | BindingFlags.Public);

		private Component clockLabel;

		private bool triedToCreate;

		private Minimap ownerMinimap;

		public void SetText(string text)
		{
			Component val = EnsureCreated();
			PropertyInfo value = TmpTextProperty.Value;
			if ((Object)(object)val == (Object)null || value == null)
			{
				return;
			}
			try
			{
				value.SetValue(val, text);
			}
			catch
			{
			}
		}

		private Component EnsureCreated()
		{
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)Minimap.instance != (Object)(object)ownerMinimap)
			{
				ownerMinimap = Minimap.instance;
				clockLabel = null;
				triedToCreate = false;
			}
			if ((Object)(object)clockLabel != (Object)null || triedToCreate || (Object)(object)Minimap.instance == (Object)null || BiomeNameSmallField == null)
			{
				return clockLabel;
			}
			triedToCreate = true;
			try
			{
				object? value = BiomeNameSmallField.GetValue(Minimap.instance);
				Component val = (Component)((value is Component) ? value : null);
				if (val == null)
				{
					return null;
				}
				GameObject val2 = Object.Instantiate<GameObject>(val.gameObject, val.transform.parent);
				((Object)val2).name = "OdinEyeClockText";
				RectTransform component = val2.GetComponent<RectTransform>();
				if ((Object)(object)component != (Object)null)
				{
					component.anchoredPosition += new Vector2(0f, -30f);
				}
				clockLabel = val2.GetComponent(((object)val).GetType());
			}
			catch
			{
				clockLabel = null;
			}
			return clockLabel;
		}
	}
	public static class EnvManTimeReader
	{
		private static readonly Lazy<FieldInfo> TotalSecondsField = new Lazy<FieldInfo>(() => typeof(EnvMan).GetField("m_totalSeconds", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic));

		public static double? GetTotalSeconds()
		{
			EnvMan instance = EnvMan.instance;
			FieldInfo value = TotalSecondsField.Value;
			if ((Object)(object)instance == (Object)null || value == null)
			{
				return null;
			}
			try
			{
				return (double)value.GetValue(instance);
			}
			catch
			{
				return null;
			}
		}
	}
	public static class TemporalClock
	{
		private const double DayLengthSeconds = 1800.0;

		private const double DawnPhaseOffset = 270.0;

		private const double DaylightSeconds = 1260.0;

		private const double NightSeconds = 540.0;

		public static string Format(double totalSeconds)
		{
			double num = Mod(Mod(totalSeconds, 1800.0) - 270.0, 1800.0);
			double num2 = Mod((num < 1260.0) ? (6.0 + num / 1260.0 * 12.0) : (18.0 + (num - 1260.0) / 540.0 * 12.0), 24.0);
			int num3 = (int)num2;
			int num4 = (int)Math.Round((num2 - (double)num3) * 60.0);
			if (num4 == 60)
			{
				num4 = 0;
				num3 = (num3 + 1) % 24;
			}
			string arg = ((num3 < 12) ? "AM" : "PM");
			int num5 = num3 % 12;
			if (num5 == 0)
			{
				num5 = 12;
			}
			return $"{num5}:{num4:D2} {arg}";
		}

		private static double Mod(double value, double modulus)
		{
			double num = value % modulus;
			if (!(num < 0.0))
			{
				return num;
			}
			return num + modulus;
		}
	}
}

plugins/OdinEye.Models.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using NGuid;
using ProtoBuf;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")]
[assembly: AssemblyCompany("sparcopt")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+54bc12311450691a0ebdbd8b7a54cc3a57b8e72c")]
[assembly: AssemblyProduct("OdinEye.Models")]
[assembly: AssemblyTitle("OdinEye.Models")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/sparcopt/odin-eye")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace OdinEye.Models
{
	public static class NameBasedGuid
	{
		private static readonly Guid NamespaceId = new Guid("4b01a09a-9b18-493c-9877-4786611eeea2");

		public static Guid NewPlayerGuid(string steamId, string playerName)
		{
			return GuidHelpers.CreateFromName(NamespaceId, steamId + playerName, 5);
		}
	}
}
namespace OdinEye.Models.Proto
{
	public enum EventType
	{
		Unknown = 0,
		PlayerJoin = 1,
		PlayerSpawn = 2,
		PlayerDeath = 3,
		PlayerDisconnect = 4,
		PlayerChat = 5,
		PlayersSleepStart = 6,
		PlayerSleepStop = 7,
		GameAwake = 50,
		GameQuit = 51,
		WorldLoad = 53,
		WorldSave = 54,
		ServerShutdown = 55,
		GlobalKeyAdd = 56,
		GlobalKeyRemove = 57,
		RandomEventActivate = 100,
		RandomEventDeactivate = 101,
		RandomEventSet = 102,
		EnvironmentMorningStart = 200,
		EnvironmentEveningStart = 201,
		EnemyKilled = 300,
		BedRemoved = 400,
		BedMissingAtRespawn = 401
	}
	[ProtoContract]
	public class GameEvent : Message
	{
		[ProtoMember(1)]
		public string Message { get; set; }

		[ProtoMember(2)]
		public EventType Type { get; set; }

		[ProtoMember(4)]
		public Player Player { get; set; }

		[ProtoMember(5)]
		public IDictionary<string, object> Data { get; set; }

		[ProtoIgnore]
		public IDictionary<string, object> Details { get; set; }

		public static GameEvent New(EventType type, string message, Player player = null)
		{
			return new GameEvent
			{
				CreatedDate = DateTime.UtcNow,
				Type = type,
				Message = message,
				Player = player
			};
		}

		public static GameEvent New(EventType type, string message, Player player, IDictionary<string, object> details)
		{
			return new GameEvent
			{
				CreatedDate = DateTime.UtcNow,
				Type = type,
				Message = message,
				Player = player,
				Details = details
			};
		}
	}
	[ProtoContract]
	public class GameStatsSnapshot : Message
	{
		[ProtoMember(1)]
		public IEnumerable<PlayerStats> PlayerStats { get; set; } = new List<PlayerStats>();

		[ProtoMember(2)]
		public WorldStats WorldStats { get; set; }
	}
	[ProtoContract]
	[ProtoInclude(2, typeof(GameEvent))]
	[ProtoInclude(3, typeof(GameStatsSnapshot))]
	public class Message
	{
		[ProtoMember(1)]
		public DateTime CreatedDate { get; set; }
	}
	[ProtoContract]
	public class Player
	{
		[ProtoMember(1)]
		public Guid Id { get; set; }

		[ProtoMember(2)]
		public string CharacterId { get; set; }

		[ProtoMember(3)]
		public string SteamId { get; set; }

		[ProtoMember(4)]
		public string Name { get; set; }

		[ProtoMember(5)]
		public float Health { get; set; }

		[ProtoMember(6)]
		public float MaxHealth { get; set; }

		[ProtoMember(7)]
		public float Stamina { get; set; }
	}
	[ProtoContract]
	public class PlayerStats
	{
		[ProtoMember(1)]
		public Guid Id { get; set; }

		[ProtoMember(2)]
		public string CharacterId { get; set; }

		[ProtoMember(3)]
		public float Health { get; set; }

		[ProtoMember(4)]
		public float MaxHealth { get; set; }

		[ProtoMember(5)]
		public float Stamina { get; set; }
	}
	[ProtoContract]
	public class WorldStats
	{
		[ProtoMember(1)]
		public int DayNumber { get; set; }

		[ProtoMember(2)]
		public string DayCycle { get; set; }
	}
}
namespace OdinEye.Models.Api
{
	public class AcceptedResponse
	{
		public bool Accepted { get; set; } = true;
	}
	public class Boss
	{
		public string Key { get; set; }

		public string Name { get; set; }

		public bool IsDefeated { get; set; }
	}
	public class BossDetails
	{
		public int ActiveBosses { get; set; }

		public IEnumerable<Boss> Bosses { get; set; } = Enumerable.Empty<Boss>();
	}
	public class CharacterStatsSubmission
	{
		public Dictionary<string, float> Stats { get; set; }

		public SubmissionMeta Meta { get; set; }
	}
	public class SubmissionMeta
	{
		public string PlayerId { get; set; }

		public string ClientVersion { get; set; }
	}
	public class CheatStatusSubmission
	{
		public bool Cheated { get; set; }

		public bool BypassEnabled { get; set; }
	}
	public class ClientEventsSubmission
	{
		public List<ClientEvent> Events { get; set; }
	}
	public class ClientEvent
	{
		public string Type { get; set; }

		public string OwnerPlayerId { get; set; }

		public string RemoverPlayerId { get; set; }

		public float X { get; set; }

		public float Y { get; set; }

		public float Z { get; set; }
	}
	public class GlobalKey
	{
		public string Name { get; set; }

		public string Value { get; set; }
	}
	public class NotifyRequest
	{
		public string Message { get; set; }
	}
	public class Player
	{
		public Guid Id { get; set; }

		public string CharacterId { get; set; }

		public string SteamId { get; set; }

		public string Name { get; set; }

		public float Health { get; set; }

		public float MaxHealth { get; set; }

		public float Stamina { get; set; }
	}
	public class ServerDetails
	{
		public int MaxNumberOfPlayers { get; set; }

		public string GameVersion { get; set; }

		public string SteamAppId { get; set; }
	}
	public class WorldDetails
	{
		public int DayNumber { get; set; }

		public string DayCycle { get; set; }

		public double NetTime { get; set; }

		public string WorldName { get; set; }

		public string SeedName { get; set; }

		public IEnumerable<string> WorldKeys { get; set; } = Enumerable.Empty<string>();

		public IEnumerable<GlobalKey> GlobalKeys { get; set; } = Enumerable.Empty<GlobalKey>();
	}
	public class WorldModifiersDetails
	{
		public IEnumerable<WorldModifierValue> Modifiers { get; set; } = Enumerable.Empty<WorldModifierValue>();

		public string Summary { get; set; }
	}
	public class WorldModifierValue
	{
		public string Category { get; set; }

		public string Value { get; set; }
	}
}

plugins/NGuid.dll

Decompiled a day ago
using System;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Cryptography;
using System.Security.Permissions;
using System.Text;
using Microsoft.CodeAnalysis;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")]
[assembly: AssemblyCompany("Bradley Grainger")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("Copyright 2023 Bradley Grainger")]
[assembly: AssemblyDescription("Creates GUIDs according to RFC 4122 and the UUID Revision Working Draft.")]
[assembly: AssemblyFileVersion("0.2.0.0")]
[assembly: AssemblyInformationalVersion("0.2.0+0752fad0bd0c6f95ace49389bc01bdc07f7d6c59")]
[assembly: AssemblyProduct("NGuid")]
[assembly: AssemblyTitle("NGuid")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/bgrainger/NGuid.git")]
[assembly: InternalsVisibleTo("NGuid.Tests")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[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 NGuid
{
	public static class GuidHelpers
	{
		public static readonly Guid DnsNamespace = new Guid("6ba7b810-9dad-11d1-80b4-00c04fd430c8");

		public static readonly Guid UrlNamespace = new Guid("6ba7b811-9dad-11d1-80b4-00c04fd430c8");

		public static readonly Guid IsoOidNamespace = new Guid("6ba7b812-9dad-11d1-80b4-00c04fd430c8");

		public static readonly Guid Sha256HashSpaceId = new Guid("3fb32780-953c-4464-9cfd-e85dbbe9843d");

		public static readonly Guid Sha384HashSpaceId = new Guid("e6800581-f333-484b-8778-601ff2b58da8");

		public static readonly Guid Sha512HashSpaceId = new Guid("0fde22f2-e7ba-4fd1-9753-9c2ea88fa3f9");

		private static readonly DateTime s_gregorianEpoch = new DateTime(1582, 10, 15, 0, 0, 0, DateTimeKind.Utc);

		public static Guid CreateFromName(Guid namespaceId, string name, int version = 5)
		{
			if (name == null)
			{
				throw new ArgumentNullException("name");
			}
			byte[] bytes = Encoding.UTF8.GetBytes(name);
			return CreateFromName(namespaceId, bytes, version);
		}

		public static Guid CreateFromName(Guid namespaceId, byte[] name, int version = 5)
		{
			if ((version != 3 && version != 5) || 1 == 0)
			{
				throw new ArgumentOutOfRangeException("version", version, "version must be either 3 or 5.");
			}
			byte[] array = namespaceId.ToByteArray();
			SwapByteOrder(array);
			byte[] buffer = array.Concat(name).ToArray();
			byte[] sourceArray;
			using (HashAlgorithm hashAlgorithm = ((version == 3) ? ((HashAlgorithm)MD5.Create()) : ((HashAlgorithm)SHA1.Create())))
			{
				sourceArray = hashAlgorithm.ComputeHash(buffer);
			}
			byte[] array2 = new byte[16];
			Array.Copy(sourceArray, 0, array2, 0, 16);
			array2[6] = (byte)((array2[6] & 0xF) | (version << 4));
			array2[8] = (byte)((array2[8] & 0x3F) | 0x80);
			SwapByteOrder(array2);
			return new Guid(array2);
		}

		public static Guid CreateVersion6()
		{
			return CreateVersion6(DateTimeOffset.UtcNow);
		}

		private static Guid CreateVersion6(DateTimeOffset timestamp)
		{
			long ticks = (timestamp.UtcDateTime - s_gregorianEpoch).Ticks;
			if (ticks < 0)
			{
				throw new ArgumentOutOfRangeException("timestamp", timestamp, "The timestamp must be after 15 October 1582.");
			}
			uint a = (uint)(ticks >> 28);
			ushort b = (ushort)(ticks >> 12);
			ushort c = (ushort)((ticks & 0xFFF) | 0x6000);
			byte[] array = new byte[8];
			using RandomNumberGenerator randomNumberGenerator = RandomNumberGenerator.Create();
			randomNumberGenerator.GetBytes(array);
			return new Guid(a, b, c, (byte)((array[0] & 0x3F) | 0x80), array[1], array[2], array[3], array[4], array[5], array[6], array[7]);
		}

		public static Guid CreateVersion6FromVersion1(Guid guid)
		{
			byte[] array = guid.ToByteArray();
			if ((array[7] & 0xF0) != 16)
			{
				throw new ArgumentException("The GUID must be a version 1 GUID.", "guid");
			}
			ulong num = (ulong)((long)(array[7] & 0xF) << 56) | ((ulong)array[6] << 48) | ((ulong)array[5] << 40) | ((ulong)array[4] << 32) | ((ulong)array[3] << 24) | ((ulong)array[2] << 16) | ((ulong)array[1] << 8) | array[0];
			array[3] = (byte)(num >> 52);
			array[2] = (byte)(num >> 44);
			array[1] = (byte)(num >> 36);
			array[0] = (byte)(num >> 28);
			array[5] = (byte)(num >> 20);
			array[4] = (byte)(num >> 12);
			array[7] = (byte)(0x60 | ((num >> 8) & 0xF));
			array[6] = (byte)num;
			return new Guid(array);
		}

		public static Guid CreateVersion7()
		{
			return CreateVersion7(DateTimeOffset.UtcNow);
		}

		private static Guid CreateVersion7(DateTimeOffset timestamp)
		{
			long num = timestamp.ToUnixTimeMilliseconds();
			if (num < 0)
			{
				throw new ArgumentOutOfRangeException("timestamp", timestamp, "The timestamp must be after 1 January 1970.");
			}
			uint a = (uint)(num >> 16);
			ushort b = (ushort)num;
			byte[] array = new byte[10];
			using RandomNumberGenerator randomNumberGenerator = RandomNumberGenerator.Create();
			randomNumberGenerator.GetBytes(array);
			ushort c = (ushort)(0x7000uL | (ulong)((array[0] & 0xF) << 8) | array[1]);
			return new Guid(a, b, c, (byte)((array[2] & 0x3F) | 0x80), array[3], array[4], array[5], array[6], array[7], array[8], array[9]);
		}

		public static Guid CreateVersion8(byte[] bytes)
		{
			if (bytes == null)
			{
				throw new ArgumentNullException("bytes");
			}
			if (bytes.Length < 16)
			{
				throw new ArgumentException("At least sixteen bytes must be provided", "bytes");
			}
			byte[] array = new byte[16];
			bytes.AsSpan(0, 16).CopyTo(array);
			SwapByteOrder(array);
			array[7] = (byte)(0x80 | (array[7] & 0xF));
			array[8] = (byte)(0x80 | (array[8] & 0x3F));
			return new Guid(array);
		}

		public static Guid CreateVersion8FromName(HashAlgorithmName hashAlgorithmName, Guid namespaceId, byte[] name)
		{
			var (guid, hashAlgorithm) = GetHashSpaceAndAlgorithm(hashAlgorithmName);
			using (hashAlgorithm)
			{
				byte[] array = guid.ToByteArray();
				SwapByteOrder(array);
				hashAlgorithm.TransformBlock(array, 0, array.Length, null, 0);
				byte[] array2 = namespaceId.ToByteArray();
				SwapByteOrder(array2);
				hashAlgorithm.TransformBlock(array2, 0, array2.Length, null, 0);
				hashAlgorithm.TransformFinalBlock(name, 0, name.Length);
				byte[] array3 = new byte[16];
				Array.Copy(hashAlgorithm.Hash, array3, 16);
				array3[6] = (byte)((array3[6] & 0xF) | 0x80);
				array3[8] = (byte)((array3[8] & 0x3F) | 0x80);
				SwapByteOrder(array3);
				return new Guid(array3);
			}
		}

		private static (Guid NamespaceId, HashAlgorithm Algorithm) GetHashSpaceAndAlgorithm(HashAlgorithmName hashAlgorithmName)
		{
			return hashAlgorithmName.Name switch
			{
				"SHA256" => (NamespaceId: Sha256HashSpaceId, Algorithm: SHA256.Create()), 
				"SHA384" => (NamespaceId: Sha384HashSpaceId, Algorithm: SHA384.Create()), 
				"SHA512" => (NamespaceId: Sha512HashSpaceId, Algorithm: SHA512.Create()), 
				_ => throw new ArgumentException("Unsupported hash algorithm name: " + hashAlgorithmName.Name, "hashAlgorithmName"), 
			};
		}

		internal static void SwapByteOrder(Span<byte> guid)
		{
			SwapBytes(guid, 0, 3);
			SwapBytes(guid, 1, 2);
			SwapBytes(guid, 4, 5);
			SwapBytes(guid, 6, 7);
		}

		private static void SwapBytes(Span<byte> guid, int left, int right)
		{
			ref byte source = ref Unsafe.AsRef(in guid[0]);
			ref byte reference = ref Unsafe.Add(ref source, right);
			ref byte reference2 = ref Unsafe.Add(ref source, left);
			byte b = Unsafe.Add(ref source, left);
			byte b2 = Unsafe.Add(ref source, right);
			reference = b;
			reference2 = b2;
		}
	}
}

plugins/Utf8Json.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Dynamic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Numerics;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using Utf8Json.Formatters;
using Utf8Json.Formatters.Internal;
using Utf8Json.Internal;
using Utf8Json.Internal.DoubleConversion;
using Utf8Json.Internal.Emit;
using Utf8Json.Resolvers;
using Utf8Json.Resolvers.Internal;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("Utf8Json")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("929e3779-4c3a-42a3-bc72-3d77511e988f")]
[assembly: AssemblyFileVersion("1.3.7")]
[assembly: TargetFramework(".NETFramework,Version=v4.7", FrameworkDisplayName = ".NET Framework 4.7")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.3.7.0")]
[module: UnverifiableCode]
namespace Utf8Json
{
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Interface, AllowMultiple = false, Inherited = true)]
	public class JsonFormatterAttribute : Attribute
	{
		public Type FormatterType { get; private set; }

		public object[] Arguments { get; private set; }

		public JsonFormatterAttribute(Type formatterType)
		{
			FormatterType = formatterType;
		}

		public JsonFormatterAttribute(Type formatterType, params object[] arguments)
		{
			FormatterType = formatterType;
			Arguments = arguments;
		}
	}
	[AttributeUsage(AttributeTargets.Constructor, AllowMultiple = false, Inherited = true)]
	public class SerializationConstructorAttribute : Attribute
	{
	}
	public delegate void JsonSerializeAction<T>(ref JsonWriter writer, T value, IJsonFormatterResolver resolver);
	public delegate T JsonDeserializeFunc<T>(ref JsonReader reader, IJsonFormatterResolver resolver);
	public interface IJsonFormatter
	{
	}
	public interface IJsonFormatter<T> : IJsonFormatter
	{
		void Serialize(ref JsonWriter writer, T value, IJsonFormatterResolver formatterResolver);

		T Deserialize(ref JsonReader reader, IJsonFormatterResolver formatterResolver);
	}
	public interface IObjectPropertyNameFormatter<T>
	{
		void SerializeToPropertyName(ref JsonWriter writer, T value, IJsonFormatterResolver formatterResolver);

		T DeserializeFromPropertyName(ref JsonReader reader, IJsonFormatterResolver formatterResolver);
	}
	public static class JsonFormatterExtensions
	{
		public static string ToJsonString<T>(this IJsonFormatter<T> formatter, T value, IJsonFormatterResolver formatterResolver)
		{
			JsonWriter writer = default(JsonWriter);
			formatter.Serialize(ref writer, value, formatterResolver);
			return writer.ToString();
		}
	}
	public interface IJsonFormatterResolver
	{
		IJsonFormatter<T> GetFormatter<T>();
	}
	public static class JsonFormatterResolverExtensions
	{
		public static IJsonFormatter<T> GetFormatterWithVerify<T>(this IJsonFormatterResolver resolver)
		{
			IJsonFormatter<T> formatter;
			try
			{
				formatter = resolver.GetFormatter<T>();
			}
			catch (TypeInitializationException innerException)
			{
				while (innerException.InnerException != null)
				{
					innerException = (TypeInitializationException)innerException.InnerException;
				}
				throw innerException;
			}
			if (formatter == null)
			{
				throw new FormatterNotRegisteredException(typeof(T).FullName + " is not registered in this resolver. resolver:" + resolver.GetType().Name);
			}
			return formatter;
		}

		public static object GetFormatterDynamic(this IJsonFormatterResolver resolver, Type type)
		{
			return typeof(IJsonFormatterResolver).GetRuntimeMethod("GetFormatter", Type.EmptyTypes).MakeGenericMethod(type).Invoke(resolver, null);
		}
	}
	public class FormatterNotRegisteredException : Exception
	{
		public FormatterNotRegisteredException(string message)
			: base(message)
		{
		}
	}
	public struct JsonReader
	{
		internal static class StringBuilderCache
		{
			[ThreadStatic]
			private static byte[] buffer;

			[ThreadStatic]
			private static char[] codePointStringBuffer;

			public static byte[] GetBuffer()
			{
				if (buffer == null)
				{
					buffer = new byte[65535];
				}
				return buffer;
			}

			public static char[] GetCodePointStringBuffer()
			{
				if (codePointStringBuffer == null)
				{
					codePointStringBuffer = new char[65535];
				}
				return codePointStringBuffer;
			}
		}

		private static readonly ArraySegment<byte> nullTokenSegment = new ArraySegment<byte>(new byte[4] { 110, 117, 108, 108 }, 0, 4);

		private static readonly byte[] bom = Encoding.UTF8.GetPreamble();

		private readonly byte[] bytes;

		private int offset;

		private bool IsInRange => offset < bytes.Length;

		public JsonReader(byte[] bytes)
			: this(bytes, 0)
		{
		}

		public JsonReader(byte[] bytes, int offset)
		{
			this.bytes = bytes;
			this.offset = offset;
			checked
			{
				if (bytes.Length >= 3 && bytes[offset] == bom[0] && bytes[offset + 1] == bom[1] && bytes[offset + 2] == bom[2])
				{
					this.offset = (offset += 3);
				}
			}
		}

		private JsonParsingException CreateParsingException(string expected)
		{
			char c = (char)bytes[offset];
			string text = c.ToString();
			int num = offset;
			try
			{
				switch (GetCurrentJsonToken())
				{
				case JsonToken.Number:
				{
					ArraySegment<byte> arraySegment = ReadNumberSegment();
					text = StringEncoding.UTF8.GetString(arraySegment.Array, arraySegment.Offset, arraySegment.Count);
					break;
				}
				case JsonToken.String:
					text = "\"" + ReadString() + "\"";
					break;
				case JsonToken.True:
					text = "true";
					break;
				case JsonToken.False:
					text = "false";
					break;
				case JsonToken.Null:
					text = "null";
					break;
				}
			}
			catch
			{
			}
			return new JsonParsingException("expected:'" + expected + "', actual:'" + text + "', at offset:" + num, bytes, num, offset, text);
		}

		private JsonParsingException CreateParsingExceptionMessage(string message)
		{
			char c = (char)bytes[offset];
			string actualChar = c.ToString();
			int limit = offset;
			return new JsonParsingException(message, bytes, limit, limit, actualChar);
		}

		public void AdvanceOffset(int offset)
		{
			checked
			{
				this.offset += offset;
			}
		}

		public byte[] GetBufferUnsafe()
		{
			return bytes;
		}

		public int GetCurrentOffsetUnsafe()
		{
			return offset;
		}

		public JsonToken GetCurrentJsonToken()
		{
			SkipWhiteSpace();
			if (offset < bytes.Length)
			{
				return bytes[offset] switch
				{
					123 => JsonToken.BeginObject, 
					125 => JsonToken.EndObject, 
					91 => JsonToken.BeginArray, 
					93 => JsonToken.EndArray, 
					116 => JsonToken.True, 
					102 => JsonToken.False, 
					110 => JsonToken.Null, 
					44 => JsonToken.ValueSeparator, 
					58 => JsonToken.NameSeparator, 
					45 => JsonToken.Number, 
					48 => JsonToken.Number, 
					49 => JsonToken.Number, 
					50 => JsonToken.Number, 
					51 => JsonToken.Number, 
					52 => JsonToken.Number, 
					53 => JsonToken.Number, 
					54 => JsonToken.Number, 
					55 => JsonToken.Number, 
					56 => JsonToken.Number, 
					57 => JsonToken.Number, 
					34 => JsonToken.String, 
					_ => JsonToken.None, 
				};
			}
			return JsonToken.None;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public void SkipWhiteSpace()
		{
			for (int i = offset; i < bytes.Length; i = checked(i + 1))
			{
				switch (bytes[i])
				{
				case 47:
					i = ReadComment(bytes, i);
					break;
				default:
					offset = i;
					return;
				case 9:
				case 10:
				case 13:
				case 32:
					break;
				}
			}
			offset = bytes.Length;
		}

		public bool ReadIsNull()
		{
			SkipWhiteSpace();
			checked
			{
				if (IsInRange && bytes[offset] == 110)
				{
					if (bytes[offset + 1] == 117 && bytes[offset + 2] == 108 && bytes[offset + 3] == 108)
					{
						offset += 4;
						return true;
					}
					throw CreateParsingException("null");
				}
				return false;
			}
		}

		public bool ReadIsBeginArray()
		{
			SkipWhiteSpace();
			checked
			{
				if (IsInRange && bytes[offset] == 91)
				{
					offset++;
					return true;
				}
				return false;
			}
		}

		public void ReadIsBeginArrayWithVerify()
		{
			if (!ReadIsBeginArray())
			{
				throw CreateParsingException("[");
			}
		}

		public bool ReadIsEndArray()
		{
			SkipWhiteSpace();
			checked
			{
				if (IsInRange && bytes[offset] == 93)
				{
					offset++;
					return true;
				}
				return false;
			}
		}

		public void ReadIsEndArrayWithVerify()
		{
			if (!ReadIsEndArray())
			{
				throw CreateParsingException("]");
			}
		}

		public bool ReadIsEndArrayWithSkipValueSeparator(ref int count)
		{
			SkipWhiteSpace();
			checked
			{
				if (IsInRange && bytes[offset] == 93)
				{
					offset++;
					return true;
				}
				if (count++ != 0)
				{
					ReadIsValueSeparatorWithVerify();
				}
				return false;
			}
		}

		public bool ReadIsInArray(ref int count)
		{
			if (count == 0)
			{
				ReadIsBeginArrayWithVerify();
				if (ReadIsEndArray())
				{
					return false;
				}
			}
			else
			{
				if (ReadIsEndArray())
				{
					return false;
				}
				ReadIsValueSeparatorWithVerify();
			}
			checked
			{
				count++;
				return true;
			}
		}

		public bool ReadIsBeginObject()
		{
			SkipWhiteSpace();
			checked
			{
				if (IsInRange && bytes[offset] == 123)
				{
					offset++;
					return true;
				}
				return false;
			}
		}

		public void ReadIsBeginObjectWithVerify()
		{
			if (!ReadIsBeginObject())
			{
				throw CreateParsingException("{");
			}
		}

		public bool ReadIsEndObject()
		{
			SkipWhiteSpace();
			checked
			{
				if (IsInRange && bytes[offset] == 125)
				{
					offset++;
					return true;
				}
				return false;
			}
		}

		public void ReadIsEndObjectWithVerify()
		{
			if (!ReadIsEndObject())
			{
				throw CreateParsingException("}");
			}
		}

		public bool ReadIsEndObjectWithSkipValueSeparator(ref int count)
		{
			SkipWhiteSpace();
			checked
			{
				if (IsInRange && bytes[offset] == 125)
				{
					offset++;
					return true;
				}
				if (count++ != 0)
				{
					ReadIsValueSeparatorWithVerify();
				}
				return false;
			}
		}

		public bool ReadIsInObject(ref int count)
		{
			if (count == 0)
			{
				ReadIsBeginObjectWithVerify();
				if (ReadIsEndObject())
				{
					return false;
				}
			}
			else
			{
				if (ReadIsEndObject())
				{
					return false;
				}
				ReadIsValueSeparatorWithVerify();
			}
			checked
			{
				count++;
				return true;
			}
		}

		public bool ReadIsValueSeparator()
		{
			SkipWhiteSpace();
			checked
			{
				if (IsInRange && bytes[offset] == 44)
				{
					offset++;
					return true;
				}
				return false;
			}
		}

		public void ReadIsValueSeparatorWithVerify()
		{
			if (!ReadIsValueSeparator())
			{
				throw CreateParsingException(",");
			}
		}

		public bool ReadIsNameSeparator()
		{
			SkipWhiteSpace();
			checked
			{
				if (IsInRange && bytes[offset] == 58)
				{
					offset++;
					return true;
				}
				return false;
			}
		}

		public void ReadIsNameSeparatorWithVerify()
		{
			if (!ReadIsNameSeparator())
			{
				throw CreateParsingException(":");
			}
		}

		private void ReadStringSegmentCore(out byte[] resultBytes, out int resultOffset, out int resultLength)
		{
			byte[] array = null;
			int num = 0;
			char[] array2 = null;
			int num2 = 0;
			if (bytes[offset] != 34)
			{
				throw CreateParsingException("String Begin Token");
			}
			checked
			{
				offset++;
				int num3 = offset;
				for (int i = offset; i < bytes.Length; i++)
				{
					byte b = 0;
					switch (bytes[i])
					{
					case 92:
					{
						switch (unchecked((char)bytes[checked(i + 1)]))
						{
						case '"':
						case '/':
						case '\\':
							b = bytes[i + 1];
							break;
						case 'b':
							b = 8;
							break;
						case 'f':
							b = 12;
							break;
						case 'n':
							b = 10;
							break;
						case 'r':
							b = 13;
							break;
						case 't':
							b = 9;
							break;
						case 'u':
						{
							if (array2 == null)
							{
								array2 = StringBuilderCache.GetCodePointStringBuffer();
							}
							if (num2 == 0)
							{
								if (array == null)
								{
									array = StringBuilderCache.GetBuffer();
								}
								int num5 = i - num3;
								BinaryUtil.EnsureCapacity(ref array, num, num5 + 1);
								Buffer.BlockCopy(bytes, num3, array, num, num5);
								num += num5;
							}
							if (array2.Length == num2)
							{
								Array.Resize(ref array2, array2.Length * 2);
							}
							byte a = bytes[i + 2];
							unchecked
							{
								char b2 = (char)bytes[checked(i + 3)];
								char c = (char)bytes[checked(i + 4)];
								char d = (char)bytes[checked(i + 5)];
								int codePoint = GetCodePoint((char)a, b2, c, d);
								array2[checked(num2++)] = (char)checked((ushort)codePoint);
							}
							i += 5;
							offset += 6;
							num3 = offset;
							continue;
						}
						default:
							throw CreateParsingExceptionMessage("Bad JSON escape.");
						}
						if (array == null)
						{
							array = StringBuilderCache.GetBuffer();
						}
						if (num2 != 0)
						{
							BinaryUtil.EnsureCapacity(ref array, num, StringEncoding.UTF8.GetMaxByteCount(num2));
							num += StringEncoding.UTF8.GetBytes(array2, 0, num2, array, num);
							num2 = 0;
						}
						int num6 = i - num3;
						BinaryUtil.EnsureCapacity(ref array, num, num6 + 1);
						Buffer.BlockCopy(bytes, num3, array, num, num6);
						num += num6;
						array[num++] = b;
						i++;
						offset += 2;
						num3 = offset;
						continue;
					}
					case 34:
					{
						offset++;
						if (num == 0 && num2 == 0)
						{
							resultBytes = bytes;
							resultOffset = num3;
							resultLength = offset - 1 - num3;
							return;
						}
						if (array == null)
						{
							array = StringBuilderCache.GetBuffer();
						}
						if (num2 != 0)
						{
							BinaryUtil.EnsureCapacity(ref array, num, StringEncoding.UTF8.GetMaxByteCount(num2));
							num += StringEncoding.UTF8.GetBytes(array2, 0, num2, array, num);
							num2 = 0;
						}
						int num4 = offset - num3 - 1;
						BinaryUtil.EnsureCapacity(ref array, num, num4);
						Buffer.BlockCopy(bytes, num3, array, num, num4);
						num += num4;
						resultBytes = array;
						resultOffset = 0;
						resultLength = num;
						return;
					}
					}
					if (num2 != 0)
					{
						if (array == null)
						{
							array = StringBuilderCache.GetBuffer();
						}
						BinaryUtil.EnsureCapacity(ref array, num, StringEncoding.UTF8.GetMaxByteCount(num2));
						num += StringEncoding.UTF8.GetBytes(array2, 0, num2, array, num);
						num2 = 0;
					}
					offset++;
				}
				resultLength = 0;
				resultBytes = null;
				resultOffset = 0;
				throw CreateParsingException("String End Token");
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private static int GetCodePoint(char a, char b, char c, char d)
		{
			return checked(((ToNumber(a) * 16 + ToNumber(b)) * 16 + ToNumber(c)) * 16 + ToNumber(d));
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private static int ToNumber(char x)
		{
			checked
			{
				if ('0' <= x && x <= '9')
				{
					return x - 48;
				}
				if ('a' <= x && x <= 'f')
				{
					return x - 97 + 10;
				}
				if ('A' <= x && x <= 'F')
				{
					return x - 65 + 10;
				}
				throw new JsonParsingException("Invalid Character" + x);
			}
		}

		public ArraySegment<byte> ReadStringSegmentUnsafe()
		{
			if (ReadIsNull())
			{
				return nullTokenSegment;
			}
			ReadStringSegmentCore(out var resultBytes, out var resultOffset, out var resultLength);
			return new ArraySegment<byte>(resultBytes, resultOffset, resultLength);
		}

		public string ReadString()
		{
			if (ReadIsNull())
			{
				return null;
			}
			ReadStringSegmentCore(out var resultBytes, out var resultOffset, out var resultLength);
			return Encoding.UTF8.GetString(resultBytes, resultOffset, resultLength);
		}

		public string ReadPropertyName()
		{
			string result = ReadString();
			ReadIsNameSeparatorWithVerify();
			return result;
		}

		public ArraySegment<byte> ReadStringSegmentRaw()
		{
			ArraySegment<byte> arraySegment = default(ArraySegment<byte>);
			if (ReadIsNull())
			{
				return nullTokenSegment;
			}
			checked
			{
				if (bytes[offset++] != 34)
				{
					throw CreateParsingException("\"");
				}
				int num = offset;
				for (int i = offset; i < bytes.Length; i++)
				{
					if (bytes[i] == 34 && bytes[i - 1] != 92)
					{
						offset = i + 1;
						return new ArraySegment<byte>(bytes, num, offset - num - 1);
					}
				}
				throw CreateParsingExceptionMessage("not found end string.");
			}
		}

		public ArraySegment<byte> ReadPropertyNameSegmentRaw()
		{
			ArraySegment<byte> result = ReadStringSegmentRaw();
			ReadIsNameSeparatorWithVerify();
			return result;
		}

		public bool ReadBoolean()
		{
			SkipWhiteSpace();
			checked
			{
				if (bytes[offset] == 116)
				{
					if (bytes[offset + 1] == 114 && bytes[offset + 2] == 117 && bytes[offset + 3] == 101)
					{
						offset += 4;
						return true;
					}
					throw CreateParsingException("true");
				}
				if (bytes[offset] == 102)
				{
					if (bytes[offset + 1] == 97 && bytes[offset + 2] == 108 && bytes[offset + 3] == 115 && bytes[offset + 4] == 101)
					{
						offset += 5;
						return false;
					}
					throw CreateParsingException("false");
				}
				throw CreateParsingException("true | false");
			}
		}

		private static bool IsWordBreak(byte c)
		{
			switch (c)
			{
			case 32:
			case 34:
			case 44:
			case 58:
			case 91:
			case 93:
			case 123:
			case 125:
				return true;
			default:
				return false;
			}
		}

		public void ReadNext()
		{
			JsonToken currentJsonToken = GetCurrentJsonToken();
			ReadNextCore(currentJsonToken);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private void ReadNextCore(JsonToken token)
		{
			checked
			{
				switch (token)
				{
				case JsonToken.BeginObject:
				case JsonToken.EndObject:
				case JsonToken.BeginArray:
				case JsonToken.EndArray:
				case JsonToken.ValueSeparator:
				case JsonToken.NameSeparator:
					offset++;
					break;
				case JsonToken.True:
				case JsonToken.Null:
					offset += 4;
					break;
				case JsonToken.False:
					offset += 5;
					break;
				case JsonToken.String:
				{
					offset++;
					for (int j = offset; j < bytes.Length; j++)
					{
						if (bytes[j] == 34 && bytes[j - 1] != 92)
						{
							offset = j + 1;
							return;
						}
					}
					throw CreateParsingExceptionMessage("not found end string.");
				}
				case JsonToken.Number:
				{
					for (int i = offset; i < bytes.Length; i++)
					{
						if (IsWordBreak(bytes[i]))
						{
							offset = i;
							return;
						}
					}
					offset = bytes.Length;
					break;
				}
				case JsonToken.None:
					break;
				}
			}
		}

		public void ReadNextBlock()
		{
			ReadNextBlockCore(0);
		}

		private void ReadNextBlockCore(int stack)
		{
			JsonToken currentJsonToken = GetCurrentJsonToken();
			checked
			{
				switch (currentJsonToken)
				{
				default:
					return;
				case JsonToken.BeginObject:
				case JsonToken.BeginArray:
					offset++;
					ReadNextBlockCore(stack + 1);
					return;
				case JsonToken.EndObject:
				case JsonToken.EndArray:
					offset++;
					if (stack - 1 != 0)
					{
						ReadNextBlockCore(stack - 1);
					}
					return;
				case JsonToken.Number:
				case JsonToken.String:
				case JsonToken.True:
				case JsonToken.False:
				case JsonToken.Null:
				case JsonToken.ValueSeparator:
				case JsonToken.NameSeparator:
					break;
				case JsonToken.None:
					return;
				}
			}
			do
			{
				ReadNextCore(currentJsonToken);
				currentJsonToken = GetCurrentJsonToken();
			}
			while (stack != 0 && (int)currentJsonToken >= 5);
			if (stack != 0)
			{
				ReadNextBlockCore(stack);
			}
		}

		public ArraySegment<byte> ReadNextBlockSegment()
		{
			int num = offset;
			ReadNextBlock();
			return new ArraySegment<byte>(bytes, num, checked(offset - num));
		}

		public sbyte ReadSByte()
		{
			return checked((sbyte)ReadInt64());
		}

		public short ReadInt16()
		{
			return checked((short)ReadInt64());
		}

		public int ReadInt32()
		{
			return checked((int)ReadInt64());
		}

		public long ReadInt64()
		{
			SkipWhiteSpace();
			int readCount;
			long result = NumberConverter.ReadInt64(bytes, offset, out readCount);
			if (readCount == 0)
			{
				throw CreateParsingException("Number Token");
			}
			checked
			{
				offset += readCount;
				return result;
			}
		}

		public byte ReadByte()
		{
			return checked((byte)ReadUInt64());
		}

		public ushort ReadUInt16()
		{
			return checked((ushort)ReadUInt64());
		}

		public uint ReadUInt32()
		{
			return checked((uint)ReadUInt64());
		}

		public ulong ReadUInt64()
		{
			SkipWhiteSpace();
			int readCount;
			ulong result = NumberConverter.ReadUInt64(bytes, offset, out readCount);
			if (readCount == 0)
			{
				throw CreateParsingException("Number Token");
			}
			checked
			{
				offset += readCount;
				return result;
			}
		}

		public float ReadSingle()
		{
			SkipWhiteSpace();
			int readCount;
			float result = StringToDoubleConverter.ToSingle(bytes, offset, out readCount);
			if (readCount == 0)
			{
				throw CreateParsingException("Number Token");
			}
			checked
			{
				offset += readCount;
				return result;
			}
		}

		public double ReadDouble()
		{
			SkipWhiteSpace();
			int readCount;
			double result = StringToDoubleConverter.ToDouble(bytes, offset, out readCount);
			if (readCount == 0)
			{
				throw CreateParsingException("Number Token");
			}
			checked
			{
				offset += readCount;
				return result;
			}
		}

		public ArraySegment<byte> ReadNumberSegment()
		{
			SkipWhiteSpace();
			int num = offset;
			int num2 = offset;
			checked
			{
				while (true)
				{
					if (num2 < bytes.Length)
					{
						if (!NumberConverter.IsNumberRepresentation(bytes[num2]))
						{
							offset = num2;
							break;
						}
						num2++;
						continue;
					}
					offset = bytes.Length;
					break;
				}
				return new ArraySegment<byte>(bytes, num, offset - num);
			}
		}

		private static int ReadComment(byte[] bytes, int offset)
		{
			checked
			{
				if (bytes[offset + 1] == 47)
				{
					offset += 2;
					for (int i = offset; i < bytes.Length; i++)
					{
						if (bytes[i] == 13 || bytes[i] == 10)
						{
							return i;
						}
					}
					throw new JsonParsingException("Can not find end token of single line comment(\r or \n).");
				}
				if (bytes[offset + 1] == 42)
				{
					offset += 2;
					for (int j = offset; j < bytes.Length; j++)
					{
						if (bytes[j] == 42 && bytes[j + 1] == 47)
						{
							return j + 1;
						}
					}
					throw new JsonParsingException("Can not find end token of multi line comment(*/).");
				}
				return offset;
			}
		}
	}
	public class JsonParsingException : Exception
	{
		private WeakReference underyingBytes;

		private int limit;

		public int Offset { get; private set; }

		public string ActualChar { get; set; }

		public JsonParsingException(string message)
			: base(message)
		{
		}

		public JsonParsingException(string message, byte[] underlyingBytes, int offset, int limit, string actualChar)
			: base(message)
		{
			underyingBytes = new WeakReference(underlyingBytes);
			Offset = offset;
			ActualChar = actualChar;
			this.limit = limit;
		}

		public byte[] GetUnderlyingByteArrayUnsafe()
		{
			return underyingBytes.Target as byte[];
		}

		public string GetUnderlyingStringUnsafe()
		{
			if (underyingBytes.Target is byte[] bytes)
			{
				return StringEncoding.UTF8.GetString(bytes, 0, limit) + "...";
			}
			return null;
		}
	}
	public static class JsonSerializer
	{
		private static class MemoryPool
		{
			[ThreadStatic]
			private static byte[] buffer;

			public static byte[] GetBuffer()
			{
				if (buffer == null)
				{
					buffer = new byte[65536];
				}
				return buffer;
			}
		}

		public static class NonGeneric
		{
			private delegate void SerializeJsonWriter(ref JsonWriter writer, object value, IJsonFormatterResolver resolver);

			private delegate object DeserializeJsonReader(ref JsonReader reader, IJsonFormatterResolver resolver);

			private class CompiledMethods
			{
				public readonly Func<object, IJsonFormatterResolver, byte[]> serialize1;

				public readonly Action<Stream, object, IJsonFormatterResolver> serialize2;

				public readonly SerializeJsonWriter serialize3;

				public readonly Func<object, IJsonFormatterResolver, ArraySegment<byte>> serializeUnsafe;

				public readonly Func<object, IJsonFormatterResolver, string> toJsonString;

				public readonly Func<string, IJsonFormatterResolver, object> deserialize1;

				public readonly Func<byte[], int, IJsonFormatterResolver, object> deserialize2;

				public readonly Func<Stream, IJsonFormatterResolver, object> deserialize3;

				public readonly DeserializeJsonReader deserialize4;

				public readonly Func<Stream, object, IJsonFormatterResolver, Task> serializeAsync;

				public readonly Func<Stream, IJsonFormatterResolver, Task<object>> deserializeAsync;

				public CompiledMethods(Type type)
				{
					DynamicMethod dynamicMethod = new DynamicMethod("serialize1", typeof(byte[]), new Type[2]
					{
						typeof(object),
						typeof(IJsonFormatterResolver)
					}, type.Module, skipVisibility: true);
					ILGenerator iLGenerator = dynamicMethod.GetILGenerator();
					iLGenerator.EmitLdarg(0);
					iLGenerator.EmitUnboxOrCast(type);
					iLGenerator.EmitLdarg(1);
					iLGenerator.EmitCall(GetMethod(type, "Serialize", new Type[2]
					{
						null,
						typeof(IJsonFormatterResolver)
					}));
					iLGenerator.Emit(OpCodes.Ret);
					serialize1 = CreateDelegate<Func<object, IJsonFormatterResolver, byte[]>>(dynamicMethod);
					DynamicMethod dynamicMethod2 = new DynamicMethod("serialize2", null, new Type[3]
					{
						typeof(Stream),
						typeof(object),
						typeof(IJsonFormatterResolver)
					}, type.Module, skipVisibility: true);
					ILGenerator iLGenerator2 = dynamicMethod2.GetILGenerator();
					iLGenerator2.EmitLdarg(0);
					iLGenerator2.EmitLdarg(1);
					iLGenerator2.EmitUnboxOrCast(type);
					iLGenerator2.EmitLdarg(2);
					iLGenerator2.EmitCall(GetMethod(type, "Serialize", new Type[3]
					{
						typeof(Stream),
						null,
						typeof(IJsonFormatterResolver)
					}));
					iLGenerator2.Emit(OpCodes.Ret);
					serialize2 = CreateDelegate<Action<Stream, object, IJsonFormatterResolver>>(dynamicMethod2);
					DynamicMethod dynamicMethod3 = new DynamicMethod("serialize3", null, new Type[3]
					{
						typeof(JsonWriter).MakeByRefType(),
						typeof(object),
						typeof(IJsonFormatterResolver)
					}, type.Module, skipVisibility: true);
					ILGenerator iLGenerator3 = dynamicMethod3.GetILGenerator();
					iLGenerator3.EmitLdarg(0);
					iLGenerator3.EmitLdarg(1);
					iLGenerator3.EmitUnboxOrCast(type);
					iLGenerator3.EmitLdarg(2);
					iLGenerator3.EmitCall(GetMethod(type, "Serialize", new Type[3]
					{
						typeof(JsonWriter).MakeByRefType(),
						null,
						typeof(IJsonFormatterResolver)
					}));
					iLGenerator3.Emit(OpCodes.Ret);
					serialize3 = CreateDelegate<SerializeJsonWriter>(dynamicMethod3);
					DynamicMethod dynamicMethod4 = new DynamicMethod("serializeUnsafe", typeof(ArraySegment<byte>), new Type[2]
					{
						typeof(object),
						typeof(IJsonFormatterResolver)
					}, type.Module, skipVisibility: true);
					ILGenerator iLGenerator4 = dynamicMethod4.GetILGenerator();
					iLGenerator4.EmitLdarg(0);
					iLGenerator4.EmitUnboxOrCast(type);
					iLGenerator4.EmitLdarg(1);
					iLGenerator4.EmitCall(GetMethod(type, "SerializeUnsafe", new Type[2]
					{
						null,
						typeof(IJsonFormatterResolver)
					}));
					iLGenerator4.Emit(OpCodes.Ret);
					serializeUnsafe = CreateDelegate<Func<object, IJsonFormatterResolver, ArraySegment<byte>>>(dynamicMethod4);
					DynamicMethod dynamicMethod5 = new DynamicMethod("toJsonString", typeof(string), new Type[2]
					{
						typeof(object),
						typeof(IJsonFormatterResolver)
					}, type.Module, skipVisibility: true);
					ILGenerator iLGenerator5 = dynamicMethod5.GetILGenerator();
					iLGenerator5.EmitLdarg(0);
					iLGenerator5.EmitUnboxOrCast(type);
					iLGenerator5.EmitLdarg(1);
					iLGenerator5.EmitCall(GetMethod(type, "ToJsonString", new Type[2]
					{
						null,
						typeof(IJsonFormatterResolver)
					}));
					iLGenerator5.Emit(OpCodes.Ret);
					toJsonString = CreateDelegate<Func<object, IJsonFormatterResolver, string>>(dynamicMethod5);
					DynamicMethod dynamicMethod6 = new DynamicMethod("Deserialize", typeof(object), new Type[2]
					{
						typeof(string),
						typeof(IJsonFormatterResolver)
					}, type.Module, skipVisibility: true);
					ILGenerator iLGenerator6 = dynamicMethod6.GetILGenerator();
					iLGenerator6.EmitLdarg(0);
					iLGenerator6.EmitLdarg(1);
					iLGenerator6.EmitCall(GetMethod(type, "Deserialize", new Type[2]
					{
						typeof(string),
						typeof(IJsonFormatterResolver)
					}));
					iLGenerator6.EmitBoxOrDoNothing(type);
					iLGenerator6.Emit(OpCodes.Ret);
					deserialize1 = CreateDelegate<Func<string, IJsonFormatterResolver, object>>(dynamicMethod6);
					DynamicMethod dynamicMethod7 = new DynamicMethod("Deserialize", typeof(object), new Type[3]
					{
						typeof(byte[]),
						typeof(int),
						typeof(IJsonFormatterResolver)
					}, type.Module, skipVisibility: true);
					ILGenerator iLGenerator7 = dynamicMethod7.GetILGenerator();
					iLGenerator7.EmitLdarg(0);
					iLGenerator7.EmitLdarg(1);
					iLGenerator7.EmitLdarg(2);
					iLGenerator7.EmitCall(GetMethod(type, "Deserialize", new Type[3]
					{
						typeof(byte[]),
						typeof(int),
						typeof(IJsonFormatterResolver)
					}));
					iLGenerator7.EmitBoxOrDoNothing(type);
					iLGenerator7.Emit(OpCodes.Ret);
					deserialize2 = CreateDelegate<Func<byte[], int, IJsonFormatterResolver, object>>(dynamicMethod7);
					DynamicMethod dynamicMethod8 = new DynamicMethod("Deserialize", typeof(object), new Type[2]
					{
						typeof(Stream),
						typeof(IJsonFormatterResolver)
					}, type.Module, skipVisibility: true);
					ILGenerator iLGenerator8 = dynamicMethod8.GetILGenerator();
					iLGenerator8.EmitLdarg(0);
					iLGenerator8.EmitLdarg(1);
					iLGenerator8.EmitCall(GetMethod(type, "Deserialize", new Type[2]
					{
						typeof(Stream),
						typeof(IJsonFormatterResolver)
					}));
					iLGenerator8.EmitBoxOrDoNothing(type);
					iLGenerator8.Emit(OpCodes.Ret);
					deserialize3 = CreateDelegate<Func<Stream, IJsonFormatterResolver, object>>(dynamicMethod8);
					DynamicMethod dynamicMethod9 = new DynamicMethod("Deserialize", typeof(object), new Type[2]
					{
						typeof(JsonReader).MakeByRefType(),
						typeof(IJsonFormatterResolver)
					}, type.Module, skipVisibility: true);
					ILGenerator iLGenerator9 = dynamicMethod9.GetILGenerator();
					iLGenerator9.EmitLdarg(0);
					iLGenerator9.EmitLdarg(1);
					iLGenerator9.EmitCall(GetMethod(type, "Deserialize", new Type[2]
					{
						typeof(JsonReader).MakeByRefType(),
						typeof(IJsonFormatterResolver)
					}));
					iLGenerator9.EmitBoxOrDoNothing(type);
					iLGenerator9.Emit(OpCodes.Ret);
					deserialize4 = CreateDelegate<DeserializeJsonReader>(dynamicMethod9);
					DynamicMethod dynamicMethod10 = new DynamicMethod("SerializeAsync", typeof(Task), new Type[3]
					{
						typeof(Stream),
						typeof(object),
						typeof(IJsonFormatterResolver)
					}, type.Module, skipVisibility: true);
					ILGenerator iLGenerator10 = dynamicMethod10.GetILGenerator();
					iLGenerator10.EmitLdarg(0);
					iLGenerator10.EmitLdarg(1);
					iLGenerator10.EmitUnboxOrCast(type);
					iLGenerator10.EmitLdarg(2);
					iLGenerator10.EmitCall(GetMethod(type, "SerializeAsync", new Type[3]
					{
						typeof(Stream),
						null,
						typeof(IJsonFormatterResolver)
					}));
					iLGenerator10.Emit(OpCodes.Ret);
					serializeAsync = CreateDelegate<Func<Stream, object, IJsonFormatterResolver, Task>>(dynamicMethod10);
					DynamicMethod dynamicMethod11 = new DynamicMethod("DeserializeAsync", typeof(Task<object>), new Type[2]
					{
						typeof(Stream),
						typeof(IJsonFormatterResolver)
					}, type.Module, skipVisibility: true);
					ILGenerator iLGenerator11 = dynamicMethod11.GetILGenerator();
					iLGenerator11.EmitLdarg(0);
					iLGenerator11.EmitLdarg(1);
					iLGenerator11.EmitCall(GetMethod(type, "DeserializeAsync", new Type[2]
					{
						typeof(Stream),
						typeof(IJsonFormatterResolver)
					}));
					iLGenerator11.EmitCall(typeof(CompiledMethods).GetMethod("TaskCast", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).MakeGenericMethod(type));
					iLGenerator11.Emit(OpCodes.Ret);
					deserializeAsync = CreateDelegate<Func<Stream, IJsonFormatterResolver, Task<object>>>(dynamicMethod11);
				}

				private static async Task<object> TaskCast<T>(Task<T> task)
				{
					return await task.ConfigureAwait(continueOnCapturedContext: false);
				}

				private static T CreateDelegate<T>(DynamicMethod dm)
				{
					return (T)(object)dm.CreateDelegate(typeof(T));
				}

				private static MethodInfo GetMethod(Type type, string name, Type[] arguments)
				{
					return (from x in typeof(JsonSerializer).GetMethods(BindingFlags.Static | BindingFlags.Public)
						where x.Name == name
						select x).Single(delegate(MethodInfo x)
					{
						ParameterInfo[] parameters = x.GetParameters();
						if (parameters.Length != arguments.Length)
						{
							return false;
						}
						for (int i = 0; i < parameters.Length; i = checked(i + 1))
						{
							if ((!(arguments[i] == null) || !parameters[i].ParameterType.IsGenericParameter) && parameters[i].ParameterType != arguments[i])
							{
								return false;
							}
						}
						return true;
					}).MakeGenericMethod(type);
				}
			}

			private static readonly Func<Type, CompiledMethods> CreateCompiledMethods;

			private static readonly ThreadsafeTypeKeyHashTable<CompiledMethods> serializes;

			static NonGeneric()
			{
				serializes = new ThreadsafeTypeKeyHashTable<CompiledMethods>(64);
				CreateCompiledMethods = (Type t) => new CompiledMethods(t);
			}

			private static CompiledMethods GetOrAdd(Type type)
			{
				return serializes.GetOrAdd(type, CreateCompiledMethods);
			}

			public static byte[] Serialize(object value)
			{
				if (value == null)
				{
					return JsonSerializer.Serialize(value);
				}
				return Serialize(value.GetType(), value, defaultResolver);
			}

			public static byte[] Serialize(Type type, object value)
			{
				return Serialize(type, value, defaultResolver);
			}

			public static byte[] Serialize(object value, IJsonFormatterResolver resolver)
			{
				if (value == null)
				{
					return JsonSerializer.Serialize(value, resolver);
				}
				return Serialize(value.GetType(), value, resolver);
			}

			public static byte[] Serialize(Type type, object value, IJsonFormatterResolver resolver)
			{
				return GetOrAdd(type).serialize1(value, resolver);
			}

			public static void Serialize(Stream stream, object value)
			{
				if (value == null)
				{
					JsonSerializer.Serialize(stream, value);
				}
				else
				{
					Serialize(value.GetType(), stream, value, defaultResolver);
				}
			}

			public static void Serialize(Type type, Stream stream, object value)
			{
				Serialize(type, stream, value, defaultResolver);
			}

			public static void Serialize(Stream stream, object value, IJsonFormatterResolver resolver)
			{
				if (value == null)
				{
					JsonSerializer.Serialize(stream, value, resolver);
				}
				else
				{
					Serialize(value.GetType(), stream, value, resolver);
				}
			}

			public static void Serialize(Type type, Stream stream, object value, IJsonFormatterResolver resolver)
			{
				GetOrAdd(type).serialize2(stream, value, resolver);
			}

			public static Task SerializeAsync(Stream stream, object value)
			{
				if (value == null)
				{
					return JsonSerializer.SerializeAsync(stream, value);
				}
				return SerializeAsync(value.GetType(), stream, value, defaultResolver);
			}

			public static Task SerializeAsync(Type type, Stream stream, object value)
			{
				return SerializeAsync(type, stream, value, defaultResolver);
			}

			public static Task SerializeAsync(Stream stream, object value, IJsonFormatterResolver resolver)
			{
				if (value == null)
				{
					return JsonSerializer.SerializeAsync(stream, value, resolver);
				}
				return SerializeAsync(value.GetType(), stream, value, resolver);
			}

			public static Task SerializeAsync(Type type, Stream stream, object value, IJsonFormatterResolver resolver)
			{
				return GetOrAdd(type).serializeAsync(stream, value, resolver);
			}

			public static void Serialize(ref JsonWriter writer, object value, IJsonFormatterResolver resolver)
			{
				if (value == null)
				{
					writer.WriteNull();
				}
				else
				{
					Serialize(value.GetType(), ref writer, value, resolver);
				}
			}

			public static void Serialize(Type type, ref JsonWriter writer, object value)
			{
				Serialize(type, ref writer, value, defaultResolver);
			}

			public static void Serialize(Type type, ref JsonWriter writer, object value, IJsonFormatterResolver resolver)
			{
				GetOrAdd(type).serialize3(ref writer, value, resolver);
			}

			public static ArraySegment<byte> SerializeUnsafe(object value)
			{
				if (value == null)
				{
					return JsonSerializer.SerializeUnsafe(value);
				}
				return SerializeUnsafe(value.GetType(), value);
			}

			public static ArraySegment<byte> SerializeUnsafe(Type type, object value)
			{
				return SerializeUnsafe(type, value, defaultResolver);
			}

			public static ArraySegment<byte> SerializeUnsafe(object value, IJsonFormatterResolver resolver)
			{
				if (value == null)
				{
					return JsonSerializer.SerializeUnsafe(value);
				}
				return SerializeUnsafe(value.GetType(), value, resolver);
			}

			public static ArraySegment<byte> SerializeUnsafe(Type type, object value, IJsonFormatterResolver resolver)
			{
				return GetOrAdd(type).serializeUnsafe(value, resolver);
			}

			public static string ToJsonString(object value)
			{
				if (value == null)
				{
					return "null";
				}
				return ToJsonString(value.GetType(), value);
			}

			public static string ToJsonString(Type type, object value)
			{
				return ToJsonString(type, value, defaultResolver);
			}

			public static string ToJsonString(object value, IJsonFormatterResolver resolver)
			{
				if (value == null)
				{
					return "null";
				}
				return ToJsonString(value.GetType(), value, resolver);
			}

			public static string ToJsonString(Type type, object value, IJsonFormatterResolver resolver)
			{
				return GetOrAdd(type).toJsonString(value, resolver);
			}

			public static object Deserialize(Type type, string json)
			{
				return Deserialize(type, json, defaultResolver);
			}

			public static object Deserialize(Type type, string json, IJsonFormatterResolver resolver)
			{
				return GetOrAdd(type).deserialize1(json, resolver);
			}

			public static object Deserialize(Type type, byte[] bytes)
			{
				return Deserialize(type, bytes, defaultResolver);
			}

			public static object Deserialize(Type type, byte[] bytes, IJsonFormatterResolver resolver)
			{
				return Deserialize(type, bytes, 0, defaultResolver);
			}

			public static object Deserialize(Type type, byte[] bytes, int offset)
			{
				return Deserialize(type, bytes, offset, defaultResolver);
			}

			public static object Deserialize(Type type, byte[] bytes, int offset, IJsonFormatterResolver resolver)
			{
				return GetOrAdd(type).deserialize2(bytes, offset, resolver);
			}

			public static object Deserialize(Type type, Stream stream)
			{
				return Deserialize(type, stream, defaultResolver);
			}

			public static object Deserialize(Type type, Stream stream, IJsonFormatterResolver resolver)
			{
				return GetOrAdd(type).deserialize3(stream, resolver);
			}

			public static object Deserialize(Type type, ref JsonReader reader)
			{
				return Deserialize(type, ref reader, defaultResolver);
			}

			public static object Deserialize(Type type, ref JsonReader reader, IJsonFormatterResolver resolver)
			{
				return GetOrAdd(type).deserialize4(ref reader, resolver);
			}

			public static Task<object> DeserializeAsync(Type type, Stream stream)
			{
				return DeserializeAsync(type, stream, defaultResolver);
			}

			public static Task<object> DeserializeAsync(Type type, Stream stream, IJsonFormatterResolver resolver)
			{
				return GetOrAdd(type).deserializeAsync(stream, resolver);
			}
		}

		private static IJsonFormatterResolver defaultResolver;

		private static readonly byte[][] indent = (from x in Enumerable.Range(0, 100)
			select Encoding.UTF8.GetBytes(new string(' ', checked(x * 2)))).ToArray();

		private static readonly byte[] newLine = Encoding.UTF8.GetBytes(Environment.NewLine);

		public static IJsonFormatterResolver DefaultResolver
		{
			get
			{
				if (defaultResolver == null)
				{
					defaultResolver = StandardResolver.Default;
				}
				return defaultResolver;
			}
		}

		public static bool IsInitialized => defaultResolver != null;

		public static void SetDefaultResolver(IJsonFormatterResolver resolver)
		{
			defaultResolver = resolver;
		}

		public static byte[] Serialize<T>(T obj)
		{
			return Serialize(obj, defaultResolver);
		}

		public static byte[] Serialize<T>(T value, IJsonFormatterResolver resolver)
		{
			if (resolver == null)
			{
				resolver = DefaultResolver;
			}
			JsonWriter writer = new JsonWriter(MemoryPool.GetBuffer());
			resolver.GetFormatterWithVerify<T>().Serialize(ref writer, value, resolver);
			return writer.ToUtf8ByteArray();
		}

		public static void Serialize<T>(ref JsonWriter writer, T value)
		{
			Serialize(ref writer, value, defaultResolver);
		}

		public static void Serialize<T>(ref JsonWriter writer, T value, IJsonFormatterResolver resolver)
		{
			if (resolver == null)
			{
				resolver = DefaultResolver;
			}
			resolver.GetFormatterWithVerify<T>().Serialize(ref writer, value, resolver);
		}

		public static void Serialize<T>(Stream stream, T value)
		{
			Serialize(stream, value, defaultResolver);
		}

		public static void Serialize<T>(Stream stream, T value, IJsonFormatterResolver resolver)
		{
			if (resolver == null)
			{
				resolver = DefaultResolver;
			}
			ArraySegment<byte> arraySegment = SerializeUnsafe(value, resolver);
			stream.Write(arraySegment.Array, arraySegment.Offset, arraySegment.Count);
		}

		public static Task SerializeAsync<T>(Stream stream, T value)
		{
			return SerializeAsync(stream, value, defaultResolver);
		}

		public static async Task SerializeAsync<T>(Stream stream, T value, IJsonFormatterResolver resolver)
		{
			if (resolver == null)
			{
				resolver = DefaultResolver;
			}
			byte[] buf = BufferPool.Default.Rent();
			try
			{
				JsonWriter writer = new JsonWriter(buf);
				resolver.GetFormatterWithVerify<T>().Serialize(ref writer, value, resolver);
				ArraySegment<byte> buffer = writer.GetBuffer();
				await stream.WriteAsync(buffer.Array, buffer.Offset, buffer.Count).ConfigureAwait(continueOnCapturedContext: false);
			}
			finally
			{
				BufferPool.Default.Return(buf);
			}
		}

		public static ArraySegment<byte> SerializeUnsafe<T>(T obj)
		{
			return SerializeUnsafe(obj, defaultResolver);
		}

		public static ArraySegment<byte> SerializeUnsafe<T>(T value, IJsonFormatterResolver resolver)
		{
			if (resolver == null)
			{
				resolver = DefaultResolver;
			}
			JsonWriter writer = new JsonWriter(MemoryPool.GetBuffer());
			resolver.GetFormatterWithVerify<T>().Serialize(ref writer, value, resolver);
			return writer.GetBuffer();
		}

		public static string ToJsonString<T>(T value)
		{
			return ToJsonString(value, defaultResolver);
		}

		public static string ToJsonString<T>(T value, IJsonFormatterResolver resolver)
		{
			if (resolver == null)
			{
				resolver = DefaultResolver;
			}
			JsonWriter writer = new JsonWriter(MemoryPool.GetBuffer());
			resolver.GetFormatterWithVerify<T>().Serialize(ref writer, value, resolver);
			return writer.ToString();
		}

		public static T Deserialize<T>(string json)
		{
			return Deserialize<T>(json, defaultResolver);
		}

		public static T Deserialize<T>(string json, IJsonFormatterResolver resolver)
		{
			return Deserialize<T>(StringEncoding.UTF8.GetBytes(json), resolver);
		}

		public static T Deserialize<T>(byte[] bytes)
		{
			return Deserialize<T>(bytes, defaultResolver);
		}

		public static T Deserialize<T>(byte[] bytes, IJsonFormatterResolver resolver)
		{
			return Deserialize<T>(bytes, 0, resolver);
		}

		public static T Deserialize<T>(byte[] bytes, int offset)
		{
			return Deserialize<T>(bytes, offset, defaultResolver);
		}

		public static T Deserialize<T>(byte[] bytes, int offset, IJsonFormatterResolver resolver)
		{
			if (resolver == null)
			{
				resolver = DefaultResolver;
			}
			JsonReader reader = new JsonReader(bytes, offset);
			return resolver.GetFormatterWithVerify<T>().Deserialize(ref reader, resolver);
		}

		public static T Deserialize<T>(ref JsonReader reader)
		{
			return Deserialize<T>(ref reader, defaultResolver);
		}

		public static T Deserialize<T>(ref JsonReader reader, IJsonFormatterResolver resolver)
		{
			if (resolver == null)
			{
				resolver = DefaultResolver;
			}
			return resolver.GetFormatterWithVerify<T>().Deserialize(ref reader, resolver);
		}

		public static T Deserialize<T>(Stream stream)
		{
			return Deserialize<T>(stream, defaultResolver);
		}

		public static T Deserialize<T>(Stream stream, IJsonFormatterResolver resolver)
		{
			if (resolver == null)
			{
				resolver = DefaultResolver;
			}
			if (stream is MemoryStream memoryStream && memoryStream.TryGetBuffer(out var buffer))
			{
				if (new JsonReader(buffer.Array, buffer.Offset).GetCurrentJsonToken() == JsonToken.Number)
				{
					byte[] array = new byte[buffer.Count];
					Buffer.BlockCopy(buffer.Array, buffer.Offset, array, 0, array.Length);
					return Deserialize<T>(array, 0, resolver);
				}
				return Deserialize<T>(buffer.Array, buffer.Offset, resolver);
			}
			byte[] buffer2 = MemoryPool.GetBuffer();
			int newSize = FillFromStream(stream, ref buffer2);
			if (new JsonReader(buffer2).GetCurrentJsonToken() == JsonToken.Number)
			{
				buffer2 = BinaryUtil.FastCloneWithResize(buffer2, newSize);
			}
			return Deserialize<T>(buffer2, resolver);
		}

		public static Task<T> DeserializeAsync<T>(Stream stream)
		{
			return DeserializeAsync<T>(stream, defaultResolver);
		}

		public static async Task<T> DeserializeAsync<T>(Stream stream, IJsonFormatterResolver resolver)
		{
			if (resolver == null)
			{
				resolver = DefaultResolver;
			}
			byte[] buffer = BufferPool.Default.Rent();
			byte[] buf = buffer;
			checked
			{
				try
				{
					int length = 0;
					while (true)
					{
						int num;
						int read = (num = await stream.ReadAsync(buf, length, buf.Length - length).ConfigureAwait(continueOnCapturedContext: false));
						if (num <= 0)
						{
							break;
						}
						length += read;
						if (length == buf.Length)
						{
							BinaryUtil.FastResize(ref buf, length * 2);
						}
					}
					if (new JsonReader(buf).GetCurrentJsonToken() == JsonToken.Number)
					{
						buf = BinaryUtil.FastCloneWithResize(buf, length);
					}
					return Deserialize<T>(buf, resolver);
				}
				finally
				{
					BufferPool.Default.Return(buffer);
				}
			}
		}

		public static string PrettyPrint(byte[] json)
		{
			return PrettyPrint(json, 0);
		}

		public static string PrettyPrint(byte[] json, int offset)
		{
			JsonReader reader = new JsonReader(json, offset);
			JsonWriter writer = new JsonWriter(MemoryPool.GetBuffer());
			WritePrittyPrint(ref reader, ref writer, 0);
			return writer.ToString();
		}

		public static string PrettyPrint(string json)
		{
			JsonReader reader = new JsonReader(Encoding.UTF8.GetBytes(json));
			JsonWriter writer = new JsonWriter(MemoryPool.GetBuffer());
			WritePrittyPrint(ref reader, ref writer, 0);
			return writer.ToString();
		}

		public static byte[] PrettyPrintByteArray(byte[] json)
		{
			return PrettyPrintByteArray(json, 0);
		}

		public static byte[] PrettyPrintByteArray(byte[] json, int offset)
		{
			JsonReader reader = new JsonReader(json, offset);
			JsonWriter writer = new JsonWriter(MemoryPool.GetBuffer());
			WritePrittyPrint(ref reader, ref writer, 0);
			return writer.ToUtf8ByteArray();
		}

		public static byte[] PrettyPrintByteArray(string json)
		{
			JsonReader reader = new JsonReader(Encoding.UTF8.GetBytes(json));
			JsonWriter writer = new JsonWriter(MemoryPool.GetBuffer());
			WritePrittyPrint(ref reader, ref writer, 0);
			return writer.ToUtf8ByteArray();
		}

		private static void WritePrittyPrint(ref JsonReader reader, ref JsonWriter writer, int depth)
		{
			checked
			{
				switch (reader.GetCurrentJsonToken())
				{
				case JsonToken.BeginObject:
				{
					writer.WriteBeginObject();
					writer.WriteRaw(newLine);
					int count2 = 0;
					while (reader.ReadIsInObject(ref count2))
					{
						if (count2 != 1)
						{
							writer.WriteRaw(44);
							writer.WriteRaw(newLine);
						}
						writer.WriteRaw(indent[depth + 1]);
						writer.WritePropertyName(reader.ReadPropertyName());
						writer.WriteRaw(32);
						WritePrittyPrint(ref reader, ref writer, depth + 1);
					}
					writer.WriteRaw(newLine);
					writer.WriteRaw(indent[depth]);
					writer.WriteEndObject();
					break;
				}
				case JsonToken.BeginArray:
				{
					writer.WriteBeginArray();
					writer.WriteRaw(newLine);
					int count = 0;
					while (reader.ReadIsInArray(ref count))
					{
						if (count != 1)
						{
							writer.WriteRaw(44);
							writer.WriteRaw(newLine);
						}
						writer.WriteRaw(indent[depth + 1]);
						WritePrittyPrint(ref reader, ref writer, depth + 1);
					}
					writer.WriteRaw(newLine);
					writer.WriteRaw(indent[depth]);
					writer.WriteEndArray();
					break;
				}
				case JsonToken.Number:
				{
					double value3 = reader.ReadDouble();
					writer.WriteDouble(value3);
					break;
				}
				case JsonToken.String:
				{
					string value2 = reader.ReadString();
					writer.WriteString(value2);
					break;
				}
				case JsonToken.True:
				case JsonToken.False:
				{
					bool value = reader.ReadBoolean();
					writer.WriteBoolean(value);
					break;
				}
				case JsonToken.Null:
					reader.ReadIsNull();
					writer.WriteNull();
					break;
				case JsonToken.EndObject:
				case JsonToken.EndArray:
					break;
				}
			}
		}

		private static int FillFromStream(Stream input, ref byte[] buffer)
		{
			int num = 0;
			checked
			{
				int num2;
				while ((num2 = input.Read(buffer, num, buffer.Length - num)) > 0)
				{
					num += num2;
					if (num == buffer.Length)
					{
						BinaryUtil.FastResize(ref buffer, num * 2);
					}
				}
				return num;
			}
		}
	}
	public enum JsonToken : byte
	{
		None,
		BeginObject,
		EndObject,
		BeginArray,
		EndArray,
		Number,
		String,
		True,
		False,
		Null,
		ValueSeparator,
		NameSeparator
	}
	public struct JsonWriter
	{
		private static readonly byte[] emptyBytes = new byte[0];

		internal byte[] buffer;

		internal int offset;

		public int CurrentOffset => offset;

		public void AdvanceOffset(int offset)
		{
			checked
			{
				this.offset += offset;
			}
		}

		public static byte[] GetEncodedPropertyName(string propertyName)
		{
			JsonWriter jsonWriter = default(JsonWriter);
			jsonWriter.WritePropertyName(propertyName);
			return jsonWriter.ToUtf8ByteArray();
		}

		public static byte[] GetEncodedPropertyNameWithPrefixValueSeparator(string propertyName)
		{
			JsonWriter jsonWriter = default(JsonWriter);
			jsonWriter.WriteValueSeparator();
			jsonWriter.WritePropertyName(propertyName);
			return jsonWriter.ToUtf8ByteArray();
		}

		public static byte[] GetEncodedPropertyNameWithBeginObject(string propertyName)
		{
			JsonWriter jsonWriter = default(JsonWriter);
			jsonWriter.WriteBeginObject();
			jsonWriter.WritePropertyName(propertyName);
			return jsonWriter.ToUtf8ByteArray();
		}

		public static byte[] GetEncodedPropertyNameWithoutQuotation(string propertyName)
		{
			JsonWriter jsonWriter = default(JsonWriter);
			jsonWriter.WriteString(propertyName);
			ArraySegment<byte> arraySegment = jsonWriter.GetBuffer();
			checked
			{
				byte[] array = new byte[arraySegment.Count - 2];
				Buffer.BlockCopy(arraySegment.Array, arraySegment.Offset + 1, array, 0, array.Length);
				return array;
			}
		}

		public JsonWriter(byte[] initialBuffer)
		{
			buffer = initialBuffer;
			offset = 0;
		}

		public ArraySegment<byte> GetBuffer()
		{
			if (buffer == null)
			{
				return new ArraySegment<byte>(emptyBytes, 0, 0);
			}
			return new ArraySegment<byte>(buffer, 0, offset);
		}

		public byte[] ToUtf8ByteArray()
		{
			if (buffer == null)
			{
				return emptyBytes;
			}
			return BinaryUtil.FastCloneWithResize(buffer, offset);
		}

		public override string ToString()
		{
			if (buffer == null)
			{
				return null;
			}
			return Encoding.UTF8.GetString(buffer, 0, offset);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public void EnsureCapacity(int appendLength)
		{
			BinaryUtil.EnsureCapacity(ref buffer, offset, appendLength);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public void WriteRaw(byte rawValue)
		{
			BinaryUtil.EnsureCapacity(ref buffer, offset, 1);
			buffer[checked(offset++)] = rawValue;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public void WriteRaw(byte[] rawValue)
		{
			UnsafeMemory.WriteRaw(ref this, rawValue);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public void WriteRawUnsafe(byte rawValue)
		{
			buffer[checked(offset++)] = rawValue;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public void WriteBeginArray()
		{
			BinaryUtil.EnsureCapacity(ref buffer, offset, 1);
			buffer[checked(offset++)] = 91;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public void WriteEndArray()
		{
			BinaryUtil.EnsureCapacity(ref buffer, offset, 1);
			buffer[checked(offset++)] = 93;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public void WriteBeginObject()
		{
			BinaryUtil.EnsureCapacity(ref buffer, offset, 1);
			buffer[checked(offset++)] = 123;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public void WriteEndObject()
		{
			BinaryUtil.EnsureCapacity(ref buffer, offset, 1);
			buffer[checked(offset++)] = 125;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public void WriteValueSeparator()
		{
			BinaryUtil.EnsureCapacity(ref buffer, offset, 1);
			buffer[checked(offset++)] = 44;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public void WriteNameSeparator()
		{
			BinaryUtil.EnsureCapacity(ref buffer, offset, 1);
			buffer[checked(offset++)] = 58;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public void WritePropertyName(string propertyName)
		{
			WriteString(propertyName);
			WriteNameSeparator();
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public void WriteQuotation()
		{
			BinaryUtil.EnsureCapacity(ref buffer, offset, 1);
			buffer[checked(offset++)] = 34;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public void WriteNull()
		{
			BinaryUtil.EnsureCapacity(ref buffer, offset, 4);
			buffer[offset] = 110;
			checked
			{
				buffer[offset + 1] = 117;
				buffer[offset + 2] = 108;
				buffer[offset + 3] = 108;
				offset += 4;
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public void WriteBoolean(bool value)
		{
			checked
			{
				if (value)
				{
					BinaryUtil.EnsureCapacity(ref buffer, offset, 4);
					buffer[offset] = 116;
					buffer[offset + 1] = 114;
					buffer[offset + 2] = 117;
					buffer[offset + 3] = 101;
					offset += 4;
				}
				else
				{
					BinaryUtil.EnsureCapacity(ref buffer, offset, 5);
					buffer[offset] = 102;
					buffer[offset + 1] = 97;
					buffer[offset + 2] = 108;
					buffer[offset + 3] = 115;
					buffer[offset + 4] = 101;
					offset += 5;
				}
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public void WriteTrue()
		{
			BinaryUtil.EnsureCapacity(ref buffer, offset, 4);
			buffer[offset] = 116;
			checked
			{
				buffer[offset + 1] = 114;
				buffer[offset + 2] = 117;
				buffer[offset + 3] = 101;
				offset += 4;
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public void WriteFalse()
		{
			BinaryUtil.EnsureCapacity(ref buffer, offset, 5);
			buffer[offset] = 102;
			checked
			{
				buffer[offset + 1] = 97;
				buffer[offset + 2] = 108;
				buffer[offset + 3] = 115;
				buffer[offset + 4] = 101;
				offset += 5;
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public void WriteSingle(float value)
		{
			checked
			{
				offset += DoubleToStringConverter.GetBytes(ref buffer, offset, value);
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public void WriteDouble(double value)
		{
			checked
			{
				offset += DoubleToStringConverter.GetBytes(ref buffer, offset, value);
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public void WriteByte(byte value)
		{
			WriteUInt64(value);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public void WriteUInt16(ushort value)
		{
			WriteUInt64(value);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public void WriteUInt32(uint value)
		{
			WriteUInt64(value);
		}

		public void WriteUInt64(ulong value)
		{
			checked
			{
				offset += NumberConverter.WriteUInt64(ref buffer, offset, value);
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public void WriteSByte(sbyte value)
		{
			WriteInt64(value);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public void WriteInt16(short value)
		{
			WriteInt64(value);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public void WriteInt32(int value)
		{
			WriteInt64(value);
		}

		public void WriteInt64(long value)
		{
			checked
			{
				offset += NumberConverter.WriteInt64(ref buffer, offset, value);
			}
		}

		public void WriteString(string value)
		{
			if (value == null)
			{
				WriteNull();
				return;
			}
			int num = offset;
			checked
			{
				int num2 = StringEncoding.UTF8.GetMaxByteCount(value.Length) + 2;
				BinaryUtil.EnsureCapacity(ref buffer, num, num2);
				int num3 = 0;
				_ = value.Length;
				buffer[offset++] = 34;
				for (int i = 0; i < value.Length; i++)
				{
					byte b = 0;
					switch (value[i])
					{
					case '"':
						b = 34;
						break;
					case '\\':
						b = 92;
						break;
					case '\b':
						b = 98;
						break;
					case '\f':
						b = 102;
						break;
					case '\n':
						b = 110;
						break;
					case '\r':
						b = 114;
						break;
					case '\t':
						b = 116;
						break;
					default:
						continue;
					}
					num2 += 2;
					BinaryUtil.EnsureCapacity(ref buffer, num, num2);
					offset += StringEncoding.UTF8.GetBytes(value, num3, i - num3, buffer, offset);
					num3 = i + 1;
					buffer[offset++] = 92;
					buffer[offset++] = b;
				}
				if (num3 != value.Length)
				{
					offset += StringEncoding.UTF8.GetBytes(value, num3, value.Length - num3, buffer, offset);
				}
				buffer[offset++] = 34;
			}
		}
	}
}
namespace Utf8Json.Resolvers
{
	public sealed class AttributeFormatterResolver : IJsonFormatterResolver
	{
		private static class FormatterCache<T>
		{
			public static readonly IJsonFormatter<T> formatter;

			static FormatterCache()
			{
				JsonFormatterAttribute customAttribute = typeof(T).GetTypeInfo().GetCustomAttribute<JsonFormatterAttribute>();
				if (customAttribute == null)
				{
					return;
				}
				try
				{
					if (customAttribute.FormatterType.IsGenericType && !customAttribute.FormatterType.GetTypeInfo().IsConstructedGenericType())
					{
						formatter = (IJsonFormatter<T>)Activator.CreateInstance(customAttribute.FormatterType.MakeGenericType(typeof(T)), customAttribute.Arguments);
					}
					else
					{
						formatter = (IJsonFormatter<T>)Activator.CreateInstance(customAttribute.FormatterType, customAttribute.Arguments);
					}
				}
				catch (Exception innerException)
				{
					throw new InvalidOperationException("Can not create formatter from JsonFormatterAttribute, check the target formatter is public and has constructor with right argument. FormatterType:" + customAttribute.FormatterType.Name, innerException);
				}
			}
		}

		public static IJsonFormatterResolver Instance = new AttributeFormatterResolver();

		private AttributeFormatterResolver()
		{
		}

		public IJsonFormatter<T> GetFormatter<T>()
		{
			return FormatterCache<T>.formatter;
		}
	}
	public sealed class BuiltinResolver : IJsonFormatterResolver
	{
		private static class FormatterCache<T>
		{
			public static readonly IJsonFormatter<T> formatter;

			static FormatterCache()
			{
				formatter = (IJsonFormatter<T>)BuiltinResolverGetFormatterHelper.GetFormatter(typeof(T));
			}
		}

		internal static class BuiltinResolverGetFormatterHelper
		{
			private static readonly Dictionary<Type, object> formatterMap = new Dictionary<Type, object>
			{
				{
					typeof(short),
					Int16Formatter.Default
				},
				{
					typeof(int),
					Int32Formatter.Default
				},
				{
					typeof(long),
					Int64Formatter.Default
				},
				{
					typeof(ushort),
					UInt16Formatter.Default
				},
				{
					typeof(uint),
					UInt32Formatter.Default
				},
				{
					typeof(ulong),
					UInt64Formatter.Default
				},
				{
					typeof(float),
					SingleFormatter.Default
				},
				{
					typeof(double),
					DoubleFormatter.Default
				},
				{
					typeof(bool),
					BooleanFormatter.Default
				},
				{
					typeof(byte),
					ByteFormatter.Default
				},
				{
					typeof(sbyte),
					SByteFormatter.Default
				},
				{
					typeof(short?),
					NullableInt16Formatter.Default
				},
				{
					typeof(int?),
					NullableInt32Formatter.Default
				},
				{
					typeof(long?),
					NullableInt64Formatter.Default
				},
				{
					typeof(ushort?),
					NullableUInt16Formatter.Default
				},
				{
					typeof(uint?),
					NullableUInt32Formatter.Default
				},
				{
					typeof(ulong?),
					NullableUInt64Formatter.Default
				},
				{
					typeof(float?),
					NullableSingleFormatter.Default
				},
				{
					typeof(double?),
					NullableDoubleFormatter.Default
				},
				{
					typeof(bool?),
					NullableBooleanFormatter.Default
				},
				{
					typeof(byte?),
					NullableByteFormatter.Default
				},
				{
					typeof(sbyte?),
					NullableSByteFormatter.Default
				},
				{
					typeof(DateTime),
					ISO8601DateTimeFormatter.Default
				},
				{
					typeof(TimeSpan),
					ISO8601TimeSpanFormatter.Default
				},
				{
					typeof(DateTimeOffset),
					ISO8601DateTimeOffsetFormatter.Default
				},
				{
					typeof(DateTime?),
					new StaticNullableFormatter<DateTime>(ISO8601DateTimeFormatter.Default)
				},
				{
					typeof(TimeSpan?),
					new StaticNullableFormatter<TimeSpan>(ISO8601TimeSpanFormatter.Default)
				},
				{
					typeof(DateTimeOffset?),
					new StaticNullableFormatter<DateTimeOffset>(ISO8601DateTimeOffsetFormatter.Default)
				},
				{
					typeof(string),
					NullableStringFormatter.Default
				},
				{
					typeof(char),
					CharFormatter.Default
				},
				{
					typeof(char?),
					NullableCharFormatter.Default
				},
				{
					typeof(decimal),
					DecimalFormatter.Default
				},
				{
					typeof(decimal?),
					new StaticNullableFormatter<decimal>(DecimalFormatter.Default)
				},
				{
					typeof(Guid),
					GuidFormatter.Default
				},
				{
					typeof(Guid?),
					new StaticNullableFormatter<Guid>(GuidFormatter.Default)
				},
				{
					typeof(Uri),
					UriFormatter.Default
				},
				{
					typeof(Version),
					VersionFormatter.Default
				},
				{
					typeof(System.Text.StringBuilder),
					StringBuilderFormatter.Default
				},
				{
					typeof(BitArray),
					BitArrayFormatter.Default
				},
				{
					typeof(Type),
					TypeFormatter.Default
				},
				{
					typeof(byte[]),
					ByteArrayFormatter.Default
				},
				{
					typeof(short[]),
					Int16ArrayFormatter.Default
				},
				{
					typeof(int[]),
					Int32ArrayFormatter.Default
				},
				{
					typeof(long[]),
					Int64ArrayFormatter.Default
				},
				{
					typeof(ushort[]),
					UInt16ArrayFormatter.Default
				},
				{
					typeof(uint[]),
					UInt32ArrayFormatter.Default
				},
				{
					typeof(ulong[]),
					UInt64ArrayFormatter.Default
				},
				{
					typeof(float[]),
					SingleArrayFormatter.Default
				},
				{
					typeof(double[]),
					DoubleArrayFormatter.Default
				},
				{
					typeof(bool[]),
					BooleanArrayFormatter.Default
				},
				{
					typeof(sbyte[]),
					SByteArrayFormatter.Default
				},
				{
					typeof(char[]),
					CharArrayFormatter.Default
				},
				{
					typeof(string[]),
					NullableStringArrayFormatter.Default
				},
				{
					typeof(List<short>),
					new ListFormatter<short>()
				},
				{
					typeof(List<int>),
					new ListFormatter<int>()
				},
				{
					typeof(List<long>),
					new ListFormatter<long>()
				},
				{
					typeof(List<ushort>),
					new ListFormatter<ushort>()
				},
				{
					typeof(List<uint>),
					new ListFormatter<uint>()
				},
				{
					typeof(List<ulong>),
					new ListFormatter<ulong>()
				},
				{
					typeof(List<float>),
					new ListFormatter<float>()
				},
				{
					typeof(List<double>),
					new ListFormatter<double>()
				},
				{
					typeof(List<bool>),
					new ListFormatter<bool>()
				},
				{
					typeof(List<byte>),
					new ListFormatter<byte>()
				},
				{
					typeof(List<sbyte>),
					new ListFormatter<sbyte>()
				},
				{
					typeof(List<DateTime>),
					new ListFormatter<DateTime>()
				},
				{
					typeof(List<char>),
					new ListFormatter<char>()
				},
				{
					typeof(List<string>),
					new ListFormatter<string>()
				},
				{
					typeof(ArraySegment<byte>),
					ByteArraySegmentFormatter.Default
				},
				{
					typeof(ArraySegment<byte>?),
					new StaticNullableFormatter<ArraySegment<byte>>(ByteArraySegmentFormatter.Default)
				},
				{
					typeof(BigInteger),
					BigIntegerFormatter.Default
				},
				{
					typeof(BigInteger?),
					new StaticNullableFormatter<BigInteger>(BigIntegerFormatter.Default)
				},
				{
					typeof(Complex),
					ComplexFormatter.Default
				},
				{
					typeof(Complex?),
					new StaticNullableFormatter<Complex>(ComplexFormatter.Default)
				},
				{
					typeof(ExpandoObject),
					ExpandoObjectFormatter.Default
				},
				{
					typeof(Task),
					TaskUnitFormatter.Default
				}
			};

			internal static object GetFormatter(Type t)
			{
				if (formatterMap.TryGetValue(t, out var value))
				{
					return value;
				}
				return null;
			}
		}

		public static readonly IJsonFormatterResolver Instance = new BuiltinResolver();

		private BuiltinResolver()
		{
		}

		public IJsonFormatter<T> GetFormatter<T>()
		{
			return FormatterCache<T>.formatter;
		}
	}
	public sealed class CompositeResolver : IJsonFormatterResolver
	{
		private static class FormatterCache<T>
		{
			public static readonly IJsonFormatter<T> formatter;

			static FormatterCache()
			{
				isFreezed = true;
				IJsonFormatter[] formatters = CompositeResolver.formatters;
				foreach (IJsonFormatter jsonFormatter in formatters)
				{
					foreach (Type implementedInterface in jsonFormatter.GetType().GetTypeInfo().ImplementedInterfaces)
					{
						TypeInfo typeInfo = implementedInterface.GetTypeInfo();
						if (typeInfo.IsGenericType && typeInfo.GenericTypeArguments[0] == typeof(T))
						{
							formatter = (IJsonFormatter<T>)jsonFormatter;
							return;
						}
					}
				}
				IJsonFormatterResolver[] resolvers = CompositeResolver.resolvers;
				for (int i = 0; i < resolvers.Length; i++)
				{
					IJsonFormatter<T> jsonFormatter2 = resolvers[i].GetFormatter<T>();
					if (jsonFormatter2 != null)
					{
						formatter = jsonFormatter2;
						break;
					}
				}
			}
		}

		public static readonly CompositeResolver Instance = new CompositeResolver();

		private static bool isFreezed = false;

		private static IJsonFormatter[] formatters = new IJsonFormatter[0];

		private static IJsonFormatterResolver[] resolvers = new IJsonFormatterResolver[0];

		private CompositeResolver()
		{
		}

		public static void Register(params IJsonFormatterResolver[] resolvers)
		{
			if (isFreezed)
			{
				throw new InvalidOperationException("Register must call on startup(before use GetFormatter<T>).");
			}
			CompositeResolver.resolvers = resolvers;
		}

		public static void Register(params IJsonFormatter[] formatters)
		{
			if (isFreezed)
			{
				throw new InvalidOperationException("Register must call on startup(before use GetFormatter<T>).");
			}
			CompositeResolver.formatters = formatters;
		}

		public static void Register(IJsonFormatter[] formatters, IJsonFormatterResolver[] resolvers)
		{
			if (isFreezed)
			{
				throw new InvalidOperationException("Register must call on startup(before use GetFormatter<T>).");
			}
			CompositeResolver.resolvers = resolvers;
			CompositeResolver.formatters = formatters;
		}

		public static void RegisterAndSetAsDefault(params IJsonFormatterResolver[] resolvers)
		{
			Register(resolvers);
			JsonSerializer.SetDefaultResolver(Instance);
		}

		public static void RegisterAndSetAsDefault(params IJsonFormatter[] formatters)
		{
			Register(formatters);
			JsonSerializer.SetDefaultResolver(Instance);
		}

		public static void RegisterAndSetAsDefault(IJsonFormatter[] formatters, IJsonFormatterResolver[] resolvers)
		{
			Register(formatters);
			Register(resolvers);
			JsonSerializer.SetDefaultResolver(Instance);
		}

		public static IJsonFormatterResolver Create(params IJsonFormatter[] formatters)
		{
			return Create(formatters, new IJsonFormatterResolver[0]);
		}

		public static IJsonFormatterResolver Create(params IJsonFormatterResolver[] resolvers)
		{
			return Create(new IJsonFormatter[0], resolvers);
		}

		public static IJsonFormatterResolver Create(IJsonFormatter[] formatters, IJsonFormatterResolver[] resolvers)
		{
			return DynamicCompositeResolver.Create(formatters, resolvers);
		}

		public IJsonFormatter<T> GetFormatter<T>()
		{
			return FormatterCache<T>.formatter;
		}
	}
	public abstract class DynamicCompositeResolver : IJsonFormatterResolver
	{
		private const string ModuleName = "Utf8Json.Resolvers.DynamicCompositeResolver";

		private static readonly DynamicAssembly assembly;

		public readonly IJsonFormatter[] formatters;

		public readonly IJsonFormatterResolver[] resolvers;

		static DynamicCompositeResolver()
		{
			assembly = new DynamicAssembly("Utf8Json.Resolvers.DynamicCompositeResolver");
		}

		public static IJsonFormatterResolver Create(IJsonFormatter[] formatters, IJsonFormatterResolver[] resolvers)
		{
			string text = Guid.NewGuid().ToString().Replace("-", "");
			TypeBuilder typeBuilder = assembly.DefineType("DynamicCompositeResolver_" + text, TypeAttributes.Public | TypeAttributes.Sealed, typeof(DynamicCompositeResolver));
			TypeBuilder typeBuilder2 = assembly.DefineType("DynamicCompositeResolverCache_" + text, TypeAttributes.Public | TypeAttributes.Sealed, null);
			GenericTypeParameterBuilder genericTypeParameterBuilder = typeBuilder2.DefineGenericParameters("T")[0];
			FieldBuilder fieldInfo = typeBuilder.DefineField("instance", typeBuilder, FieldAttributes.Public | FieldAttributes.Static);
			FieldBuilder field = typeBuilder2.DefineField("formatter", typeof(IJsonFormatter<>).MakeGenericType(genericTypeParameterBuilder), FieldAttributes.Public | FieldAttributes.Static);
			ILGenerator iLGenerator = typeBuilder2.DefineConstructor(MethodAttributes.Static, CallingConventions.Standard, Type.EmptyTypes).GetILGenerator();
			iLGenerator.EmitLdsfld(fieldInfo);
			iLGenerator.EmitCall(typeof(DynamicCompositeResolver).GetMethod("GetFormatterLoop").MakeGenericMethod(genericTypeParameterBuilder));
			iLGenerator.Emit(OpCodes.Stsfld, field);
			iLGenerator.Emit(OpCodes.Ret);
			Type type = typeBuilder2.CreateTypeInfo().AsType();
			ILGenerator iLGenerator2 = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, new Type[2]
			{
				typeof(IJsonFormatter[]),
				typeof(IJsonFormatterResolver[])
			}).GetILGenerator();
			iLGenerator2.EmitLdarg(0);
			iLGenerator2.EmitLdarg(1);
			iLGenerator2.EmitLdarg(2);
			iLGenerator2.Emit(OpCodes.Call, typeof(DynamicCompositeResolver).GetConstructors()[0]);
			iLGenerator2.Emit(OpCodes.Ret);
			MethodBuilder methodBuilder = typeBuilder.DefineMethod("GetFormatter", MethodAttributes.Public | MethodAttributes.Virtual);
			GenericTypeParameterBuilder genericTypeParameterBuilder2 = methodBuilder.DefineGenericParameters("T")[0];
			methodBuilder.SetReturnType(typeof(IJsonFormatter<>).MakeGenericType(genericTypeParameterBuilder2));
			ILGenerator iLGenerator3 = methodBuilder.GetILGenerator();
			FieldInfo field2 = TypeBuilder.GetField(type.MakeGenericType(genericTypeParameterBuilder2), type.GetField("formatter", BindingFlags.Static | BindingFlags.Public | BindingFlags.GetField));
			iLGenerator3.EmitLdsfld(field2);
			iLGenerator3.Emit(OpCodes.Ret);
			object obj = Activator.CreateInstance(typeBuilder.CreateTypeInfo().AsType(), new object[2] { formatters, resolvers });
			obj.GetType().GetField("instance", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).SetValue(null, obj);
			return (IJsonFormatterResolver)obj;
		}

		public DynamicCompositeResolver(IJsonFormatter[] formatters, IJsonFormatterResolver[] resolvers)
		{
			this.formatters = formatters;
			this.resolvers = resolvers;
		}

		public IJsonFormatter<T> GetFormatterLoop<T>()
		{
			IJsonFormatter[] array = formatters;
			foreach (IJsonFormatter jsonFormatter in array)
			{
				foreach (Type implementedInterface in jsonFormatter.GetType().GetTypeInfo().ImplementedInterfaces)
				{
					TypeInfo typeInfo = implementedInterface.GetTypeInfo();
					if (typeInfo.IsGenericType && typeInfo.GenericTypeArguments[0] == typeof(T))
					{
						return (IJsonFormatter<T>)jsonFormatter;
					}
				}
			}
			IJsonFormatterResolver[] array2 = resolvers;
			for (int i = 0; i < array2.Length; i++)
			{
				IJsonFormatter<T> formatter = array2[i].GetFormatter<T>();
				if (formatter != null)
				{
					return formatter;
				}
			}
			return null;
		}

		public abstract IJsonFormatter<T> GetFormatter<T>();
	}
	public sealed class DynamicGenericResolver : IJsonFormatterResolver
	{
		private static class FormatterCache<T>
		{
			public static readonly IJsonFormatter<T> formatter;

			static FormatterCache()
			{
				formatter = (IJsonFormatter<T>)DynamicGenericResolverGetFormatterHelper.GetFormatter(typeof(T));
			}
		}

		public static readonly IJsonFormatterResolver Instance = new DynamicGenericResolver();

		private DynamicGenericResolver()
		{
		}

		public IJsonFormatter<T> GetFormatter<T>()
		{
			return FormatterCache<T>.formatter;
		}
	}
	public static class DynamicObjectResolver
	{
		public static readonly IJsonFormatterResolver Default = DynamicObjectResolverAllowPrivateFalseExcludeNullFalseNameMutateOriginal.Instance;

		public static readonly IJsonFormatterResolver CamelCase = DynamicObjectResolverAllowPrivateFalseExcludeNullFalseNameMutateCamelCase.Instance;

		public static readonly IJsonFormatterResolver SnakeCase = DynamicObjectResolverAllowPrivateFalseExcludeNullFalseNameMutateSnakeCase.Instance;

		public static readonly IJsonFormatterResolver ExcludeNull = DynamicObjectResolverAllowPrivateFalseExcludeNullTrueNameMutateOriginal.Instance;

		public static readonly IJsonFormatterResolver ExcludeNullCamelCase = DynamicObjectResolverAllowPrivateFalseExcludeNullTrueNameMutateCamelCase.Instance;

		public static readonly IJsonFormatterResolver ExcludeNullSnakeCase = DynamicObjectResolverAllowPrivateFalseExcludeNullTrueNameMutateSnakeCase.Instance;

		public static readonly IJsonFormatterResolver AllowPrivate = DynamicObjectResolverAllowPrivateTrueExcludeNullFalseNameMutateOriginal.Instance;

		public static readonly IJsonFormatterResolver AllowPrivateCamelCase = DynamicObjectResolverAllowPrivateTrueExcludeNullFalseNameMutateCamelCase.Instance;

		public static readonly IJsonFormatterResolver AllowPrivateSnakeCase = DynamicObjectResolverAllowPrivateTrueExcludeNullFalseNameMutateSnakeCase.Instance;

		public static readonly IJsonFormatterResolver AllowPrivateExcludeNull = DynamicObjectResolverAllowPrivateTrueExcludeNullTrueNameMutateOriginal.Instance;

		public static readonly IJsonFormatterResolver AllowPrivateExcludeNullCamelCase = DynamicObjectResolverAllowPrivateTrueExcludeNullTrueNameMutateCamelCase.Instance;

		public static readonly IJsonFormatterResolver AllowPrivateExcludeNullSnakeCase = DynamicObjectResolverAllowPrivateTrueExcludeNullTrueNameMutateSnakeCase.Instance;
	}
	public static class EnumResolver
	{
		public static readonly IJsonFormatterResolver Default = EnumDefaultResolver.Instance;

		public static readonly IJsonFormatterResolver UnderlyingValue = EnumUnderlyingValueResolver.Instance;
	}
	public static class StandardResolver
	{
		public static readonly IJsonFormatterResolver Default = DefaultStandardResolver.Instance;

		public static readonly IJsonFormatterResolver CamelCase = CamelCaseStandardResolver.Instance;

		public static readonly IJsonFormatterResolver SnakeCase = SnakeCaseStandardResolver.Instance;

		public static readonly IJsonFormatterResolver ExcludeNull = ExcludeNullStandardResolver.Instance;

		public static readonly IJsonFormatterResolver ExcludeNullCamelCase = ExcludeNullCamelCaseStandardResolver.Instance;

		public static readonly IJsonFormatterResolver ExcludeNullSnakeCase = ExcludeNullSnakeCaseStandardResolver.Instance;

		public static readonly IJsonFormatterResolver AllowPrivate = AllowPrivateStandardResolver.Instance;

		public static readonly IJsonFormatterResolver AllowPrivateCamelCase = AllowPrivateCamelCaseStandardResolver.Instance;

		public static readonly IJsonFormatterResolver AllowPrivateSnakeCase = AllowPrivateSnakeCaseStandardResolver.Instance;

		public static readonly IJsonFormatterResolver AllowPrivateExcludeNull = AllowPrivateExcludeNullStandardResolver.Instance;

		public static readonly IJsonFormatterResolver AllowPrivateExcludeNullCamelCase = AllowPrivateExcludeNullCamelCaseStandardResolver.Instance;

		public static readonly IJsonFormatterResolver AllowPrivateExcludeNullSnakeCase = AllowPrivateExcludeNullSnakeCaseStandardResolver.Instance;
	}
}
namespace Utf8Json.Resolvers.Internal
{
	internal static class DynamicGenericResolverGetFormatterHelper
	{
		private static readonly Dictionary<Type, Type> formatterMap = new Dictionary<Type, Type>
		{
			{
				typeof(List<>),
				typeof(ListFormatter<>)
			},
			{
				typeof(LinkedList<>),
				typeof(LinkedListFormatter<>)
			},
			{
				typeof(Queue<>),
				typeof(QeueueFormatter<>)
			},
			{
				typeof(Stack<>),
				typeof(StackFormatter<>)
			},
			{
				typeof(HashSet<>),
				typeof(HashSetFormatter<>)
			},
			{
				typeof(ReadOnlyCollection<>),
				typeof(ReadOnlyCollectionFormatter<>)
			},
			{
				typeof(IList<>),
				typeof(InterfaceListFormatter<>)
			},
			{
				typeof(ICollection<>),
				typeof(InterfaceCollectionFormatter<>)
			},
			{
				typeof(IEnumerable<>),
				typeof(InterfaceEnumerableFormatter<>)
			},
			{
				typeof(Dictionary<, >),
				typeof(DictionaryFormatter<, >)
			},
			{
				typeof(IDictionary<, >),
				typeof(InterfaceDictionaryFormatter<, >)
			},
			{
				typeof(SortedDictionary<, >),
				typeof(SortedDictionaryFormatter<, >)
			},
			{
				typeof(SortedList<, >),
				typeof(SortedListFormatter<, >)
			},
			{
				typeof(ILookup<, >),
				typeof(InterfaceLookupFormatter<, >)
			},
			{
				typeof(IGrouping<, >),
				typeof(InterfaceGroupingFormatter<, >)
			},
			{
				typeof(ObservableCollection<>),
				typeof(ObservableCollectionFormatter<>)
			},
			{
				typeof(ReadOnlyObservableCollection<>),
				typeof(ReadOnlyObservableCollectionFormatter<>)
			},
			{
				typeof(IReadOnlyList<>),
				typeof(InterfaceReadOnlyListFormatter<>)
			},
			{
				typeof(IReadOnlyCollection<>),
				typeof(InterfaceReadOnlyCollectionFormatter<>)
			},
			{
				typeof(ISet<>),
				typeof(InterfaceSetFormatter<>)
			},
			{
				typeof(ConcurrentBag<>),
				typeof(ConcurrentBagFormatter<>)
			},
			{
				typeof(ConcurrentQueue<>),
				typeof(ConcurrentQueueFormatter<>)
			},
			{
				typeof(ConcurrentStack<>),
				typeof(ConcurrentStackFormatter<>)
			},
			{
				typeof(ReadOnlyDictionary<, >),
				typeof(ReadOnlyDictionaryFormatter<, >)
			},
			{
				typeof(IReadOnlyDictionary<, >),
				typeof(InterfaceReadOnlyDictionaryFormatter<, >)
			},
			{
				typeof(ConcurrentDictionary<, >),
				typeof(ConcurrentDictionaryFormatter<, >)
			},
			{
				typeof(Lazy<>),
				typeof(LazyFormatter<>)
			},
			{
				typeof(Task<>),
				typeof(TaskValueFormatter<>)
			}
		};

		internal static object GetFormatter(Type t)
		{
			TypeInfo typeInfo = t.GetTypeInfo();
			if (t.IsArray)
			{
				switch (t.GetArrayRank())
				{
				case 1:
					if (t.GetElementType() == typeof(byte))
					{
						return ByteArrayFormatter.Default;
					}
					return Activator.CreateInstance(typeof(ArrayFormatter<>).MakeGenericType(t.GetElementType()));
				case 2:
					return Activator.CreateInstance(typeof(TwoDimentionalArrayFormatter<>).MakeGenericType(t.GetElementType()));
				case 3:
					return Activator.CreateInstance(typeof(ThreeDimentionalArrayFormatter<>).MakeGenericType(t.GetElementType()));
				case 4:
					return Activator.CreateInstance(typeof(FourDimentionalArrayFormatter<>).MakeGenericType(t.GetElementType()));
				default:
					return null;
				}
			}
			if (typeInfo.IsGenericType)
			{
				Type genericTypeDefinition = typeInfo.GetGenericTypeDefinition();
				bool flag = genericTypeDefinition.GetTypeInfo().IsNullable();
				Type type = (flag ? typeInfo.GenericTypeArguments[0] : null);
				if (genericTypeDefinition == typeof(KeyValuePair<, >))
				{
					return CreateInstance(typeof(KeyValuePairFormatter<, >), typeInfo.GenericTypeArguments);
				}
				if (flag && type.GetTypeInfo().IsConstructedGenericType() && type.GetGenericTypeDefinition() == typeof(KeyValuePair<, >))
				{
					return CreateInstance(typeof(NullableFormatter<>), new Type[1] { type });
				}
				if (genericTypeDefinition == typeof(ValueTask<>))
				{
					return CreateInstance(typeof(ValueTaskFormatter<>), typeInfo.GenericTypeArguments);
				}
				if (flag && type.IsConstructedGenericType && type.GetGenericTypeDefinition() == typeof(ValueTask<>))
				{
					return CreateInstance(typeof(NullableFormatter<>), new Type[1] { type });
				}
				if (typeInfo.FullName.StartsWith("System.Tuple"))
				{
					Type genericType = null;
					switch (typeInfo.GenericTypeArguments.Length)
					{
					case 1:
						genericType = typeof(TupleFormatter<>);
						break;
					case 2:
						genericType = typeof(TupleFormatter<, >);
						break;
					case 3:
						genericType = typeof(TupleFormatter<, , >);
						break;
					case 4:
						genericType = typeof(TupleFormatter<, , , >);
						break;
					case 5:
						genericType = typeof(TupleFormatter<, , , , >);
						break;
					case 6:
						genericType = typeof(TupleFormatter<, , , , , >);
						break;
					case 7:
						genericType = typeof(TupleFormatter<, , , , , , >);
						break;
					case 8:
						genericType = typeof(TupleFormatter<, , , , , , , >);
						break;
					}
					return CreateInstance(genericType, typeInfo.GenericTypeArguments);
				}
				if (typeInfo.FullName.StartsWith("System.ValueTuple"))
				{
					Type genericType2 = null;
					switch (typeInfo.GenericTypeArguments.Length)
					{
					case 1:
						genericType2 = typeof(ValueTupleFormatter<>);
						break;
					case 2:
						genericType2 = typeof(ValueTupleFormatter<, >);
						break;
					case 3:
						genericType2 = typeof(ValueTupleFormatter<, , >);
						break;
					case 4:
						genericType2 = typeof(ValueTupleFormatter<, , , >);
						break;
					case 5:
						genericType2 = typeof(ValueTupleFormatter<, , , , >);
						break;
					case 6:
						genericType2 = typeof(ValueTupleFormatter<, , , , , >);
						break;
					case 7:
						genericType2 = typeof(ValueTupleFormatter<, , , , , , >);
						break;
					case 8:
						genericType2 = typeof(ValueTupleFormatter<, , , , , , , >);
						break;
					}
					return CreateInstance(genericType2, typeInfo.GenericTypeArguments);
				}
				if (genericTypeDefinition == typeof(ArraySegment<>))
				{
					if (typeInfo.GenericTypeArguments[0] == typeof(byte))
					{
						return ByteArraySegmentFormatter.Default;
					}
					return CreateInstance(typeof(ArraySegmentFormatter<>), typeInfo.GenericTypeArguments);
				}
				if (flag && type.GetTypeInfo().IsConstructedGenericType() && type.GetGenericTypeDefinition() == typeof(ArraySegment<>))
				{
					if (type == typeof(ArraySegment<byte>))
					{
						return new StaticNullableFormatter<ArraySegment<byte>>(ByteArraySegmentFormatter.Default);
					}
					return CreateInstance(typeof(NullableFormatter<>), new Type[1] { type });
				}
				if (formatterMap.TryGetValue(genericTypeDefinition, out var value))
				{
					return CreateInstance(value, typeInfo.GenericTypeArguments);
				}
				if (typeInfo.GenericTypeArguments.Length == 1 && typeInfo.ImplementedInterfaces.Any((Type x) => x.GetTypeInfo().IsConstructedGenericType() && x.GetGenericTypeDefinition() == typeof(ICollection<>)) && typeInfo.DeclaredConstructors.Any((ConstructorInfo x) => x.GetParameters().Length == 0))
				{
					Type type2 = typeInfo.GenericTypeArguments[0];
					return CreateInstance(typeof(GenericCollectionFormatter<, >), new Type[2] { type2, t });
				}
				if (typeInfo.GenericTypeArguments.Length == 2 && typeInfo.ImplementedInterfaces.Any((Type x) => x.GetTypeInfo().IsConstructedGenericType() && x.GetGenericTypeDefinition() == typeof(IDictionary<, >)) && typeInfo.DeclaredConstructors.Any((ConstructorInfo x) => x.GetParameters().Length == 0))
				{
					Type type3 = typeInfo.GenericTypeArguments[0];
					Type type4 = typeInfo.GenericTypeArguments[1];
					return CreateInstance(typeof(GenericDictionaryFormatter<, , >), new Type[3] { type3, type4, t });
				}
			}
			else
			{
				if (t == typeof(IEnumerable))
				{
					return NonGenericInterfaceEnumerableFormatter.Default;
				}
				if (t == typeof(ICollection))
				{
					return NonGenericInterfaceCollectionFormatter.Default;
				}
				if (t == typeof(IList))
				{
					return NonGenericInterfaceListFormatter.Default;
				}
				if (t == typeof(IDictionary))
				{
					return NonGenericInterfaceDictionaryFormatter.Default;
				}
				if (typeof(IList).GetTypeInfo().IsAssignableFrom(typeInfo) && typeInfo.DeclaredConstructors.Any((ConstructorInfo x) => x.GetParameters().Length == 0))
				{
					return Activator.CreateInstance(typeof(NonGenericListFormatter<>).MakeGenericType(t));
				}
				if (typeof(IDictionary).GetTypeInfo().IsAssignableFrom(typeInfo) && typeInfo.DeclaredConstructors.Any((ConstructorInfo x) => x.GetParameters().Length == 0))
				{
					return Activator.CreateInstance(typeof(NonGenericDictionaryFormatter<>).MakeGenericType(t));
				}
			}
			return null;
		}

		private static object CreateInstance(Type genericType, Type[] genericTypeArguments, params object[] arguments)
		{
			return Activator.CreateInstance(genericType.MakeGenericType(genericTypeArguments), arguments);
		}
	}
	internal sealed class DynamicObjectResolverAllowPrivateFalseExcludeNullFalseNameMutateOriginal : IJsonFormatterResolver
	{
		private static class FormatterCache<T>
		{
			public static readonly IJsonFormatter<T> formatter;

			static FormatterCache()
			{
				formatter = (IJsonFormatter<T>)DynamicObjectTypeBuilder.BuildFormatterToAssembly<T>(assembly, Instance, nameMutator, excludeNull);
			}
		}

		public static readonly IJsonFormatterResolver Instance;

		private static readonly Func<string, string> nameMutator;

		private static readonly bool excludeNull;

		private const string ModuleName = "Utf8Json.Resolvers.DynamicObjectResolverAllowPrivateFalseExcludeNullFalseNameMutateOriginal";

		private static readonly DynamicAssembly assembly;

		static DynamicObjectResolverAllowPrivateFalseExcludeNullFalseNameMutateOriginal()
		{
			Instance = new DynamicObjectResolverAllowPrivateFalseExcludeNullFalseNameMutateOriginal();
			nameMutator = StringMutator.Original;
			excludeNull = false;
			assembly = new DynamicAssembly("Utf8Json.Resolvers.DynamicObjectResolverAllowPrivateFalseExcludeNullFalseNameMutateOriginal");
		}

		private DynamicObjectResolverAllowPrivateFalseExcludeNullFalseNameMutateOriginal()
		{
		}

		public IJsonFormatter<T> GetFormatter<T>()
		{
			return FormatterCache<T>.formatter;
		}
	}
	internal sealed class DynamicObjectResolverAllowPrivateFalseExcludeNullFalseNameMutateCamelCase : IJsonFormatterResolver
	{
		private static class FormatterCache<T>
		{
			public static readonly IJsonFormatter<T> formatter;

			static FormatterCache()
			{
				formatter = (IJsonFormatter<T>)DynamicObjectTypeBuilder.BuildFormatterToAssembly<T>(assembly, Instance, nameMutator, excludeNull);
			}
		}

		public static readonly IJsonFormatterResolver Instance;

		private static readonly Func<string, string> nameMutator;

		private static readonly bool excludeNull;

		private const string ModuleName = "Utf8Json.Resolvers.DynamicObjectResolverAllowPrivateFalseExcludeNullFalseNameMutateCamelCase";

		private static readonly DynamicAssembly assembly;

		static DynamicObjectResolverAllowPrivateFalseExcludeNullFalseNameMutateCamelCase()
		{
			Instance = new DynamicObjectResolverAllowPrivateFalseExcludeNullFalseNameMutateCamelCase();
			nameMutator = StringMutator.ToCamelCase;
			excludeNull = false;
			assembly = new DynamicAssembly("Utf8Json.Resolvers.DynamicObjectResolverAllowPrivateFalseExcludeNullFalseNameMutateCamelCase");
		}

		private DynamicObjectResolverAllowPrivateFalseExcludeNullFalseNameMutateCamelCase()
		{
		}

		public IJsonFormatter<T> GetFormatter<T>()
		{
			return FormatterCache<T>.formatter;
		}
	}
	internal sealed class DynamicObjectResolverAllowPrivateFalseExcludeNullFalseNameMutateSnakeCase : IJsonFormatterResolver
	{
		private static class FormatterCache<T>
		{
			public static readonly IJsonFormatter<T> formatter;

			static FormatterCache()
			{
				formatter = (IJsonFormatter<T>)DynamicObjectTypeBuilder.BuildFormatterToAssembly<T>(assembly, Instance, nameMutator, excludeNull);
			}
		}

		public static readonly IJsonFormatterResolver Instance;

		private static readonly Func<string, string> nameMutator;

		private static readonly bool excludeNull;

		private const string ModuleName = "Utf8Json.Resolvers.DynamicObjectResolverAllowPrivateFalseExcludeNullFalseNameMutateSnakeCase";

		private static readonly DynamicAssembly assembly;

		static DynamicObjectResolverAllowPrivateFalseExcludeNullFalseNameMutateSnakeCase()
		{
			Instance = new DynamicObjectResolverAllowPrivateFalseExcludeNullFalseNameMutateSnakeCase();
			nameMutator = StringMutator.ToSnakeCase;
			excludeNull = false;
			assembly = new DynamicAssembly("Utf8Json.Resolvers.DynamicObjectResolverAllowPrivateFalseExcludeNullFalseNameMutateSnakeCase");
		}

		private DynamicObjectResolverAllowPrivateFalseExcludeNullFalseNameMutateSnakeCase()
		{
		}

		public IJsonFormatter<T> GetFormatter<T>()
		{
			return FormatterCache<T>.formatter;
		}
	}
	internal sealed class DynamicObjectResolverAllowPrivateFalseExcludeNullTrueNameMutateOriginal : IJsonFormatterResolver
	{
		private static class FormatterCache<T>
		{
			public static readonly IJsonFormatter<T> formatter;

			static FormatterCache()
			{
				formatter = (IJsonFormatter<T>)DynamicObjectTypeBuilder.BuildFormatterToAssembly<T>(assembly, Instance, nameMutator, excludeNull);
			}
		}

		public static readonly IJsonFormatterResolver Instance;

		private static readonly Func<string, string> nameMutator;

		private static readonly bool excludeNull;

		private const string ModuleName = "Utf8Json.Resolvers.DynamicObjectResolverAllowPrivateFalseExcludeNullTrueNameMutateOriginal";

		private static readonly DynamicAssembly assembly;

		static DynamicObjectResolverAllowPrivateFalseExcludeNullTrueNameMutateOriginal()
		{
			Instance = new DynamicObjectResolverAllowPrivateFalseExcludeNullTrueNameMutateOriginal();
			nameMutator = StringMutator.Original;
			excludeNull = true;
			assembly = new DynamicAssembly("Utf8Json.Resolvers.DynamicObjectResolverAllowPrivateFalseExcludeNullTrueNameMutateOriginal");
		}

		private DynamicObjectResolverAllowPrivateFalseExcludeNullTrueNameMutateOriginal()
		{
		}

		public IJsonFormatter<T> GetFormatter<T>()
		{
			return FormatterCache<T>.formatter;
		}
	}
	internal sealed class DynamicObjectResolverAllowPrivateFalseExcludeNullTrueNameMutateCamelCase : IJsonFormatterResolver
	{
		private static class FormatterCache<T>
		{
			public static readonly IJsonFormatter<T> formatter;

			static FormatterCache()
			{
				formatter = (IJsonFormatter<T>)DynamicObjectTypeBuilder.BuildFormatterToAssembly<T>(assembly, Instance, nameMutator, excludeNull);
			}
		}

		public static readonly IJsonFormatterResolver Instance;

		private static readonly Func<string, string> nameMutator;

		private static readonly bool excludeNull;

		private const string ModuleName = "Utf8Json.Resolvers.DynamicObjectResolverAllowPrivateFalseExcludeNullTrueNameMutateCamelCase";

		private static readonly DynamicAssembly assembly;

		static DynamicObjectResolverAllowPrivateFalseExcludeNullTrueNameMutateCamelCase()
		{
			Instance = new DynamicObjectResolverAllowPrivateFalseExcludeNullTrueNameMutateCamelCase();
			nameMutator = StringMutator.ToCamelCase;
			excludeNull = true;
			assembly = new DynamicAssembly("Utf8Json.Resolvers.DynamicObjectResolverAllowPrivateFalseExcludeNullTrueNameMutateCamelCase");
		}

		private DynamicObjectResolverAllowPrivateFalseExcludeNullTrueNameMutateCamelCase()
		{
		}

		public IJsonFormatter<T> GetFormatter<T>()
		{
			return FormatterCache<T>.formatter;
		}
	}
	internal sealed class DynamicObjectResolverAllowPrivateFalseExcludeNullTrueNameMutateSnakeCase : IJsonFormatterResolver
	{
		private static class FormatterCache<T>
		{
			public static readonly IJsonFormatter<T> formatter;

			static FormatterCache()
			{
				formatter = (IJsonFormatter<T>)DynamicObjectTypeBuilder.BuildFormatterToAssembly<T>(assembly, Instance, nameMutator, excludeNull);
			}
		}

		public static readonly IJsonFormatterResolver Instance;

		private static readonly Func<string, string> nameMutator;

		private static readonly bool excludeNull;

		private const string ModuleName = "Utf8Json.Resolvers.DynamicObjectResolverAllowPrivateFalseExcludeNullTrueNameMutateSnakeCase";

		private static readonly DynamicAssembly assembly;

		static DynamicObjectResolverAllowPrivateFalseExcludeNullTrueNameMutateSnakeCase()
		{
			Instance = new DynamicObjectResolverAllowPrivateFalseExcludeNullTrueNameMutateSnakeCase();
			nameMutator = StringMutator.ToSnakeCase;
			excludeNull = true;
			assembly = new DynamicAssembly("Utf8Json.Resolvers.DynamicObjectResolverAllowPrivateFalseExcludeNullTrueNameMutateSnakeCase");
		}

		private DynamicObjectResolverAllowPrivateFalseExcludeNullTrueNameMutateSnakeCase()
		{
		}

		public IJsonFormatter<T> GetFormatter<T>()
		{
			return FormatterCache<T>.formatter;
		}
	}
	internal sealed class DynamicObjectResolverAllowPrivateTrueExcludeNullFalseNameMutateOriginal : IJsonFormatterResolver
	{
		private static class FormatterCache<T>
		{
			public static readonly IJsonFormatter<T> formatter;

			static FormatterCache()
			{
				formatter = (IJsonFormatter<T>)DynamicObjectTypeBuilder.BuildFormatterToDynamicMethod<T>(Instance, nameMutator, excludeNull, allowPrivate: true);
			}
		}

		public static readonly IJsonFormatterResolver Instance = new DynamicObjectResolverAllowPrivateTrueExcludeNullFalseNameMutateOriginal();

		private static readonly Func<string, string> nameMutator = StringMutator.Original;

		private static readonly bool excludeNull = false;

		public IJsonFormatter<T> GetFormatter<T>()
		{
			return FormatterCache<T>.formatter;
		}
	}
	internal sealed class DynamicObjectResolverAllowPrivateTrueExcludeNullFalseNameMutateCamelCase : IJsonFormatterResolver
	{
		private static class FormatterCache<T>
		{
			public static readonly IJsonFormatter<T> formatter;

			static FormatterCache()
			{
				formatter = (IJsonFormatter<T>)DynamicObjectTypeBuilder.BuildFormatterToDynamicMethod<T>(Instance, nameMutator, excludeNull, allowPrivate: true);
			}
		}

		public static readonly IJsonFormatterResolver Instance = new DynamicObjectResolverAllowPrivateTrueExcludeNullFalseNameMutateCamelCase();

		private static readonly Func<string, string> nameMutator = StringMutator.ToCamelCase;

		private static readonly bool excludeNull = false;

		public IJsonFormatter<T> GetFormatter<T>()
		{
			return FormatterCache<T>.formatter;
		}
	}
	internal sealed class DynamicObjectResolverAllowPrivateTrueExcludeNullFalseNameMutateSnakeCase : IJsonFormatterResolver
	{
		private static class FormatterCache<T>
		{
			public static readonly IJsonFormatter<T> formatter;

			static FormatterCache()
			{
				formatter = (IJsonFormatter<T>)DynamicObjectTypeBuilder.BuildFormatterToDynamicMethod<T>(Instance, nameMutator, excludeNull, allowPrivate: true);
			}
		}

		public static readonly IJsonFormatterResolver Instance = new DynamicObjectResolverAllowPrivateTrueExcludeNullFalseNameMutateSnakeCase();

		private static readonly Func<string, string> nameMutator = StringMutator.ToSnakeCase;

		private static readonly bool excludeNull = false;

		public IJsonFormatter<T> GetFormatter<T>()
		{
			return FormatterCache<T>.formatter;
		}
	}
	internal sealed class DynamicObjectResolverAllowPrivateTrueExcludeNullTrueNameMutateOriginal : IJsonFormatterResolver
	{
		private static class FormatterCache<T>
		{
			public static readonly IJsonFormatter<T> formatter;

			static FormatterCache()
			{
				formatter = (IJsonFormatter<T>)DynamicObjectTypeBuilder.BuildFormatterToDynamicMethod<T>(Instance, nameMutator, excludeNull, allowPrivate: true);
			}
		}

		public static readonly IJsonFormatterResolver Instance = new DynamicObjectResolverAllowPrivateTrueExcludeNullTrueNameMutateOriginal();

		private static readonly Func<string, string> nameMutator = StringMutator.Original;

		private static readonly bool excludeNull = true;

		public IJsonFormatter<T> GetFormatter<T>()
		{
			return FormatterCache<T>.formatter;
		}
	}
	internal sealed class DynamicObjectResolverAllowPrivateTrueExcludeNullTrueNameMutateCamelCase : IJsonFormatterResolver
	{
		private static class FormatterCache<T>
		{
			public static readonly IJsonFormatter<T> formatter;

			static FormatterCache()
			{
				formatter = (IJsonFormatter<T>)DynamicObjectTypeBuilder.BuildFormatterToDynamicMethod<T>(Instance, nameMutator, excludeNull, allowPrivate: true);
			}
		}

		public static readonly IJsonFormatterResolver Instance = new DynamicObjectResolverAllowPrivateTrueExcludeNullTrueNameMutateCamelCase();

		private static readonly Func<string, string> nameMutator = StringMutator.ToCamelCase;

		private static readonly bool excludeNull = true;

		public IJsonFormatter<T> GetFormatter<T>()
		{
			return FormatterCache<T>.formatter;
		}
	}
	internal sealed class DynamicObjectResolverAllowPrivateTrueExcludeNullTrueNameMutateSnakeCase : IJsonFormatterResolver
	{
		private static class FormatterCache<T>
		{
			public static readonly IJsonFormatter<T> formatter;

			static FormatterCache()
			{
				formatter = (IJsonFormatter<T>)DynamicObjectTypeBuilder.BuildFormatterToDynamicMethod<T>(Instance, nameMutator, excludeNull, allowPrivate: true);
			}
		}

		public static readonly IJsonFormatterResolver Instance = new DynamicObjectResolverAllowPrivateTrueExcludeNullTrueNameMutateSnakeCase();

		private static readonly Func<string, string> nameMutator = StringMutator.ToSnakeCase;

		private static readonly bool excludeNull = true;

		public IJsonFormatter<T> GetFormatter<T>()
		{
			return FormatterCache<T>.formatter;
		}
	}
	internal static class DynamicObjectTypeBuilder
	{
		private struct DeserializeInfo
		{
			public MetaMember MemberInfo;

			public LocalBuilder LocalField;

			public LocalBuilder IsDeserializedField;
		}

		internal static class EmitInfo
		{
			internal static class JsonWriter
			{
				public static readonly MethodInfo GetEncodedPropertyNameWithBeginObject;

				public static readonly MethodInfo GetEncodedPropertyNameWithPrefixValueSeparator;

				public static readonly MethodInfo GetEncodedPropertyNameWithoutQuotation;

				public static readonly MethodInfo GetEncodedPropertyName;

				public static readonly MethodInfo WriteNull;

				public static readonly MethodInfo WriteRaw;

				public static readonly MethodInfo WriteBeginObject;

				public static readonly MethodInfo WriteEndObject;

				public static readonly MethodInfo WriteValueSeparator;

				static JsonWriter()
				{
					GetEncodedPropertyNameWithBeginObject = ExpressionUtility.GetMethodInfo(() => Utf8Json.JsonWriter.GetEncodedPropertyNameWithBeginObject(null));
					GetEncodedPropertyNameWithPrefixValueSeparator = ExpressionUtility.GetMethodInfo(() => Utf8Json.JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator(null));
					GetEncodedPropertyNameWithoutQuotation = ExpressionUtility.GetMethodInfo(() => Utf8Json.JsonWriter

plugins/System.Threading.Tasks.Extensions.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security;
using System.Threading.Tasks;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("System.Threading.Tasks.Extensions")]
[assembly: AssemblyDescription("System.Threading.Tasks.Extensions")]
[assembly: AssemblyDefaultAlias("System.Threading.Tasks.Extensions")]
[assembly: AssemblyCompany("Microsoft Corporation")]
[assembly: AssemblyProduct("Microsoft® .NET Framework")]
[assembly: AssemblyCopyright("© Microsoft Corporation.  All rights reserved.")]
[assembly: AssemblyFileVersion("4.6.25519.03")]
[assembly: AssemblyInformationalVersion("4.6.25519.03 built by: dlab-DDVSOWINAGE013. Commit Hash: 8321c729934c0f8be754953439b88e6e1c120c24")]
[assembly: CLSCompliant(true)]
[assembly: AssemblyMetadata(".NETFrameworkAssembly", "")]
[assembly: AssemblyMetadata("Serviceable", "True")]
[assembly: AssemblyMetadata("PreferInbox", "True")]
[assembly: AssemblyVersion("4.1.1.0")]
namespace System.Threading.Tasks
{
	[StructLayout(LayoutKind.Auto)]
	[AsyncMethodBuilder(typeof(AsyncValueTaskMethodBuilder<>))]
	public struct ValueTask<TResult> : IEquatable<ValueTask<TResult>>
	{
		internal readonly Task<TResult> _task;

		internal readonly TResult _result;

		public bool IsCompleted
		{
			get
			{
				if (_task != null)
				{
					return _task.IsCompleted;
				}
				return true;
			}
		}

		public bool IsCompletedSuccessfully
		{
			get
			{
				if (_task != null)
				{
					return _task.Status == TaskStatus.RanToCompletion;
				}
				return true;
			}
		}

		public bool IsFaulted
		{
			get
			{
				if (_task != null)
				{
					return _task.IsFaulted;
				}
				return false;
			}
		}

		public bool IsCanceled
		{
			get
			{
				if (_task != null)
				{
					return _task.IsCanceled;
				}
				return false;
			}
		}

		public TResult Result
		{
			get
			{
				if (_task != null)
				{
					return _task.GetAwaiter().GetResult();
				}
				return _result;
			}
		}

		public ValueTask(TResult result)
		{
			_task = null;
			_result = result;
		}

		public ValueTask(Task<TResult> task)
		{
			if (task == null)
			{
				throw new ArgumentNullException("task");
			}
			_task = task;
			_result = default(TResult);
		}

		public override int GetHashCode()
		{
			if (_task == null)
			{
				if (_result == null)
				{
					return 0;
				}
				return _result.GetHashCode();
			}
			return _task.GetHashCode();
		}

		public override bool Equals(object obj)
		{
			if (obj is ValueTask<TResult>)
			{
				return Equals((ValueTask<TResult>)obj);
			}
			return false;
		}

		public bool Equals(ValueTask<TResult> other)
		{
			if (_task == null && other._task == null)
			{
				return EqualityComparer<TResult>.Default.Equals(_result, other._result);
			}
			return _task == other._task;
		}

		public static bool operator ==(ValueTask<TResult> left, ValueTask<TResult> right)
		{
			return left.Equals(right);
		}

		public static bool operator !=(ValueTask<TResult> left, ValueTask<TResult> right)
		{
			return !left.Equals(right);
		}

		public Task<TResult> AsTask()
		{
			return _task ?? Task.FromResult(_result);
		}

		public ValueTaskAwaiter<TResult> GetAwaiter()
		{
			return new ValueTaskAwaiter<TResult>(this);
		}

		public ConfiguredValueTaskAwaitable<TResult> ConfigureAwait(bool continueOnCapturedContext)
		{
			return new ConfiguredValueTaskAwaitable<TResult>(this, continueOnCapturedContext);
		}

		public override string ToString()
		{
			if (_task != null)
			{
				if (_task.Status != TaskStatus.RanToCompletion || _task.Result == null)
				{
					return string.Empty;
				}
				return _task.Result.ToString();
			}
			if (_result == null)
			{
				return string.Empty;
			}
			return _result.ToString();
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public static AsyncValueTaskMethodBuilder<TResult> CreateAsyncMethodBuilder()
		{
			return AsyncValueTaskMethodBuilder<TResult>.Create();
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false, AllowMultiple = false)]
	public sealed class AsyncMethodBuilderAttribute : Attribute
	{
		public Type BuilderType { get; }

		public AsyncMethodBuilderAttribute(Type builderType)
		{
			BuilderType = builderType;
		}
	}
	[StructLayout(LayoutKind.Auto)]
	public struct AsyncValueTaskMethodBuilder<TResult>
	{
		private AsyncTaskMethodBuilder<TResult> _methodBuilder;

		private TResult _result;

		private bool _haveResult;

		private bool _useBuilder;

		public ValueTask<TResult> Task
		{
			get
			{
				if (_haveResult)
				{
					return new ValueTask<TResult>(_result);
				}
				_useBuilder = true;
				return new ValueTask<TResult>(_methodBuilder.Task);
			}
		}

		public static AsyncValueTaskMethodBuilder<TResult> Create()
		{
			return new AsyncValueTaskMethodBuilder<TResult>
			{
				_methodBuilder = AsyncTaskMethodBuilder<TResult>.Create()
			};
		}

		public void Start<TStateMachine>(ref TStateMachine stateMachine) where TStateMachine : IAsyncStateMachine
		{
			_methodBuilder.Start(ref stateMachine);
		}

		public void SetStateMachine(IAsyncStateMachine stateMachine)
		{
			_methodBuilder.SetStateMachine(stateMachine);
		}

		public void SetResult(TResult result)
		{
			if (_useBuilder)
			{
				_methodBuilder.SetResult(result);
				return;
			}
			_result = result;
			_haveResult = true;
		}

		public void SetException(Exception exception)
		{
			_methodBuilder.SetException(exception);
		}

		public void AwaitOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : INotifyCompletion where TStateMachine : IAsyncStateMachine
		{
			_useBuilder = true;
			_methodBuilder.AwaitOnCompleted(ref awaiter, ref stateMachine);
		}

		[SecuritySafeCritical]
		public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : ICriticalNotifyCompletion where TStateMachine : IAsyncStateMachine
		{
			_useBuilder = true;
			_methodBuilder.AwaitUnsafeOnCompleted(ref awaiter, ref stateMachine);
		}
	}
	[StructLayout(LayoutKind.Auto)]
	public struct ConfiguredValueTaskAwaitable<TResult>
	{
		[StructLayout(LayoutKind.Auto)]
		public struct ConfiguredValueTaskAwaiter : ICriticalNotifyCompletion, INotifyCompletion
		{
			private readonly ValueTask<TResult> _value;

			private readonly bool _continueOnCapturedContext;

			public bool IsCompleted => _value.IsCompleted;

			internal ConfiguredValueTaskAwaiter(ValueTask<TResult> value, bool continueOnCapturedContext)
			{
				_value = value;
				_continueOnCapturedContext = continueOnCapturedContext;
			}

			public TResult GetResult()
			{
				if (_value._task != null)
				{
					return _value._task.GetAwaiter().GetResult();
				}
				return _value._result;
			}

			public void OnCompleted(Action continuation)
			{
				_value.AsTask().ConfigureAwait(_continueOnCapturedContext).GetAwaiter()
					.OnCompleted(continuation);
			}

			public void UnsafeOnCompleted(Action continuation)
			{
				_value.AsTask().ConfigureAwait(_continueOnCapturedContext).GetAwaiter()
					.UnsafeOnCompleted(continuation);
			}
		}

		private readonly ValueTask<TResult> _value;

		private readonly bool _continueOnCapturedContext;

		internal ConfiguredValueTaskAwaitable(ValueTask<TResult> value, bool continueOnCapturedContext)
		{
			_value = value;
			_continueOnCapturedContext = continueOnCapturedContext;
		}

		public ConfiguredValueTaskAwaiter GetAwaiter()
		{
			return new ConfiguredValueTaskAwaiter(_value, _continueOnCapturedContext);
		}
	}
	public struct ValueTaskAwaiter<TResult> : ICriticalNotifyCompletion, INotifyCompletion
	{
		private readonly ValueTask<TResult> _value;

		public bool IsCompleted => _value.IsCompleted;

		internal ValueTaskAwaiter(ValueTask<TResult> value)
		{
			_value = value;
		}

		public TResult GetResult()
		{
			if (_value._task != null)
			{
				return _value._task.GetAwaiter().GetResult();
			}
			return _value._result;
		}

		public void OnCompleted(Action continuation)
		{
			_value.AsTask().ConfigureAwait(continueOnCapturedContext: true).GetAwaiter()
				.OnCompleted(continuation);
		}

		public void UnsafeOnCompleted(Action continuation)
		{
			_value.AsTask().ConfigureAwait(continueOnCapturedContext: true).GetAwaiter()
				.UnsafeOnCompleted(continuation);
		}
	}
	[AttributeUsage(AttributeTargets.All)]
	internal class __BlockReflectionAttribute : Attribute
	{
	}
}