Decompiled source of LandoriaModPack v1.0.42

Landoria.LandoriaModPack.dll

Decompiled 6 days ago
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Data;
using System.Data.SqlTypes;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
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.Serialization.Formatters;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Cryptography;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Linq;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Landoria.ServerShield.Shared;
using Landoria.ServerShield.Shared.Models;
using Landoria.ServerShield.Shared.Network;
using Landoria.ServerShield.Shared.Serialization;
using Landoria.ServerShield.Shared.World;
using Landoria.SharedLib;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Newtonsoft.Json.Bson;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Linq.JsonPath;
using Newtonsoft.Json.Schema;
using Newtonsoft.Json.Serialization;
using Newtonsoft.Json.Utilities;
using PlayFab.Party;
using Splatform;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("Landoria.LandoriaModPack")]
[assembly: AssemblyDescription("Installs the Landoria modpack dependencies.")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Landoria.LandoriaModPack")]
[assembly: AssemblyCopyright("Copyright © 2026")]
[assembly: ComVisible(false)]
[assembly: Guid("BD9DB129-FFA6-414E-95AD-10EA8CE362C4")]
[assembly: AssemblyFileVersion("1.0.42")]
[assembly: AssemblyInformationalVersion("1.0.42")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = "")]
[assembly: AssemblyVersion("1.0.42.17079")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[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 Landoria.ServerShield.Shared
{
	internal static class Constants
	{
		internal static class Movement
		{
			internal const int Portal = 0;

			internal const int Dungeon = 1;

			internal const float RequestInterval = 2f;

			internal const float SpawnRetrySeconds = 1f;

			internal const float ArrivalTolerance = 2f;

			internal const float ArrivalToleranceSquared = 4f;

			internal const float ObservationSeconds = 5f;

			internal const float ObservationFactor = 4f;

			internal const float ObservationLogInterval = 30f;

			internal const int TeleportRequestBytes = 28;

			internal const float SourceDistance = 5f;

			internal const float SourceHintToleranceSquared = 1f;

			internal const float LogoutHeightOffset = 0.25f;

			internal const float StartHeightOffset = 2f;

			internal const float BedSearchDistance = 5f;

			internal const int ConnectionsFlag = 1;

			internal const int FloatsFlag = 2;

			internal const int VectorsFlag = 4;

			internal const int QuaternionsFlag = 8;

			internal const int IntegersFlag = 16;
		}

		internal static class Rpc
		{
			internal const string Admission = "Landoria.ServerShield.Admission";

			internal const string Rejection = "Landoria.ServerShield.Rejection";

			internal const string RejectionAck = "Landoria.ServerShield.RejectionAck";

			internal const string TeleportComplete = "Landoria.ServerShield.TeleportDone";

			internal const string SpawnAnchor = "Landoria.ServerShield.SpawnAnchor";

			internal const string TeleportRequest = "Landoria.ServerShield.Teleport";

			internal const string TeleportResult = "Landoria.ServerShield.TeleportResult";

			internal const string RejectedObjects = "Landoria.ServerShield.RejectedObjects";

			internal const string SkillProgress = "Landoria.ServerShield.SkillProgress";

			internal const string PickupResult = "Landoria.ServerShield.PickupResult";

			internal const string ContainerSnapshot = "Landoria.ServerShield.ContainerSnapshot";

			internal const string WorldAction = "Landoria.ServerShield.WorldAction";

			internal const string WorldActionResult = "Landoria.ServerShield.WorldActionResult";

			internal const string ReservePlayer = "Landoria.ServerShield.ReservePlayer";

			internal const string ReservedPlayer = "Landoria.ServerShield.ReservedPlayer";

			internal const string Spawn = "Landoria.ServerShield.Spawn";

			internal const string SpawnResult = "Landoria.ServerShield.SpawnResult";

			internal const string Discoveries = "Landoria.ServerShield.Discoveries";

			internal const string MapState = "Landoria.ServerShield.MapState";

			internal const string MapExplore = "Landoria.ServerShield.MapExplore";

			internal const string MapPinRequest = "Landoria.ServerShield.MapPinRequest";

			internal const string MapPinResult = "Landoria.ServerShield.MapPinResult";

			internal const string Attack = "Landoria.ServerShield.Attack";

			internal const string CombatResult = "Landoria.ServerShield.CombatResult";

			internal const string PlayerHealth = "Landoria.ServerShield.PlayerHealth";

			internal const string FoodState = "Landoria.ServerShield.FoodState";

			internal const string CombatInventory = "Landoria.ServerShield.CombatInventory";

			internal const string Response = "Landoria.ServerShield.Profile";
		}

		internal static class Serialization
		{
			internal const int MaximumBytes = 67108864;

			internal const int MaximumEntries = 100000;

			internal const string CharacterFormat = "Landoria.ServerShield.character";

			internal const int ProfileVersion = 46;

			internal const int PlayerVersion = 33;

			internal const int InventoryVersion = 109;

			internal const int SkillsVersion = 2;

			internal const int JsonSchemaVersion = 1;

			internal const int MaximumJsonDepth = 64;

			internal const int FchEnvelopeBytes = 72;

			internal const long JsonSizeMultiplier = 4L;

			internal const int CompactCountContinuationBit = 128;

			internal const int CompactCountHighMask = 127;

			internal const int MaximumCompactCount = 32767;

			internal const int ByteMask = 255;

			internal const int BitsPerByte = 8;

			internal const float DurabilityScale = 100f;

			internal const int FirstPrintableAscii = 32;

			internal const int PrintableAsciiEnd = 127;
		}

		internal static class Combat
		{
			internal const float HealthSnapshotSeconds = 1f;

			internal const int MaximumHealthPlayers = 1024;

			internal const string AttackSoundKey = "Landoria.ServerShield.attackSound";

			internal const int MaximumPredictedImpacts = 4096;

			internal const float AudioLogRange = 12f;

			internal const float AudioLogWindowSeconds = 5f;

			internal const int MaximumAudioLogsPerWindow = 80;

			internal const float MinimumAudioPitch = 0.01f;

			internal const float MinimumReverbPitch = 0.5f;

			internal const float AudioCleanupDelaySeconds = 0.1f;

			internal const float ImpactAngleStepDegrees = 4f;

			internal const int MaximumAttackRequests = 100000;

			internal const float MinimumMovementNoiseSpeed = 0.1f;

			internal const float PerceptionSampleSeconds = 0.5f;

			internal const float WalkingNoiseRange = 15f;

			internal const float RunningNoiseRange = 30f;
		}

		internal static class Plugin
		{
			internal const string ClientGuid = "Landoria.ServerShield.Client";

			internal const string ServerGuid = "Landoria.ServerShield.Server";
		}

		internal static class ItemFlags
		{
			internal const int Quality = 4;

			internal const int Quantity = 8;

			internal const int Variant = 16;

			internal const int Crafter = 32;

			internal const int PrefabHash = 64;

			internal const int CustomData = 128;

			internal const int Equipped = 2;
		}

		internal static class Map
		{
			internal const int MaximumPins = 10000;

			internal const int MaximumPinNameLength = 128;

			internal const int MaximumPinRequestJsonLength = 2048;

			internal const int MaximumPinRequestsPerSession = 100000;

			internal const int MaximumSize = 4096;

			internal const int MaximumPinRequestsPerSecond = 16;

			internal const int FormatVersion = 8;
		}

		internal static class World
		{
			internal const int MaximumUpdateBytes = 2097152;

			internal const int MaximumInvalidations = 100000;

			internal const int RejectedObjectHistory = 4096;

			internal const int MaximumRejectedObjectLogs = 20;

			internal const float RejectedObjectLogWindowSeconds = 5f;

			internal const int MaximumTracedCreatures = 256;

			internal const float CreatureTraceWaitSeconds = 5f;

			internal const float MaximumCoordinateMagnitude = 100000f;

			internal const int MaximumRpcBytes = 65536;

			internal const int MaximumActionJsonLength = 8192;

			internal const int MaximumActionRequests = 100000;

			internal const int RotationFlag = 4096;

			internal const int ObjectHeaderBytes = 6;
		}

		internal static class Compression
		{
			internal const int MaximumUncompressedControlBytes = 5;

			internal const int HeaderByteShift = 8;

			internal const int CompressionMethodMask = 15;

			internal const int DeflateCompressionMethod = 8;

			internal const int HeaderChecksumDivisor = 31;
		}

		internal static class Timing
		{
			internal const float RejectionTimeoutSeconds = 2f;

			internal const float CharacterRequestTimeoutSeconds = 30f;

			internal const float CharacterSaveIntervalSeconds = 30f;

			internal const double CharacterCacheIdleSeconds = 600.0;

			internal const float MinimumAttackIntervalSeconds = 0.15f;

			internal const float MinimumAttackLifetimeSeconds = 5f;

			internal const float AttackLifetimeGraceSeconds = 2f;

			internal const float LoadingPickupTimeoutSeconds = 10f;

			internal const float PickupTimeoutSeconds = 2f;

			internal const float PinRateWindowSeconds = 1f;
		}

		internal static class Building
		{
			internal const float RemovalRayDistance = 50f;

			internal const float PlacementNoiseRange = 50f;

			internal const float PlacementRayDistance = 50f;

			internal const float MaximumCameraDistance = 8f;

			internal const float MinimumAimMagnitude = 0.0001f;

			internal const float SurfaceProbeOffset = 50f;

			internal const float WaterPlacementOffset = 3f;

			internal const float SnapSearchRadius = 10f;

			internal const float SnapDistance = 0.5f;

			internal const float OverlapDistance = 0.05f;

			internal const float OverlapAngle = 10f;

			internal const float MaximumAshlandsVegetationMask = 0.1f;

			internal const float MinimumVegetationMask = 0.25f;

			internal const float MinimumFlatSurfaceNormalY = 0.8f;

			internal const float MaximumCeilingNormalY = -0.5f;

			internal const float MaximumNonFloorNormalY = 0.1f;

			internal const float MaximumClippingPenetration = 0.2f;
		}

		internal static class Spawn
		{
			internal const int MaximumCommandLength = 256;

			internal const float DefaultRadius = 0.5f;

			internal const int MaximumAmount = 100;

			internal const int MaximumLevel = 9;

			internal const int MaximumRadius = 20;
		}

		internal static class Inventory
		{
			internal const int MaximumRepairStationLevel = 4;

			internal const int MaximumPickupReports = 256;

			internal const int MaximumPendingPickups = 4096;

			internal const int MaximumPendingPickupsPerPeer = 64;

			internal const float HeavyItemWeight = 300f;

			internal const float HeavyItemDropSpeed = 0.5f;

			internal const float ItemDropSpeed = 5f;

			internal const float MaximumInteractionDistance = 4f;

			internal const int MaximumCraftCount = 100;
		}

		internal static class Character
		{
			internal const int MaximumDiscoveryNameLength = 256;

			internal const int MaximumStationLevel = 10000;

			internal const int MaximumDiscoveriesJsonLength = 262144;

			internal const int MaximumAccessoryNameLength = 128;

			internal const int MaximumAppearanceJsonLength = 4096;

			internal const int MaximumDiscoveries = 4096;

			internal const float InitialHealth = 25f;

			internal const float InitialStamina = 75f;

			internal const string StarterTorchPrefab = "Torch";

			internal const string StarterChestPrefab = "ArmorRagsChest";
		}
	}
	internal static class PluginPatches
	{
		internal static Type[] For(Type pluginType)
		{
			List<Type> list = new List<Type>();
			Type[] types = pluginType.Assembly.GetTypes();
			foreach (Type type in types)
			{
				if (!(type.Namespace == pluginType.Namespace) && !(type.Namespace == typeof(PluginPatches).Namespace))
				{
					string? text = type.Namespace;
					if (text == null || !text.StartsWith(typeof(PluginPatches).Namespace + ".", StringComparison.Ordinal))
					{
						continue;
					}
				}
				list.Add(type);
			}
			return list.ToArray();
		}
	}
}
namespace Landoria.ServerShield.Shared.World
{
	internal static class WorldInteractions
	{
		internal static bool Supported(Component component)
		{
			if (!(component is Pickable) && !(component is PickableItem) && !(component is Beehive) && !(component is Fermenter) && !(component is CookingStation) && !(component is Fireplace))
			{
				if (component is Switch)
				{
					if (!((Object)(object)component.GetComponentInParent<Smelter>() != (Object)null))
					{
						return (Object)(object)component.GetComponentInParent<CookingStation>() != (Object)null;
					}
					return true;
				}
				return false;
			}
			return true;
		}
	}
}
namespace Landoria.ServerShield.Shared.Serialization
{
	internal sealed class BinaryJson : IDisposable
	{
		private readonly MemoryStream stream;

		private readonly BinaryReader reader;

		private readonly BinaryWriter writer;

		internal bool Writing => writer != null;

		internal BinaryJson(byte[] data = null)
		{
			if (data != null && data.Length > 67108864)
			{
				throw new InvalidDataException("Character data is too large.");
			}
			stream = ((data == null) ? new MemoryStream() : new MemoryStream(data, writable: false));
			UTF8Encoding encoding = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: true);
			if (data == null)
			{
				writer = new BinaryWriter(stream, encoding, leaveOpen: true);
			}
			else
			{
				reader = new BinaryReader(stream, encoding, leaveOpen: true);
			}
		}

		internal byte[] Finish()
		{
			ValidateComplete();
			return stream.ToArray();
		}

		internal void ValidateComplete(int reservedBytes = 0)
		{
			if (!Writing && stream.Position != stream.Length)
			{
				throw new InvalidDataException("Trailing character data.");
			}
			if (stream.Length > 67108864 - reservedBytes)
			{
				throw new InvalidDataException("Character data is too large.");
			}
		}

		private T Field<T>(JObject obj, string name, Func<T> read, Action<T> write, Func<JToken, T> parse)
		{
			if (!Writing)
			{
				T val = read();
				obj[name] = JToken.FromObject(val);
				return val;
			}
			T val2 = parse(Required(obj, name));
			write(val2);
			if (stream.Length > 67108864)
			{
				throw new InvalidDataException("Character data is too large.");
			}
			return val2;
		}

		internal static JToken Required(JObject obj, string name)
		{
			return obj[name] ?? throw new InvalidDataException("Missing JSON field: " + name);
		}

		internal static long Integer(JToken token)
		{
			if (token.Type != JTokenType.Integer)
			{
				throw new InvalidDataException("Expected an integer.");
			}
			return token.Value<long>();
		}

		internal static bool Boolean(JToken token)
		{
			if (token.Type != JTokenType.Boolean)
			{
				throw new InvalidDataException("Expected a boolean.");
			}
			return token.Value<bool>();
		}

		internal static string Text(JToken token)
		{
			if (token.Type != JTokenType.String)
			{
				throw new InvalidDataException("Expected a string.");
			}
			return token.Value<string>();
		}

		internal int Int(JObject obj, string name)
		{
			return Field(obj, name, (reader == null) ? null : new Func<int>(reader.ReadInt32), (writer == null) ? null : new Action<int>(writer.Write), (JToken t) => checked((int)Integer(t)));
		}

		internal byte Byte(JObject obj, string name)
		{
			return Field(obj, name, (reader == null) ? null : new Func<byte>(reader.ReadByte), (writer == null) ? null : new Action<byte>(writer.Write), (JToken t) => checked((byte)Integer(t)));
		}

		internal ushort UShort(JObject obj, string name)
		{
			return Field(obj, name, (reader == null) ? null : new Func<ushort>(reader.ReadUInt16), (writer == null) ? null : new Action<ushort>(writer.Write), (JToken t) => checked((ushort)Integer(t)));
		}

		internal bool Bool(JObject obj, string name)
		{
			return Field(obj, name, (reader == null) ? null : new Func<bool>(reader.ReadBoolean), (writer == null) ? null : new Action<bool>(writer.Write), Boolean);
		}

		internal string String(JObject obj, string name)
		{
			return Field(obj, name, (reader == null) ? null : new Func<string>(reader.ReadString), (writer == null) ? null : new Action<string>(writer.Write), Text);
		}

		internal void Long(JObject obj, string name)
		{
			if (!Writing)
			{
				obj[name] = reader.ReadInt64().ToString(CultureInfo.InvariantCulture);
			}
			else
			{
				writer.Write(long.Parse(Text(Required(obj, name)), CultureInfo.InvariantCulture));
			}
		}

		internal void Float(JObject obj, string name)
		{
			if (Writing)
			{
				WriteFloat(Required(obj, name));
			}
			else
			{
				obj[name] = ReadFloat();
			}
		}

		private JToken ReadFloat()
		{
			int num = reader.ReadInt32();
			float num2 = BitConverter.ToSingle(BitConverter.GetBytes(num), 0);
			if (!float.IsNaN(num2) && !float.IsInfinity(num2) && num != int.MinValue)
			{
				return new JValue((double)num2);
			}
			object[] array = new object[1];
			uint num3 = (uint)num;
			array[0] = num3.ToString("X8", CultureInfo.InvariantCulture);
			return JsonTemplate.Object(FormattableStringFactory.Create("{{\n    \"floatBits\": {0}\n}}", array));
		}

		private void WriteFloat(JToken token)
		{
			if (token is JObject obj)
			{
				writer.Write(uint.Parse(Text(Required(obj, "floatBits")), NumberStyles.HexNumber, CultureInfo.InvariantCulture));
				return;
			}
			if (token.Type != JTokenType.Float && token.Type != JTokenType.Integer)
			{
				throw new InvalidDataException("Expected a number or floatBits.");
			}
			float num = token.Value<float>();
			if (float.IsInfinity(num) || float.IsNaN(num))
			{
				throw new InvalidDataException("Non-finite float requires floatBits.");
			}
			writer.Write(num);
		}

		internal void Version(JObject obj, int expected)
		{
			if (Int(obj, "version") != expected)
			{
				throw new InvalidDataException("Unsupported format version; expected " + expected);
			}
		}

		internal void Object(JObject obj, string name, Action<JObject> visit)
		{
			JObject jObject = (Writing ? (Required(obj, name) as JObject) : new JObject());
			if (jObject == null)
			{
				throw new InvalidDataException("Expected object: " + name);
			}
			visit(jObject);
			if (!Writing)
			{
				obj[name] = jObject;
			}
		}

		internal void List(JObject obj, string name, Action<JObject> visit, bool shortCount = false, int fixedCount = -1)
		{
			JArray jArray = (Writing ? (Required(obj, name) as JArray) : new JArray());
			if (jArray == null)
			{
				throw new InvalidDataException("Expected array: " + name);
			}
			int num = (Writing ? jArray.Count : ((fixedCount >= 0) ? fixedCount : (shortCount ? reader.ReadUInt16() : reader.ReadInt32())));
			if (num < 0 || num > 100000)
			{
				throw new InvalidDataException("Invalid array size.");
			}
			if (Writing && fixedCount >= 0 && num != fixedCount)
			{
				throw new InvalidDataException("Invalid fixed array size.");
			}
			if (Writing && fixedCount < 0)
			{
				if (shortCount)
				{
					writer.Write(checked((ushort)num));
				}
				else
				{
					writer.Write(num);
				}
			}
			for (int i = 0; i < num; i++)
			{
				JObject jObject = (Writing ? (jArray[i] as JObject) : new JObject());
				if (jObject == null)
				{
					throw new InvalidDataException("Expected array entry object.");
				}
				visit(jObject);
				if (!Writing)
				{
					jArray.Add(jObject);
				}
			}
			if (!Writing)
			{
				obj[name] = jArray;
			}
		}

		internal void Vector(JObject obj, string name)
		{
			Object(obj, name, delegate(JObject v)
			{
				Float(v, "x");
				Float(v, "y");
				Float(v, "z");
			});
		}

		internal void Blob(JObject obj, string name, Action<BinaryJson, JObject> visit = null)
		{
			if (!Writing)
			{
				int num = reader.ReadInt32();
				if (num < 0 || num > 67108864 || num > stream.Length - stream.Position)
				{
					throw new InvalidDataException("Invalid binary block size.");
				}
				byte[] array = reader.ReadBytes(num);
				if (visit == null)
				{
					obj[name] = Convert.ToBase64String(array);
					return;
				}
				JObject jObject = new JObject();
				using (BinaryJson binaryJson = new BinaryJson(array))
				{
					visit(binaryJson, jObject);
					binaryJson.Finish();
				}
				obj[name] = jObject;
				return;
			}
			byte[] array2;
			if (visit == null)
			{
				array2 = Convert.FromBase64String(Text(Required(obj, name)));
			}
			else
			{
				JObject arg = (Required(obj, name) as JObject) ?? throw new InvalidDataException("Expected package object.");
				using BinaryJson binaryJson2 = new BinaryJson();
				visit(binaryJson2, arg);
				array2 = binaryJson2.Finish();
			}
			if (array2.Length > 67108864)
			{
				throw new InvalidDataException("Binary block is too large.");
			}
			writer.Write(array2.Length);
			writer.Write(array2);
		}

		internal int CompactCount(JObject obj, string name)
		{
			if (!Writing)
			{
				int num = reader.ReadByte();
				if ((num & 0x80) != 0)
				{
					num = ((num & 0x7F) << 8) | reader.ReadByte();
				}
				obj[name] = num;
				return num;
			}
			int num2 = checked((int)Integer(Required(obj, name)));
			if (num2 < 0 || num2 > 32767)
			{
				throw new InvalidDataException("Invalid compact count.");
			}
			if (num2 >= 128)
			{
				writer.Write((byte)((num2 >> 8) | 0x80));
			}
			writer.Write((byte)(num2 & 0xFF));
			return num2;
		}

		public void Dispose()
		{
			reader?.Dispose();
			writer?.Dispose();
			stream.Dispose();
		}
	}
	internal static class CharacterBinary
	{
		internal static CharacterPlayerData ReadPlayer(byte[] bytes)
		{
			return Read<CharacterPlayerData>(bytes, CharacterSchema.Player);
		}

		internal static CharacterInventory ReadInventory(byte[] bytes)
		{
			return Read<CharacterInventory>(bytes, CharacterSchema.Inventory);
		}

		internal static byte[] WriteInventory(CharacterInventory inventory)
		{
			return Write(inventory, CharacterSchema.Inventory);
		}

		internal static CharacterSkills ReadSkills(byte[] bytes)
		{
			return Read<CharacterSkills>(bytes, CharacterSchema.Skills);
		}

		internal static byte[] WriteSkills(CharacterSkills skills)
		{
			return Write(skills, CharacterSchema.Skills);
		}

		private static T Read<T>(byte[] bytes, Action<BinaryJson, JObject> visit) where T : CharacterData
		{
			JObject jObject = new JObject();
			using (BinaryJson binaryJson = new BinaryJson(bytes))
			{
				visit(binaryJson, jObject);
				binaryJson.ValidateComplete();
			}
			return CharacterDocument.FromJson<T>(jObject);
		}

		private static byte[] Write(CharacterData data, Action<BinaryJson, JObject> visit)
		{
			using BinaryJson binaryJson = new BinaryJson();
			visit(binaryJson, CharacterDocument.ToJson(data));
			return binaryJson.Finish();
		}
	}
	internal static class CharacterDocument
	{
		internal static Character Read(string json)
		{
			JObject jObject = CharacterJson.ReadDocument(json);
			CharacterJson.ValidateProfile((JObject)jObject["profile"]);
			return FromJson<Character>(jObject);
		}

		internal static JObject ToJson(CharacterData character)
		{
			return JObject.FromObject(character, Serializer());
		}

		internal static T FromJson<T>(JObject document) where T : CharacterData
		{
			return document.ToObject<T>(Serializer());
		}

		internal static string Serialize(CharacterData character, Formatting formatting = Formatting.Indented)
		{
			using StringWriter stringWriter = new StringWriter(CultureInfo.InvariantCulture);
			using JsonTextWriter jsonWriter = new JsonTextWriter(stringWriter)
			{
				Formatting = formatting
			};
			Serializer().Serialize(jsonWriter, character);
			return stringWriter.ToString();
		}

		internal static bool Equivalent(CharacterData first, CharacterData second)
		{
			return JToken.DeepEquals(ToJson(first), ToJson(second));
		}

		private static JsonSerializer Serializer()
		{
			JsonSerializer jsonSerializer = JsonSerializer.Create(new JsonSerializerSettings
			{
				Culture = CultureInfo.InvariantCulture,
				CheckAdditionalContent = true,
				DateParseHandling = DateParseHandling.None
			});
			jsonSerializer.Converters.Add(new CharacterFloatConverter());
			return jsonSerializer;
		}
	}
	internal sealed class CharacterFloatConverter : JsonConverter<float>
	{
		public override float ReadJson(JsonReader reader, Type objectType, float existingValue, bool hasExistingValue, JsonSerializer serializer)
		{
			JToken jToken = JToken.Load(reader);
			if (jToken is JObject obj)
			{
				return BitConverter.ToSingle(BitConverter.GetBytes(uint.Parse(BinaryJson.Text(BinaryJson.Required(obj, "floatBits")), NumberStyles.HexNumber, CultureInfo.InvariantCulture)), 0);
			}
			return jToken.Value<float>();
		}

		public override void WriteJson(JsonWriter writer, float value, JsonSerializer serializer)
		{
			int num = BitConverter.ToInt32(BitConverter.GetBytes(value), 0);
			if (float.IsNaN(value) || float.IsInfinity(value) || num == int.MinValue)
			{
				writer.WriteStartObject();
				writer.WritePropertyName("floatBits");
				uint num2 = (uint)num;
				writer.WriteValue(num2.ToString("X8", CultureInfo.InvariantCulture));
				writer.WriteEndObject();
			}
			else
			{
				writer.WriteValue((double)value);
			}
		}
	}
	internal static class CharacterJson
	{
		internal static JObject ReadProfile(string json)
		{
			return (JObject)ReadDocument(json)["profile"];
		}

		internal static JObject ReadDocument(string json)
		{
			if (json == null)
			{
				throw new ArgumentNullException("json");
			}
			if ((long)json.Length > 268435456L)
			{
				throw new InvalidDataException("JSON is too large.");
			}
			JObject jObject;
			using (JsonTextReader jsonTextReader = new JsonTextReader(new StringReader(json))
			{
				DateParseHandling = DateParseHandling.None,
				MaxDepth = 64
			})
			{
				jObject = JObject.Load(jsonTextReader, new JsonLoadSettings
				{
					DuplicatePropertyNameHandling = DuplicatePropertyNameHandling.Error
				});
				if (jsonTextReader.Read())
				{
					throw new InvalidDataException("Trailing JSON content.");
				}
			}
			if ((string?)jObject["format"] != "Landoria.ServerShield.character" || (int?)jObject["schemaVersion"] != 1)
			{
				throw new InvalidDataException("Unsupported JSON format.");
			}
			if (!(jObject["profile"] is JObject))
			{
				throw new InvalidDataException("Missing profile.");
			}
			return jObject;
		}

		internal static void Validate(string json)
		{
			ValidateProfile(ReadProfile(json));
		}

		internal static void ValidateProfile(JObject profile)
		{
			using BinaryJson binaryJson = new BinaryJson();
			CharacterSchema.Profile(binaryJson, profile);
			binaryJson.ValidateComplete(72);
		}
	}
	internal static class CharacterSchema
	{
		internal static void Profile(BinaryJson io, JObject obj)
		{
			io.Version(obj, 46);
			int stats = io.Int(obj, "statCount");
			io.List(obj, "statGroups", delegate(JObject group)
			{
				Stats(io, group, stats);
			});
			io.Bool(obj, "firstSpawn");
			io.List(obj, "worlds", delegate(JObject world)
			{
				World(io, world);
			});
			io.String(obj, "playerName");
			io.Long(obj, "playerId");
			io.String(obj, "startSeed");
			io.Bool(obj, "usedCheats");
			io.Long(obj, "dateCreated");
			if (io.Bool(obj, "hasPlayerData"))
			{
				io.Blob(obj, "playerData", Player);
			}
		}

		private static void Stats(BinaryJson io, JObject obj, int count)
		{
			if (count < 0 || count > 100000)
			{
				throw new InvalidDataException("Invalid stat count.");
			}
			io.List(obj, "values", delegate(JObject value)
			{
				io.Float(value, "value");
			}, shortCount: false, count);
			Floats(io, obj, "knownWorlds");
			Floats(io, obj, "knownWorldKeys");
			Floats(io, obj, "knownCommands");
			io.List(obj, "enemyStats", delegate(JObject group)
			{
				Floats(io, group, "values");
			});
			string[] array = new string[5] { "itemPickupStats", "itemCraftStats", "pickableStats", "foodEatenStats", "piecesPlacedStats" };
			foreach (string name in array)
			{
				Floats(io, obj, name);
			}
		}

		private static void World(BinaryJson io, JObject obj)
		{
			io.Long(obj, "worldId");
			io.Bool(obj, "haveCustomSpawnPoint");
			io.Vector(obj, "spawnPoint");
			io.Bool(obj, "haveLogoutPoint");
			io.Vector(obj, "logoutPoint");
			io.Bool(obj, "haveDeathPoint");
			io.Vector(obj, "deathPoint");
			io.Vector(obj, "homePoint");
			if (io.Bool(obj, "hasMapData"))
			{
				io.Blob(obj, "mapData");
			}
		}

		internal static void Player(BinaryJson io, JObject obj)
		{
			io.Version(obj, 33);
			string[] array = new string[4] { "maxHealth", "health", "maxStamina", "timeSinceDeath" };
			foreach (string name in array)
			{
				io.Float(obj, name);
			}
			io.String(obj, "guardianPower");
			io.Float(obj, "guardianPowerCooldown");
			io.Object(obj, "inventory", delegate(JObject inventory)
			{
				Inventory(io, inventory);
			});
			Strings(io, obj, "knownRecipes");
			io.List(obj, "knownStations", delegate(JObject entry)
			{
				io.String(entry, "key");
				io.Int(entry, "value");
			});
			array = new string[5] { "knownMaterial", "shownTutorials", "uniques", "trophies", "knownBiome" };
			foreach (string name2 in array)
			{
				Strings(io, obj, name2);
			}
			Pairs(io, obj, "knownTexts");
			io.String(obj, "beardItem");
			io.String(obj, "hairItem");
			io.Vector(obj, "skinColor");
			io.Vector(obj, "hairColor");
			io.Int(obj, "modelIndex");
			io.List(obj, "foods", delegate(JObject food)
			{
				io.String(food, "name");
				io.Float(food, "time");
			});
			io.Object(obj, "skills", delegate(JObject skills)
			{
				Skills(io, skills);
			});
			Pairs(io, obj, "customData");
			array = new string[3] { "stamina", "maxEitr", "eitr" };
			foreach (string name3 in array)
			{
				io.Float(obj, name3);
			}
			io.Blob(obj, "buildUi");
		}

		internal static void Inventory(BinaryJson io, JObject obj)
		{
			io.Version(obj, 109);
			io.List(obj, "items", delegate(JObject item)
			{
				Item(io, item);
			}, shortCount: true);
		}

		internal static void Item(BinaryJson io, JObject obj)
		{
			io.Int(obj, "durabilityHundredths");
			io.Byte(obj, "slotX");
			io.Byte(obj, "slotY");
			io.Byte(obj, "worldLevel");
			byte num = io.Byte(obj, "flags");
			if ((num & 4) != 0)
			{
				io.UShort(obj, "quality");
			}
			if ((num & 8) != 0)
			{
				io.UShort(obj, "quantity");
			}
			if ((num & 0x10) != 0)
			{
				io.Int(obj, "variant");
			}
			if ((num & 0x20) != 0)
			{
				io.Long(obj, "crafterId");
				io.String(obj, "crafterName");
			}
			if ((num & 0x40) != 0)
			{
				io.Int(obj, "prefabHash");
			}
			if ((num & 0x80) != 0)
			{
				if (io.Writing)
				{
					obj["customDataCount"] = ((JArray)BinaryJson.Required(obj, "customData")).Count;
				}
				int fixedCount = io.CompactCount(obj, "customDataCount");
				io.List(obj, "customData", delegate(JObject entry)
				{
					io.String(entry, "key");
					io.String(entry, "value");
				}, shortCount: false, fixedCount);
			}
			io.Byte(obj, "extraFlags");
		}

		internal static void Skills(BinaryJson io, JObject obj)
		{
			io.Version(obj, 2);
			io.List(obj, "values", delegate(JObject skill)
			{
				io.Int(skill, "type");
				io.Float(skill, "level");
				io.Float(skill, "accumulator");
			});
		}

		private static void Strings(BinaryJson io, JObject obj, string name)
		{
			io.List(obj, name, delegate(JObject entry)
			{
				io.String(entry, "value");
			});
		}

		private static void Floats(BinaryJson io, JObject obj, string name)
		{
			io.List(obj, name, delegate(JObject entry)
			{
				io.String(entry, "key");
				io.Float(entry, "value");
			});
		}

		private static void Pairs(BinaryJson io, JObject obj, string name)
		{
			io.List(obj, name, delegate(JObject entry)
			{
				io.String(entry, "key");
				io.String(entry, "value");
			});
		}
	}
	public static class FchJsonConverter
	{
		public static string ToJson(byte[] fch)
		{
			if (fch == null)
			{
				throw new ArgumentNullException("fch");
			}
			JObject jObject = new JObject();
			using (BinaryJson binaryJson = new BinaryJson(fch))
			{
				binaryJson.Blob(jObject, "payload");
				binaryJson.Blob(jObject, "hash");
				binaryJson.Finish();
			}
			byte[] array = Convert.FromBase64String((string?)jObject["payload"]);
			using (SHA512 sHA = SHA512.Create())
			{
				if (!sHA.ComputeHash(array).SequenceEqual(Convert.FromBase64String((string?)jObject["hash"])))
				{
					throw new InvalidDataException("Character SHA-512 checksum does not match.");
				}
			}
			JObject jObject2 = new JObject();
			using (BinaryJson binaryJson2 = new BinaryJson(array))
			{
				CharacterSchema.Profile(binaryJson2, jObject2);
				binaryJson2.Finish();
			}
			return JsonTemplate.Object(FormattableStringFactory.Create("{{\n    \"format\": {0},\n    \"schemaVersion\": {1},\n    \"profile\": {2}\n}}", "Landoria.ServerShield.character", 1, jObject2)).ToString(Formatting.Indented);
		}

		public static byte[] FromJson(string json)
		{
			JObject obj = CharacterJson.ReadProfile(json);
			byte[] array;
			using (BinaryJson binaryJson = new BinaryJson())
			{
				CharacterSchema.Profile(binaryJson, obj);
				array = binaryJson.Finish();
			}
			JObject jObject = JsonTemplate.Object($"{{\n    \"payload\": {Convert.ToBase64String(array)}\n}}");
			using (SHA512 sHA = SHA512.Create())
			{
				jObject["hash"] = Convert.ToBase64String(sHA.ComputeHash(array));
			}
			using BinaryJson binaryJson2 = new BinaryJson();
			binaryJson2.Blob(jObject, "payload");
			binaryJson2.Blob(jObject, "hash");
			return binaryJson2.Finish();
		}
	}
	internal static class JsonTemplate
	{
		internal static JObject Object(FormattableString template)
		{
			object[] arguments = template.GetArguments();
			object[] array = new object[arguments.Length];
			for (int i = 0; i < arguments.Length; i++)
			{
				array[i] = Serialize(arguments[i]);
			}
			using JsonTextReader jsonTextReader = new JsonTextReader(new StringReader(string.Format(CultureInfo.InvariantCulture, template.Format, array)));
			jsonTextReader.DateParseHandling = DateParseHandling.None;
			jsonTextReader.MaxDepth = null;
			return JObject.Load(jsonTextReader);
		}

		private static string Serialize(object value)
		{
			using StringWriter stringWriter = new StringWriter(CultureInfo.InvariantCulture);
			using JsonTextWriter jsonWriter = new JsonTextWriter(stringWriter);
			JsonSerializer.Create(new JsonSerializerSettings
			{
				Culture = CultureInfo.InvariantCulture,
				FloatFormatHandling = FloatFormatHandling.Symbol
			}).Serialize(jsonWriter, value);
			return stringWriter.ToString();
		}
	}
	internal static class WireJson
	{
		internal static T Read<T>(string json) where T : class
		{
			using JsonTextReader jsonTextReader = new JsonTextReader(new StringReader(json));
			jsonTextReader.DateParseHandling = DateParseHandling.None;
			jsonTextReader.MaxDepth = 64;
			return Serializer().Deserialize<T>(jsonTextReader) ?? throw new InvalidDataException("Missing JSON object.");
		}

		internal static string Write(object value)
		{
			using StringWriter stringWriter = new StringWriter(CultureInfo.InvariantCulture);
			using JsonTextWriter jsonWriter = new JsonTextWriter(stringWriter);
			Serializer().Serialize(jsonWriter, value);
			return stringWriter.ToString();
		}

		private static JsonSerializer Serializer()
		{
			JsonSerializer jsonSerializer = JsonSerializer.Create(new JsonSerializerSettings
			{
				Culture = CultureInfo.InvariantCulture,
				DateParseHandling = DateParseHandling.None,
				CheckAdditionalContent = true,
				TypeNameHandling = TypeNameHandling.None,
				FloatFormatHandling = FloatFormatHandling.Symbol
			});
			jsonSerializer.Converters.Add(new StrictPrimitiveConverter());
			jsonSerializer.Converters.Add(new StringEnumConverter
			{
				AllowIntegerValues = false
			});
			return jsonSerializer;
		}
	}
	internal sealed class StrictPrimitiveConverter : JsonConverter
	{
		public override bool CanWrite => false;

		public override bool CanConvert(Type type)
		{
			type = Nullable.GetUnderlyingType(type) ?? type;
			if (!(type == typeof(string)) && !(type == typeof(bool)) && !(type == typeof(int)) && !(type == typeof(uint)) && !(type == typeof(float)))
			{
				return type == typeof(double);
			}
			return true;
		}

		public override object ReadJson(JsonReader reader, Type type, object existingValue, JsonSerializer serializer)
		{
			Type underlyingType = Nullable.GetUnderlyingType(type);
			if (reader.TokenType == JsonToken.Null && (underlyingType != null || type == typeof(string)))
			{
				return null;
			}
			type = underlyingType ?? type;
			bool num;
			if (!(type == typeof(string)))
			{
				if (!(type == typeof(bool)))
				{
					if (reader.TokenType == JsonToken.Integer)
					{
						goto IL_00c6;
					}
					if (!(type == typeof(float)) && !(type == typeof(double)))
					{
						goto IL_00b0;
					}
					num = reader.TokenType == JsonToken.Float;
				}
				else
				{
					num = reader.TokenType == JsonToken.Boolean;
				}
			}
			else
			{
				num = reader.TokenType == JsonToken.String;
			}
			if (!num)
			{
				goto IL_00b0;
			}
			goto IL_00c6;
			IL_00b0:
			throw new JsonSerializationException("Unexpected JSON value at " + reader.Path);
			IL_00c6:
			return Convert.ChangeType(reader.Value, type, CultureInfo.InvariantCulture);
		}

		public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
		{
			throw new NotSupportedException();
		}
	}
}
namespace Landoria.ServerShield.Shared.Network
{
	internal static class ActionRejectionLog
	{
		private static readonly Dictionary<string, long> counts = new Dictionary<string, long>();

		private static readonly Stopwatch clock = Stopwatch.StartNew();

		private static double nextFlush;

		internal static bool Record(string action, string reason)
		{
			string text = "action=" + action + " reason=" + reason;
			if (counts.TryGetValue(text, out var value))
			{
				counts[text] = value + 1;
			}
			else
			{
				counts.Add(text, 0L);
				NetworkLog.Log.LogDebug("ActionRejected " + text + " count=1");
			}
			return false;
		}

		internal static void Tick()
		{
			if (!(clock.Elapsed.TotalSeconds < nextFlush))
			{
				Flush();
				nextFlush = clock.Elapsed.TotalSeconds + 5.0;
			}
		}

		internal static void Flush()
		{
			foreach (KeyValuePair<string, long> count in counts)
			{
				if (count.Value > 0)
				{
					NetworkLog.Log.LogDebug("ActionRejected " + count.Key + " " + $"count={count.Value} repeated=true");
				}
			}
			counts.Clear();
		}
	}
	internal static class BuildTrace
	{
		internal static string Resources(Piece piece, Inventory inventory)
		{
			return Resources(piece?.m_resources, inventory);
		}

		internal static string Resources(Requirement[] requirements, Inventory inventory, int quality = 0, int multiplier = 1)
		{
			if (requirements == null || inventory == null)
			{
				return "unavailable";
			}
			return string.Join(",", from value in requirements
				where (Object)(object)value.m_resItem != (Object)null
				select ((Object)value.m_resItem).name + ":" + $"{inventory.CountItems(value.m_resItem.m_itemData.m_shared.m_name, -1, true)}" + $"/cost={value.GetAmount(quality) * multiplier}");
		}

		internal static Piece Piece(int prefab)
		{
			ZNetScene instance = ZNetScene.instance;
			if (instance == null)
			{
				return null;
			}
			GameObject prefab2 = instance.GetPrefab(prefab);
			if (prefab2 == null)
			{
				return null;
			}
			return prefab2.GetComponent<Piece>();
		}
	}
	internal sealed class FoodSnapshot
	{
		internal ZDOID Character;

		internal float Health;

		internal float Maximum;

		internal float Stamina;

		internal float Eitr;

		internal List<Food> Foods = new List<Food>();

		internal static FoodSnapshot Capture(Player player)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			return new FoodSnapshot
			{
				Character = ((Character)player).GetZDOID(),
				Health = ((Character)player).GetHealth(),
				Maximum = ((Character)player).GetMaxHealth(),
				Stamina = ((Character)player).GetMaxStamina(),
				Eitr = ((Character)player).GetMaxEitr(),
				Foods = player.GetFoods().Select(Clone).ToList()
			};
		}

		private static Food Clone(Food food)
		{
			//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_0011: 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_0029: 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)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Expected O, but got Unknown
			return new Food
			{
				m_name = food.m_name,
				m_item = food.m_item,
				m_time = food.m_time,
				m_health = food.m_health,
				m_stamina = food.m_stamina,
				m_eitr = food.m_eitr
			};
		}

		internal void Apply(Player player, bool flash)
		{
			player.GetFoods().Clear();
			player.GetFoods().AddRange(Foods.Select(Clone));
			player.SetMaxHealth(Maximum, flash);
			((Character)player).SetHealth(Health);
			player.SetMaxStamina(Stamina, flash);
			NativeFood.SetMaxEitr(player, Eitr, flash);
		}

		internal ZPackage Write()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			ZPackage val = new ZPackage();
			val.Write(Character);
			val.Write(Health);
			val.Write(Maximum);
			val.Write(Stamina);
			val.Write(Eitr);
			val.Write(Foods.Count);
			foreach (Food food in Foods)
			{
				val.Write(food.m_name);
				val.Write(food.m_time);
				val.Write(food.m_health);
				val.Write(food.m_stamina);
				val.Write(food.m_eitr);
			}
			return val;
		}

		internal static FoodSnapshot Read(ZPackage package)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			FoodSnapshot foodSnapshot = new FoodSnapshot
			{
				Character = package.ReadZDOID(),
				Health = Number(package),
				Maximum = Number(package),
				Stamina = Number(package),
				Eitr = Number(package)
			};
			int num = package.ReadInt();
			if (((ZDOID)(ref foodSnapshot.Character)).IsNone() || foodSnapshot.Maximum <= 0f || foodSnapshot.Health > foodSnapshot.Maximum || foodSnapshot.Stamina <= 0f || num < 0 || num > 3)
			{
				throw new InvalidDataException("Invalid food snapshot.");
			}
			for (int i = 0; i < num; i++)
			{
				Food val = Resolve(package.ReadString(), Number(package));
				val.m_health = Number(package);
				val.m_stamina = Number(package);
				val.m_eitr = Number(package);
				foodSnapshot.Foods.Add(val);
			}
			if (package.GetPos() != package.Size() || foodSnapshot.Foods.Select((Food food) => food.m_name).Distinct().Count() != num)
			{
				throw new InvalidDataException("Invalid food snapshot contents.");
			}
			return foodSnapshot;
		}

		private static float Number(ZPackage package)
		{
			float num = package.ReadSingle();
			if (float.IsNaN(num) || float.IsInfinity(num) || num < 0f)
			{
				throw new InvalidDataException("Invalid food value.");
			}
			return num;
		}

		internal static Food Resolve(string name, float time)
		{
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Expected O, but got Unknown
			GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(name);
			ItemData val = (((Object)(object)itemPrefab == (Object)null) ? null : itemPrefab.GetComponent<ItemDrop>()?.m_itemData);
			if (val == null || val.m_shared.m_food <= 0f || float.IsNaN(time) || float.IsInfinity(time) || time < 0f)
			{
				throw new InvalidDataException("Unknown or invalid saved food.");
			}
			return new Food
			{
				m_name = name,
				m_item = val,
				m_time = time,
				m_health = val.m_shared.m_food,
				m_stamina = val.m_shared.m_foodStamina,
				m_eitr = val.m_shared.m_foodEitr
			};
		}

		internal static List<CharacterFood> Saved(Player player)
		{
			return (from food in player.GetFoods()
				select new CharacterFood
				{
					Name = food.m_name,
					Time = food.m_time
				}).ToList();
		}
	}
	[HarmonyPatch]
	internal static class InventorySnapshot
	{
		internal static void Apply(Player player, ZPackage package)
		{
			//IL_0019: 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)
			Inventory inventory = ((Humanoid)player).GetInventory();
			Inventory val = new Inventory("Server snapshot", (Sprite)null, inventory.GetWidth(), inventory.GetHeight());
			val.Load(package);
			List<ItemData> list = inventory.GetAllItems().ToList();
			List<ItemData> allItems = val.GetAllItems();
			Dictionary<ItemData, ItemData> dictionary = new Dictionary<ItemData, ItemData>();
			foreach (ItemData item in allItems)
			{
				Match(item, list, dictionary, sameSlot: true);
			}
			foreach (ItemData item2 in allItems)
			{
				if (!dictionary.ContainsKey(item2))
				{
					Match(item2, list, dictionary, sameSlot: false);
				}
			}
			foreach (ItemData item3 in list)
			{
				((Humanoid)player).UnequipItem(item3, false);
			}
			List<ItemData> collection = Reconcile(player, allItems, dictionary);
			inventory.GetAllItems().Clear();
			inventory.GetAllItems().AddRange(collection);
			NotifyChanged(inventory, success: false, cheatedStateChanged: false);
		}

		private static List<ItemData> Reconcile(Player player, List<ItemData> incoming, Dictionary<ItemData, ItemData> matches)
		{
			List<ItemData> list = new List<ItemData>();
			foreach (ItemData item in incoming)
			{
				if (!matches.TryGetValue(item, out var value))
				{
					item.m_equipped = false;
					value = item;
				}
				else
				{
					CopyState(value, item);
				}
				if (value.m_shared.m_useDurability && value.m_durability <= 0f)
				{
					((Humanoid)player).UnequipItem(value, false);
				}
				list.Add(value);
			}
			return list;
		}

		private static void Match(ItemData incoming, List<ItemData> available, Dictionary<ItemData, ItemData> matches, bool sameSlot)
		{
			ItemData val = ((IEnumerable<ItemData>)available).FirstOrDefault((Func<ItemData, bool>)((ItemData item) => SameItem(item, incoming) && (!sameSlot || ((Vector2i)(ref item.m_gridPos)).Equals(incoming.m_gridPos))));
			if (val != null)
			{
				available.Remove(val);
				matches.Add(incoming, val);
			}
		}

		private static bool SameItem(ItemData left, ItemData right)
		{
			string value;
			if ((Object)(object)left.m_dropPrefab == (Object)(object)right.m_dropPrefab && left.m_quality == right.m_quality && left.m_variant == right.m_variant && left.m_worldLevel == right.m_worldLevel && left.m_crafterID == right.m_crafterID && left.m_crafterName == right.m_crafterName && left.m_customData.Count == right.m_customData.Count)
			{
				return left.m_customData.All((KeyValuePair<string, string> pair) => right.m_customData.TryGetValue(pair.Key, out value) && value == pair.Value);
			}
			return false;
		}

		private static void CopyState(ItemData current, ItemData incoming)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			current.m_stack = incoming.m_stack;
			current.m_durability = incoming.m_durability;
			current.m_gridPos = incoming.m_gridPos;
			current.m_pickedUp = incoming.m_pickedUp;
			current.m_cheated = incoming.m_cheated;
		}

		[HarmonyReversePatch(/*Could not decode attribute arguments.*/)]
		[HarmonyPatch(typeof(Inventory), "Changed")]
		private static void NotifyChanged(Inventory instance, bool success, bool cheatedStateChanged)
		{
			throw new NotImplementedException("Native inventory notification was not patched.");
		}
	}
	[HarmonyPatch]
	internal static class NativeFood
	{
		[HarmonyReversePatch(/*Could not decode attribute arguments.*/)]
		[HarmonyPatch(typeof(Player), "UpdateFood")]
		internal static void Update(Player player, float dt, bool forceUpdate)
		{
			throw new NotImplementedException("Native food update was not patched.");
		}

		[HarmonyReversePatch(/*Could not decode attribute arguments.*/)]
		[HarmonyPatch(typeof(Player), "SetMaxEitr")]
		internal static void SetMaxEitr(Player player, float eitr, bool flashBar)
		{
			throw new NotImplementedException("Native food eitr was not patched.");
		}

		[HarmonyReversePatch(/*Could not decode attribute arguments.*/)]
		[HarmonyPatch(typeof(Humanoid), "SetUseHandVisual")]
		internal static void ShowItem(Humanoid player, GameObject item, float seconds)
		{
			throw new NotImplementedException("Native food visual was not patched.");
		}
	}
	internal static class NetworkLog
	{
		internal static ModLog Log;
	}
	internal static class ObjectTraceLog
	{
		private static readonly HashSet<string> seen = new HashSet<string>();

		private static readonly Queue<string> order = new Queue<string>();

		private static readonly Stopwatch clock = Stopwatch.StartNew();

		private static double window;

		private static int count;

		private static long suppressed;

		internal static bool IsCreature(int hash)
		{
			ZNetScene instance = ZNetScene.instance;
			GameObject val = ((instance != null) ? instance.GetPrefab(hash) : null);
			if ((Object)(object)val != (Object)null && (Object)(object)val.GetComponent<Character>() != (Object)null)
			{
				return (Object)(object)val.GetComponent<Player>() == (Object)null;
			}
			return false;
		}

		internal unsafe static void Write(string stage, ZDOID id, int hash, string details)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			ZDOID val = id;
			string item = stage + "/" + ((object)(*(ZDOID*)(&val))/*cast due to .constrained prefix*/).ToString();
			if (!seen.Add(item))
			{
				return;
			}
			order.Enqueue(item);
			if (order.Count > 4096)
			{
				seen.Remove(order.Dequeue());
			}
			if (CanWrite())
			{
				ZNetScene instance = ZNetScene.instance;
				object obj;
				if (instance == null)
				{
					obj = null;
				}
				else
				{
					GameObject prefab = instance.GetPrefab(hash);
					obj = ((prefab != null) ? ((Object)prefab).name : null);
				}
				if (obj == null)
				{
					obj = "unknown";
				}
				string arg = (string)obj;
				NetworkLog.Log.LogDebug($"ObjectTrace stage={stage} object={id} " + $"prefab={arg} prefabHash={hash} {details}");
			}
		}

		private static bool CanWrite()
		{
			double totalSeconds = clock.Elapsed.TotalSeconds;
			if (totalSeconds - window >= 5.0)
			{
				if (suppressed > 0)
				{
					NetworkLog.Log.LogDebug($"ObjectTrace suppressed={suppressed}");
				}
				window = totalSeconds;
				count = 0;
				suppressed = 0L;
			}
			if (count >= 20)
			{
				suppressed++;
				return false;
			}
			count++;
			return true;
		}
	}
	[HarmonyPatch(typeof(ZPlayFabSocket), "ProcessAck")]
	internal static class PlayFabAckDiagnostics
	{
		private static void Prefix(ZPlayFabSocket __instance, uint msgId, InFlightQueue ___m_inFlightQueue, bool ___m_isClient)
		{
			if (__instance.IsConnected())
			{
				uint num = ___m_inFlightQueue.Head - ___m_inFlightQueue.Tail;
				if (msgId - ___m_inFlightQueue.Tail > num)
				{
					NetworkLog.Log.LogError($"PlayFab ACK outside the send window: ack={msgId}, " + $"tail={___m_inFlightQueue.Tail}, head={___m_inFlightQueue.Head}, " + "side=" + (___m_isClient ? "client" : "server") + ". Native processing will close the socket. Call stack: " + Environment.StackTrace);
				}
			}
		}
	}
	[HarmonyPatch(typeof(ZPlayFabSocket), "OnDataMessageReceived")]
	internal static class PlayFabEarlyCompression
	{
		private sealed class Report
		{
			internal bool Written;
		}

		private static readonly ConditionalWeakTable<ZPlayFabSocket, Report> reports = new ConditionalWeakTable<ZPlayFabSocket, Report>();

		private static bool Prefix(ZPlayFabSocket __instance, PlayFabPlayer from, byte[] compressedBuffer, bool ___m_isClient, bool ___m_useCompression, PlayFabZLibWorkQueue ___m_zlibWorkQueue)
		{
			if (___m_useCompression || ((from == null) ? null : from.EntityKey?.Id) != __instance.m_remotePlayerId || !IsEarlyCompressedBuffer(compressedBuffer))
			{
				return true;
			}
			Report orCreateValue = reports.GetOrCreateValue(__instance);
			if (!orCreateValue.Written)
			{
				orCreateValue.Written = true;
				NetworkLog.Log.LogWarning("PlayFab compressed buffer arrived before VersionMatch; selective decompression enabled for early buffers, side=" + (___m_isClient ? "client" : "server") + ". Reported once per socket.");
			}
			___m_zlibWorkQueue.Decompress(compressedBuffer);
			return false;
		}

		private static bool IsEarlyCompressedBuffer(byte[] buffer)
		{
			if (buffer == null || buffer.Length <= 5)
			{
				return false;
			}
			int num = (buffer[0] << 8) | buffer[1];
			if ((buffer[0] & 0xF) == 8)
			{
				return num % 31 == 0;
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(ZPlayFabSocket), "LateUpdateAllSocket")]
	internal static class PlayFabSocketUpdate
	{
		private static bool Prefix(Dictionary<string, ZPlayFabSocket> ___s_connectSockets)
		{
			KeyValuePair<string, ZPlayFabSocket>[] array = ___s_connectSockets.ToArray();
			for (int i = 0; i < array.Length; i++)
			{
				KeyValuePair<string, ZPlayFabSocket> keyValuePair = array[i];
				if (___s_connectSockets.TryGetValue(keyValuePair.Key, out var value) && value == keyValuePair.Value)
				{
					try
					{
						UpdateSocket(value);
					}
					catch (Exception message)
					{
						NetworkLog.Log.LogError(message);
					}
				}
			}
			return false;
		}

		[HarmonyReversePatch(/*Could not decode attribute arguments.*/)]
		[HarmonyPatch(typeof(ZPlayFabSocket), "LateUpdate")]
		private static void UpdateSocket(ZPlayFabSocket instance)
		{
			throw new NotImplementedException("Native PlayFab socket update was not patched.");
		}
	}
	[HarmonyPatch]
	internal static class TerrainCompilerLifecycle
	{
		private static readonly HashSet<TerrainComp> waiting = new HashSet<TerrainComp>();

		[HarmonyPrefix]
		[HarmonyPatch(typeof(TerrainComp), "Awake")]
		private static bool BeforeAwake(TerrainComp __instance)
		{
			if (CanInitialize(__instance))
			{
				return true;
			}
			((Behaviour)__instance).enabled = false;
			waiting.Add(__instance);
			return false;
		}

		private static bool CanInitialize(TerrainComp compiler)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			Vector3 position = ((Component)compiler).transform.position;
			if ((Object)(object)Heightmap.FindHeightmap(position) != (Object)null)
			{
				return (Object)(object)TerrainComp.FindTerrainCompiler(position) == (Object)null;
			}
			return false;
		}

		internal static void Tick()
		{
			if (waiting.Count == 0)
			{
				return;
			}
			foreach (TerrainComp item in new List<TerrainComp>(waiting))
			{
				if ((Object)(object)item == (Object)null)
				{
					waiting.Remove(item);
					continue;
				}
				ZNetView component = ((Component)item).GetComponent<ZNetView>();
				if (!((Object)(object)component == (Object)null) && component.IsValid() && CanInitialize(item))
				{
					waiting.Remove(item);
					try
					{
						AwakeNative(item);
						((Behaviour)item).enabled = true;
					}
					catch (Exception message)
					{
						NetworkLog.Log.LogError(message);
					}
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(TerrainComp), "OnDestroy")]
		private static void AfterDestroy(TerrainComp __instance)
		{
			waiting.Remove(__instance);
		}

		[HarmonyReversePatch(/*Could not decode attribute arguments.*/)]
		[HarmonyPatch(typeof(TerrainComp), "Awake")]
		private static void AwakeNative(TerrainComp instance)
		{
			throw new NotSupportedException("Native terrain awake was not patched.");
		}
	}
	[HarmonyPatch]
	internal static class TerrainCompilerReuse
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(Heightmap), "GetAndCreateTerrainCompiler")]
		private static bool Prefix(Heightmap __instance, GameObject ___m_terrainCompilerPrefab, ref TerrainComp __result)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: 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_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			Vector3 position = ((Component)__instance).transform.position;
			if ((Object)(object)TerrainComp.FindTerrainCompiler(position) != (Object)null)
			{
				return true;
			}
			int stableHashCode = StringExtensionMethods.GetStableHashCode(((Object)___m_terrainCompilerPrefab).name);
			List<ZDO> list = new List<ZDO>();
			ZDOMan.instance.FindSectorObjects(ZoneSystem.GetZone(position), new SimulationDistance(0, 0, false), list, (List<ZDO>)null);
			foreach (ZDO item in list)
			{
				if (item.GetPrefab() == stableHashCode && !(item.GetPosition() != position))
				{
					ZNetView val = ZNetScene.instance.FindInstance(item);
					GameObject val2 = (((Object)(object)val == (Object)null) ? CreateNative(ZNetScene.instance, item) : ((Component)val).gameObject);
					TerrainCompilerLifecycle.Tick();
					__result = val2.GetComponent<TerrainComp>();
					if (!((Behaviour)__result).enabled)
					{
						throw new InvalidOperationException("Terrain is not ready.");
					}
					return false;
				}
			}
			return true;
		}

		[HarmonyReversePatch(/*Could not decode attribute arguments.*/)]
		[HarmonyPatch(typeof(ZNetScene), "CreateObject")]
		private static GameObject CreateNative(ZNetScene instance, ZDO zdo)
		{
			throw new NotSupportedException("Native terrain creation was not patched.");
		}
	}
	[HarmonyPatch(typeof(TerrainComp), "Awake")]
	internal static class TerrainCompilerTrace
	{
		private static readonly HashSet<string> reported = new HashSet<string>();

		private static ZNetScene scene;

		private static void Prefix(TerrainComp __instance)
		{
			try
			{
				Inspect(__instance);
			}
			catch (Exception message)
			{
				NetworkLog.Log.LogError(message);
			}
		}

		private static void Inspect(TerrainComp compiler)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)scene != (Object)(object)ZNetScene.instance)
			{
				scene = ZNetScene.instance;
				reported.Clear();
			}
			if (reported.Count >= 64)
			{
				return;
			}
			Vector3 position = ((Component)compiler).transform.position;
			TerrainComp val = TerrainComp.FindTerrainCompiler(position);
			bool flag = (Object)(object)Heightmap.FindHeightmap(position) != (Object)null;
			if (!((Object)(object)val == (Object)(object)compiler) && !((Object)(object)val == (Object)null && flag))
			{
				ZNetView component = ((Component)compiler).GetComponent<ZNetView>();
				ZDO val2 = ((component != null) ? component.GetZDO() : null);
				object obj;
				if (val == null)
				{
					obj = null;
				}
				else
				{
					ZNetView component2 = ((Component)val).GetComponent<ZNetView>();
					obj = ((component2 != null) ? component2.GetZDO() : null);
				}
				ZDO val3 = (ZDO)obj;
				string item = $"{val2?.m_uid}/{val3?.m_uid}/{flag}";
				if (reported.Add(item))
				{
					Report(compiler, val, val2, val3, flag);
				}
			}
		}

		private static void Report(TerrainComp compiler, TerrainComp existing, ZDO incoming, ZDO previous, bool heightmap)
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			string text = (((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer()) ? "server" : "client");
			NetworkLog.Log.LogWarning("TerrainCompilerTrace side=" + text + $" heightmap={heightmap} position={((Component)compiler).transform.position}" + $" existingPosition={((existing != null) ? new Vector3?(((Component)existing).transform.position) : ((Vector3?)null))}" + " incoming=[" + Describe(incoming) + "] previous=[" + Describe(previous) + "]");
		}

		private static string Describe(ZDO zdo)
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			if (zdo == null)
			{
				return "no_zdo";
			}
			byte[] byteArray = zdo.GetByteArray(ZDOVars.s_TCData, (byte[])null);
			string text = "absent";
			if (byteArray != null)
			{
				using SHA256 sHA = SHA256.Create();
				text = BitConverter.ToString(sHA.ComputeHash(byteArray)).Replace("-", "");
			}
			return $"id={zdo.m_uid} owner={zdo.GetOwner()} revision={zdo.DataRevision}" + $" position={zdo.GetPosition()} bytes={((byteArray != null) ? byteArray.Length : 0)}" + " sha256=" + text;
		}
	}
}
namespace Landoria.ServerShield.Shared.Models
{
	[JsonObject(MemberSerialization.OptIn)]
	internal sealed class BuildRay
	{
		[JsonProperty("x", Required = Required.Always)]
		public float X { get; set; }

		[JsonProperty("y", Required = Required.Always)]
		public float Y { get; set; }

		[JsonProperty("z", Required = Required.Always)]
		public float Z { get; set; }

		[JsonProperty("dx", Required = Required.Always)]
		public float DX { get; set; }

		[JsonProperty("dy", Required = Required.Always)]
		public float DY { get; set; }

		[JsonProperty("dz", Required = Required.Always)]
		public float DZ { get; set; }
	}
	[JsonObject(MemberSerialization.OptIn)]
	internal sealed class Character : CharacterData
	{
		[JsonProperty("format", NullValueHandling = NullValueHandling.Ignore)]
		public string Format { get; set; }

		[JsonProperty("schemaVersion", NullValueHandling = NullValueHandling.Ignore)]
		public int SchemaVersion { get; set; }

		[JsonProperty("profile", NullValueHandling = NullValueHandling.Ignore)]
		public CharacterProfile Profile { get; set; }

		[JsonProperty("lastTombstoneCharacter", NullValueHandling = NullValueHandling.Ignore)]
		public string LastTombstoneCharacter { get; set; }
	}
	[JsonObject(MemberSerialization.OptIn)]
	internal sealed class CharacterProfile : CharacterData
	{
		[JsonProperty("version", NullValueHandling = NullValueHandling.Ignore)]
		public int Version { get; set; }

		[JsonProperty("statCount", NullValueHandling = NullValueHandling.Ignore)]
		public int StatCount { get; set; }

		[JsonProperty("statGroups", NullValueHandling = NullValueHandling.Ignore)]
		public List<CharacterStats> StatGroups { get; set; }

		[JsonProperty("firstSpawn", NullValueHandling = NullValueHandling.Ignore)]
		public bool FirstSpawn { get; set; }

		[JsonProperty("worlds", NullValueHandling = NullValueHandling.Ignore)]
		public List<CharacterWorld> Worlds { get; set; }

		[JsonProperty("playerName", NullValueHandling = NullValueHandling.Ignore)]
		public string PlayerName { get; set; }

		[JsonProperty("playerId", NullValueHandling = NullValueHandling.Ignore)]
		public string PlayerId { get; set; }

		[JsonProperty("startSeed", NullValueHandling = NullValueHandling.Ignore)]
		public string StartSeed { get; set; }

		[JsonProperty("usedCheats", NullValueHandling = NullValueHandling.Ignore)]
		public bool UsedCheats { get; set; }

		[JsonProperty("dateCreated", NullValueHandling = NullValueHandling.Ignore)]
		public string DateCreated { get; set; }

		[JsonProperty("hasPlayerData", NullValueHandling = NullValueHandling.Ignore)]
		public bool HasPlayerData { get; set; }

		[JsonProperty("playerData", NullValueHandling = NullValueHandling.Ignore)]
		public CharacterPlayerData PlayerData { get; set; }
	}
	[JsonObject(MemberSerialization.OptIn)]
	internal sealed class CharacterWorld : CharacterData
	{
		[JsonProperty("worldId", NullValueHandling = NullValueHandling.Ignore)]
		public string WorldId { get; set; }

		[JsonProperty("haveCustomSpawnPoint", NullValueHandling = NullValueHandling.Ignore)]
		public bool HaveCustomSpawnPoint { get; set; }

		[JsonProperty("spawnPoint", NullValueHandling = NullValueHandling.Ignore)]
		public CharacterVector SpawnPoint { get; set; }

		[JsonProperty("haveLogoutPoint", NullValueHandling = NullValueHandling.Ignore)]
		public bool HaveLogoutPoint { get; set; }

		[JsonProperty("logoutPoint", NullValueHandling = NullValueHandling.Ignore)]
		public CharacterVector LogoutPoint { get; set; }

		[JsonProperty("haveDeathPoint", NullValueHandling = NullValueHandling.Ignore)]
		public bool HaveDeathPoint { get; set; }

		[JsonProperty("deathPoint", NullValueHandling = NullValueHandling.Ignore)]
		public CharacterVector DeathPoint { get; set; }

		[JsonProperty("homePoint", NullValueHandling = NullValueHandling.Ignore)]
		public CharacterVector HomePoint { get; set; }

		[JsonProperty("hasMapData", NullValueHandling = NullValueHandling.Ignore)]
		public bool HasMapData { get; set; }

		[JsonProperty("mapData", NullValueHandling = NullValueHandling.Ignore)]
		public string MapData { get; set; }

		[JsonProperty("mapPinIds", NullValueHandling = NullValueHandling.Ignore)]
		public List<string> MapPinIds { get; set; }
	}
	[JsonObject(MemberSerialization.OptIn)]
	internal sealed class CharacterPlayerData : CharacterData
	{
		[JsonProperty("version", NullValueHandling = NullValueHandling.Ignore)]
		public int Version { get; set; }

		[JsonProperty("maxHealth", NullValueHandling = NullValueHandling.Ignore)]
		public float MaxHealth { get; set; }

		[JsonProperty("health", NullValueHandling = NullValueHandling.Ignore)]
		public float Health { get; set; }

		[JsonProperty("maxStamina", NullValueHandling = NullValueHandling.Ignore)]
		public float MaxStamina { get; set; }

		[JsonProperty("timeSinceDeath", NullValueHandling = NullValueHandling.Ignore)]
		public float TimeSinceDeath { get; set; }

		[JsonProperty("guardianPower", NullValueHandling = NullValueHandling.Ignore)]
		public string GuardianPower { get; set; }

		[JsonProperty("guardianPowerCooldown", NullValueHandling = NullValueHandling.Ignore)]
		public float GuardianPowerCooldown { get; set; }

		[JsonProperty("inventory", NullValueHandling = NullValueHandling.Ignore)]
		public CharacterInventory Inventory { get; set; }

		[JsonProperty("knownRecipes", NullValueHandling = NullValueHandling.Ignore)]
		public List<CharacterString> KnownRecipes { get; set; }

		[JsonProperty("knownStations", NullValueHandling = NullValueHandling.Ignore)]
		public List<CharacterStation> KnownStations { get; set; }

		[JsonProperty("knownMaterial", NullValueHandling = NullValueHandling.Ignore)]
		public List<CharacterString> KnownMaterial { get; set; }

		[JsonProperty("shownTutorials", NullValueHandling = NullValueHandling.Ignore)]
		public List<CharacterString> ShownTutorials { get; set; }

		[JsonProperty("uniques", NullValueHandling = NullValueHandling.Ignore)]
		public List<CharacterString> Uniques { get; set; }

		[JsonProperty("trophies", NullValueHandling = NullValueHandling.Ignore)]
		public List<CharacterString> Trophies { get; set; }

		[JsonProperty("knownBiome", NullValueHandling = NullValueHandling.Ignore)]
		public List<CharacterString> KnownBiome { get; set; }

		[JsonProperty("knownTexts", NullValueHandling = NullValueHandling.Ignore)]
		public List<CharacterText> KnownTexts { get; set; }

		[JsonProperty("beardItem", NullValueHandling = NullValueHandling.Ignore)]
		public string BeardItem { get; set; }

		[JsonProperty("hairItem", NullValueHandling = NullValueHandling.Ignore)]
		public string HairItem { get; set; }

		[JsonProperty("skinColor", NullValueHandling = NullValueHandling.Ignore)]
		public CharacterVector SkinColor { get; set; }

		[JsonProperty("hairColor", NullValueHandling = NullValueHandling.Ignore)]
		public CharacterVector HairColor { get; set; }

		[JsonProperty("modelIndex", NullValueHandling = NullValueHandling.Ignore)]
		public int ModelIndex { get; set; }

		[JsonProperty("foods", NullValueHandling = NullValueHandling.Ignore)]
		public List<CharacterFood> Foods { get; set; }

		[JsonProperty("skills", NullValueHandling = NullValueHandling.Ignore)]
		public CharacterSkills Skills { get; set; }

		[JsonProperty("customData", NullValueHandling = NullValueHandling.Ignore)]
		public List<CharacterText> CustomData { get; set; }

		[JsonProperty("stamina", NullValueHandling = NullValueHandling.Ignore)]
		public float Stamina { get; set; }

		[JsonProperty("maxEitr", NullValueHandling = NullValueHandling.Ignore)]
		public float MaxEitr { get; set; }

		[JsonProperty("eitr", NullValueHandling = NullValueHandling.Ignore)]
		public float Eitr { get; set; }

		[JsonProperty("buildUi", NullValueHandling = NullValueHandling.Ignore)]
		public string BuildUi { get; set; }
	}
	[JsonObject(MemberSerialization.OptIn)]
	internal sealed class CharacterInventory : CharacterData
	{
		[JsonProperty("version", NullValueHandling = NullValueHandling.Ignore)]
		public int Version { get; set; }

		[JsonProperty("items", NullValueHandling = NullValueHandling.Ignore)]
		public List<CharacterItem> Items { get; set; }
	}
	[JsonObject(MemberSerialization.OptIn)]
	internal sealed class CharacterItem : CharacterData
	{
		[JsonProperty("durabilityHundredths", NullValueHandling = NullValueHandling.Ignore)]
		public int DurabilityHundredths { get; set; }

		[JsonProperty("slotX", NullValueHandling = NullValueHandling.Ignore)]
		public byte SlotX { get; set; }

		[JsonProperty("slotY", NullValueHandling = NullValueHandling.Ignore)]
		public byte SlotY { get; set; }

		[JsonProperty("worldLevel", NullValueHandling = NullValueHandling.Ignore)]
		public byte WorldLevel { get; set; }

		[JsonProperty("flags", NullValueHandling = NullValueHandling.Ignore)]
		public byte Flags { get; set; }

		[JsonProperty("quality", NullValueHandling = NullValueHandling.Ignore)]
		public ushort? Quality { get; set; }

		[JsonProperty("quantity", NullValueHandling = NullValueHandling.Ignore)]
		public ushort? Quantity { get; set; }

		[JsonProperty("variant", NullValueHandling = NullValueHandling.Ignore)]
		public int? Variant { get; set; }

		[JsonProperty("crafterId", NullValueHandling = NullValueHandling.Ignore)]
		public string CrafterId { get; set; }

		[JsonProperty("crafterName", NullValueHandling = NullValueHandling.Ignore)]
		public string CrafterName { get; set; }

		[JsonProperty("prefabHash", NullValueHandling = NullValueHandling.Ignore)]
		public int? PrefabHash { get; set; }

		[JsonProperty("customDataCount", NullValueHandling = NullValueHandling.Ignore)]
		public int? CustomDataCount { get; set; }

		[JsonProperty("customData", NullValueHandling = NullValueHandling.Ignore)]
		public List<CharacterText> CustomData { get; set; }

		[JsonProperty("extraFlags", NullValueHandling = NullValueHandling.Ignore)]
		public byte ExtraFlags { get; set; }
	}
	[JsonObject(MemberSerialization.OptIn)]
	internal sealed class CharacterVector : CharacterData
	{
		[JsonProperty("x", Required = Required.Always)]
		public float X { get; set; }

		[JsonProperty("y", Required = Required.Always)]
		public float Y { get; set; }

		[JsonProperty("z", Required = Required.Always)]
		public float Z { get; set; }
	}
	[JsonObject(MemberSerialization.OptIn)]
	internal sealed class CharacterString : CharacterData
	{
		[JsonProperty("value", NullValueHandling = NullValueHandling.Ignore)]
		public string Value { get; set; }
	}
	[JsonObject(MemberSerialization.OptIn)]
	internal sealed class CharacterText : CharacterData
	{
		[JsonProperty("key", NullValueHandling = NullValueHandling.Ignore)]
		public string Key { get; set; }

		[JsonProperty("value", NullValueHandling = NullValueHandling.Ignore)]
		public string Value { get; set; }
	}
	[JsonObject(MemberSerialization.OptIn)]
	internal sealed class CharacterStation : CharacterData
	{
		[JsonProperty("key", Required = Required.Always)]
		public string Key { get; set; }

		[JsonProperty("value", Required = Required.Always)]
		public int Value { get; set; }
	}
	[JsonObject(MemberSerialization.OptIn)]
	internal sealed class CharacterFood : CharacterData
	{
		[JsonProperty("name", NullValueHandling = NullValueHandling.Ignore)]
		public string Name { get; set; }

		[JsonProperty("time", NullValueHandling = NullValueHandling.Ignore)]
		public float Time { get; set; }
	}
	[JsonObject(MemberSerialization.OptIn)]
	internal sealed class CharacterSkills : CharacterData
	{
		[JsonProperty("version", NullValueHandling = NullValueHandling.Ignore)]
		public int Version { get; set; }

		[JsonProperty("values", NullValueHandling = NullValueHandling.Ignore)]
		public List<CharacterSkill> Values { get; set; }
	}
	[JsonObject(MemberSerialization.OptIn)]
	internal sealed class CharacterSkill : CharacterData
	{
		[JsonProperty("type", NullValueHandling = NullValueHandling.Ignore)]
		public int Type { get; set; }

		[JsonProperty("level", NullValueHandling = NullValueHandling.Ignore)]
		public float Level { get; set; }

		[JsonProperty("accumulator", NullValueHandling = NullValueHandling.Ignore)]
		public float Accumulator { get; set; }
	}
	[JsonObject(MemberSerialization.OptIn)]
	internal sealed class CharacterStats : CharacterData
	{
		[JsonProperty("values", NullValueHandling = NullValueHandling.Ignore)]
		public List<CharacterFloat> Values { get; set; }

		[JsonProperty("knownWorlds", NullValueHandling = NullValueHandling.Ignore)]
		public List<CharacterFloatPair> KnownWorlds { get; set; }

		[JsonProperty("knownWorldKeys", NullValueHandling = NullValueHandling.Ignore)]
		public List<CharacterFloatPair> KnownWorldKeys { get; set; }

		[JsonProperty("knownCommands", NullValueHandling = NullValueHandling.Ignore)]
		public List<CharacterFloatPair> KnownCommands { get; set; }

		[JsonProperty("enemyStats", NullValueHandling = NullValueHandling.Ignore)]
		public List<CharacterEnemyStats> EnemyStats { get; set; }

		[JsonProperty("itemPickupStats", NullValueHandling = NullValueHandling.Ignore)]
		public List<CharacterFloatPair> ItemPickupStats { get; set; }

		[JsonProperty("itemCraftStats", NullValueHandling = NullValueHandling.Ignore)]
		public List<CharacterFloatPair> ItemCraftStats { get; set; }

		[JsonProperty("pickableStats", NullValueHandling = NullValueHandling.Ignore)]
		public List<CharacterFloatPair> PickableStats { get; set; }

		[JsonProperty("foodEatenStats", NullValueHandling = NullValueHandling.Ignore)]
		public List<CharacterFloatPair> FoodEatenStats { get; set; }

		[JsonProperty("piecesPlacedStats", NullValueHandling = NullValueHandling.Ignore)]
		public List<CharacterFloatPair> PiecesPlacedStats { get; set; }
	}
	[JsonObject(MemberSerialization.OptIn)]
	internal sealed class CharacterFloat : CharacterData
	{
		[JsonProperty("value", NullValueHandling = NullValueHandling.Ignore)]
		public float Value { get; set; }
	}
	[JsonObject(MemberSerialization.OptIn)]
	internal sealed class CharacterFloatPair : CharacterData
	{
		[JsonProperty("key", NullValueHandling = NullValueHandling.Ignore)]
		public string Key { get; set; }

		[JsonProperty("value", NullValueHandling = NullValueHandling.Ignore)]
		public float Value { get; set; }
	}
	[JsonObject(MemberSerialization.OptIn)]
	internal sealed class CharacterEnemyStats : CharacterData
	{
		[JsonProperty("values", NullValueHandling = NullValueHandling.Ignore)]
		public List<CharacterFloatPair> Values { get; set; }
	}
	internal abstract class CharacterData
	{
		[JsonExtensionData]
		public IDictionary<string, JToken> AdditionalData { get; set; }
	}
	[JsonObject(MemberSerialization.OptIn)]
	internal sealed class CharacterAppearanceData : CharacterData
	{
		[JsonProperty("modelIndex", Required = Required.Always)]
		public int ModelIndex { get; set; }

		[JsonProperty("beardItem", Required = Required.Always)]
		public string BeardItem { get; set; }

		[JsonProperty("hairItem", Required = Required.Always)]
		public string HairItem { get; set; }

		[JsonProperty("skinColor", Required = Required.Always)]
		public CharacterVector SkinColor { get; set; }

		[JsonProperty("hairColor", Required = Required.Always)]
		public CharacterVector HairColor { get; set; }
	}
	[JsonObject(MemberSerialization.OptIn)]
	internal sealed class CharacterDiscoveries : CharacterData
	{
		[JsonProperty("knownRecipes", Required = Required.Always)]
		public List<string> KnownRecipes { get; set; }

		[JsonProperty("knownMaterial", Required = Required.Always)]
		public List<string> KnownMaterial { get; set; }

		[JsonProperty("knownStations", Required = Required.Always)]
		public List<CharacterStation> KnownStations { get; set; }
	}
	[JsonObject(MemberSerialization.OptIn)]
	internal class MapPinData
	{
		[JsonProperty("name")]
		public string Name { get; set; }

		[JsonProperty("x")]
		public float? X { get; set; }

		[JsonProperty("y")]
		public float? Y { get; set; }

		[JsonProperty("z")]
		public float? Z { get; set; }

		[JsonProperty("type")]
		public int? Type { get; set; }

		[JsonProperty("checked")]
		public bool? Checked { get; set; }

		internal bool SameAs(MapPinData other)
		{
			if (other != null && Name == other.Name && X.Equals(other.X) && Y.Equals(other.Y) && Z.Equals(other.Z) && Type == other.Type)
			{
				return Checked == other.Checked;
			}
			return false;
		}
	}
	[JsonObject(MemberSerialization.OptIn)]
	internal sealed class MapPinRequest : MapPinData
	{
		[JsonProperty("request", Required = Required.Always)]
		public string Request { get; set; }

		[JsonProperty("kind", Required = Required.Always)]
		public MapPinOperation Kind { get; set; }

		[JsonProperty("id")]
		public string Id { get; set; }
	}
	internal enum MapPinOperation
	{
		[EnumMember(Value = "create")]
		Create,
		[EnumMember(Value = "update")]
		Update,
		[EnumMember(Value = "delete")]
		Delete
	}
	[JsonObject(MemberSerialization.OptIn)]
	internal abstract class WorldAction
	{
		[JsonProperty("id", NullValueHandling = NullValueHandling.Ignore)]
		public string Id { get; set; }

		[JsonProperty("kind")]
		public abstract string Kind { get; }
	}
	[JsonObject(MemberSerialization.OptIn)]
	internal abstract class TargetAction : WorldAction
	{
		[JsonProperty("user", Required = Required.Always)]
		public string User { get; set; }

		[JsonProperty("object", Required = Required.Always)]
		public uint Object { get; set; }
	}
	[JsonObject(MemberSerialization.OptIn)]
	internal sealed class PickupAction : TargetAction
	{
		public override string Kind => "pickup";

		[JsonProperty("automatic", NullValueHandling = NullValueHandling.Ignore)]
		public bool? Automatic { get; set; }
	}
	[JsonObject(MemberSerialization.OptIn)]
	internal sealed class RepairAction : TargetAction
	{
		public override string Kind => "repair";
	}
	[JsonObject(MemberSerialization.OptIn)]
	internal sealed class ContainerAction : TargetAction
	{
		public override string Kind => "container";

		[JsonProperty("operation", Required = Required.Always)]
		public ContainerOperation Operation { get; set; }

		[JsonProperty("deposit", NullValueHandling = NullValueHandling.Ignore)]
		public bool? Deposit { get; set; }

		[JsonProperty("x", NullValueHandling = NullValueHandling.Ignore)]
		public int? X { get; set; }

		[JsonProperty("y", NullValueHandling = NullValueHandling.Ignore)]
		public int? Y { get; set; }

		[JsonProperty("amount", NullValueHandling = NullValueHandling.Ignore)]
		public int? Amount { get; set; }

		[JsonProperty("prefab", NullValueHandling = NullValueHandling.Ignore)]
		public int? Prefab { get; set; }
	}
	[JsonObject(MemberSerialization.OptIn)]
	internal sealed class TradeAction : TargetAction
	{
		public override string Kind => "trade";

		[JsonProperty("sell", NullValueHandling = NullValueHandling.Ignore)]
		public bool? Sell { get; set; }

		[JsonProperty("offer", NullValueHandling = NullValueHandling.Ignore)]
		public int? Offer { get; set; }
	}
	[JsonObject(MemberSerialization.OptIn)]
	internal sealed class InteractAction : TargetAction
	{
		public override string Kind => "interact";

		[JsonProperty("component", Required = Required.Always)]
		public int Component { get; set; }

		[JsonProperty("alt", NullValueHandling = NullValueHandling.Ignore)]
		public bool? Alt { get; set; }

		[JsonProperty("useItem", NullValueHandling = NullValueHandling.Ignore)]
		public bool? UseItem { get; set; }

		[JsonProperty("x", NullValueHandling = NullValueHandling.Ignore)]
		public int? X { get; set; }

		[JsonProperty("y", NullValueHandling = NullValueHandling.Ignore)]
		public int? Y { get; set; }

		[JsonProperty("prefab", NullValueHandling = NullValueHandling.Ignore)]
		public int? Prefab { get; set; }
	}
	[JsonObject(MemberSerialization.OptIn)]
	internal sealed class CraftAction : WorldAction
	{
		public override string Kind => "craft";

		[JsonProperty("prefab", Required = Required.Always)]
		public int Prefab { get; set; }

		[JsonProperty("count", NullValueHandling = NullValueHandling.Ignore)]
		public int? Count { get; set; }

		[JsonProperty("variant", NullValueHandling = NullValueHandling.Ignore)]
		public int? Variant { get; set; }

		[JsonProperty("upgrade", NullValueHandling = NullValueHandling.Ignore)]
		public bool? Upgrade { get; set; }

		[JsonProperty("x", NullValueHandling = NullValueHandling.Ignore)]
		public int? X { get; set; }

		[JsonProperty("y", NullValueHandling = NullValueHandling.Ignore)]
		public int? Y { get; set; }

		[JsonProperty("quality", NullValueHandling = NullValueHandling.Ignore)]
		public int? Quality { get; set; }
	}
	[JsonObject(MemberSerialization.OptIn)]
	internal sealed class EatAction : WorldAction
	{
		public override string Kind => "eat";

		[JsonProperty("prefab", Required = Required.Always)]
		public int Prefab { get; set; }

		[JsonProperty("quality", Required = Required.Always)]
		public int Quality { get; set; }

		[JsonProperty("x", Required = Required.Always)]
		public int X { get; set; }

		[JsonProperty("y", Required = Required.Always)]
		public int Y { get; set; }
	}
	[JsonObject(MemberSerialization.OptIn)]
	internal sealed class DropAction : WorldAction
	{
		public override string Kind => "drop";

		[JsonProperty("prefab", Required = Required.Always)]
		public int Prefab { get; set; }

		[JsonProperty("amount", Required = Required.Always)]
		public int Amount { get; set; }

		[JsonProperty("quality", Required = Required.Always)]
		public int Quality { get; set; }

		[JsonProperty("variant", Required = Required.Always)]
		public int Variant { get; set; }

		[JsonProperty("x", Required = Required.Always)]
		public int X { get; set; }

		[JsonProperty("y", Required = Required.Always)]
		public int Y { get; set; }
	}
	[JsonObject(MemberSerialization.OptIn)]
	internal sealed class RearrangeAction : WorldAction
	{
		public override string Kind => "rearrange";

		[JsonProperty("x", Required = Required.Always)]
		public int X { get; set; }

		[JsonProperty("y", Required = Required.Always)]
		public int Y { get; set; }

		[JsonProperty("toX", Required = Required.Always)]
		public int ToX { get; set; }

		[JsonProperty("toY", Required = Required.Always)]
		public int ToY { get; set; }

		[JsonProperty("amount", Required = Required.Always)]
		public int Amount { get; set; }

		[JsonProperty("prefab", Required = Required.Always)]
		public int Prefab { get; set; }

		[JsonProperty("quality", Required = Required.Always)]
		public int Quality { get; set; }
	}
	[JsonObject(MemberSerialization.OptIn)]
	internal sealed class RemovePieceAction : TargetAction
	{
		public override string Kind => "removePiece";
	}
	[JsonObject(MemberSerialization.OptIn)]
	internal sealed class BuildAction : WorldAction
	{
		public override string Kind => "build";

		[JsonProperty("ray", Required = Required.Always)]
		public BuildRay Ray { get; set; }

		[JsonProperty("prefab", Required = Required.Always)]
		public int Prefab { get; set; }

		[JsonProperty("snap", Required = Required.Always)]
		public int Snap { get; set; }

		[JsonProperty("alt", Required = Required.Always)]
		public bool Alt { get; set; }

		[JsonProperty("yaw", Required = Required.Always)]
		public float Yaw { get; set; }
	}
	[JsonObject(MemberSerialization.OptIn)]
	internal sealed class TombstoneAction : WorldAction
	{
		public override string Kind => "tombstone";
	}
	internal enum ContainerOperation
	{
		[EnumMember(Value = "open")]
		Open,
		[EnumMember(Value = "item")]
		Item,
		[EnumMember(Value = "stack")]
		Stack,
		[EnumMember(Value = "all")]
		All
	}
}
namespace Landoria.ServerShield.Client
{
	[HarmonyPatch(typeof(Game), "UpdateRespawn")]
	internal static class CharacterLoad
	{
		internal static PlayerProfile Profile;

		internal static byte[] LoadingPayload;

		private static PlayerProfile loadingProfile;

		private static string requestId;

		private static ZRpc connection;

		private static float requestedAt;

		internal static bool Rejected;

		private static bool Prefix(ref PlayerProfile ___m_playerProfile, ref bool ___m_queuedIntro, ref bool ___m_inIntro)
		{
			ZNet instance = ZNet.instance;
			if ((Object)(object)instance == (Object)null || instance.IsServer())
			{
				return true;
			}
			ZNetPeer serverPeer = instance.GetServerPeer();
			if (serverPeer == null)
			{
				return false;
			}
			if (!instance.IsCurrentServerDedicated())
			{
				return true;
			}
			if (connection != serverPeer.m_rpc)
			{
				Reset(serverPeer.m_rpc);
			}
			if (Profile != null)
			{
				ApplyProfile(ref ___m_playerProfile, ref ___m_queuedIntro, ref ___m_inIntro);
				return true;
			}
			if (!Rejected)
			{
				Request();
			}
			return false;
		}

		private static void ApplyProfile(ref PlayerProfile profile, ref bool queuedIntro, ref bool inIntro)
		{
			if (profile != Profile)
			{
				profile = Profile;
				queuedIntro = false;
				inIntro = false;
			}
		}

		private static void Request()
		{
			if (requestId == null)
			{
				requestId = Guid.NewGuid().ToString("D");
				requestedAt = Time.realtimeSinceStartup;
				NetworkLog.Log.LogDebug("Requesting the server character profile.");
				try
				{
					PlayerProfile playerProfile = Game.instance.GetPlayerProfile();
					bool flag = playerProfile.m_firstSpawn && playerProfile.m_playerStats.All((PlayerStats stats) => stats.m_knownWorlds.Count == 0);
					connection.Invoke("Landoria.ServerShield.Admission", new object[3]
					{
						requestId,
						InitialAppearance.Read(playerProfile),
						flag
					});
					return;
				}
				catch (Exception message)
				{
					NetworkLog.Log.LogError(message);
					Game.instance.Logout(false, true);
					return;
				}
			}
			if (Time.realtimeSinceStartup - requestedAt > 30f)
			{
				NetworkLog.Log.LogError("Server character load timed out; no local character was used.");
				Game.instance.Logout(false, true);
			}
		}

		internal static bool IsPending(ZRpc rpc, string id)
		{
			if (!Rejected && rpc == connection && id == requestId && Profile == null)
			{
				ZNet instance = ZNet.instance;
				return rpc == ((instance != null) ? instance.GetServerRPC() : null);
			}
			return false;
		}

		internal static void Receive(ZRpc rpc, string id, ZPackage package)
		{
			if (!IsPending(rpc, id))
			{
				return;
			}
			try
			{
				LoadProfile(package);
			}
			catch (Exception message)
			{
				NetworkLog.Log.LogError(message);
				Game.instance.Logout(false, true);
			}
			finally
			{
				loadingProfile = null;
				LoadingPayload = null;
			}
		}

		private static void LoadProfile(ZPackage package)
		{
			//IL_003c: 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_004b: Expected O, but got Unknown
			byte[] array = package.ReadByteArray();
			FchJsonConverter.ToJson(array);
			NetworkLog.Log.LogDebug($"Character checksum and schema validated: bytes={array.Length}.");
			PlayerProfile playerProfile = Game.instance.GetPlayerProfile();
			loadingProfile = new PlayerProfile(playerProfile.m_filename, playerProfile.m_fileSource);
			using (BinaryReader binaryReader = new BinaryReader(new MemoryStream(array)))
			{
				LoadingPayload = binaryReader.ReadBytes(binaryReader.ReadInt32());
			}
			if (!loadingProfile.Load())
			{
				throw new InvalidDataException("Server character could not be loaded.");
			}
			Profile = loadingProfile;
			NetworkLog.Log.LogInfo("Server character received; spawn can proceed.");
		}

		internal static bool IsLoading(PlayerProfile profile)
		{
			return profile == loadingProfile;
		}

		internal static void Reset(ZRpc rpc = null)
		{
			if (connection != null || Profile != null || requestId != null)
			{
				NetworkLog.Log.LogDebug("Clearing the client character session.");
			}
			ClientMap.Reset();
			PlayerHealth.Reset();
			PlayerCreation.Reset();
			Profile = null;
			loadingProfile = null;
			LoadingPayload = null;
			requestId = null;
			connection = rpc;
			Rejected = false;
		}
	}
	[HarmonyPatch(typeof(PlayerProfile), "LoadPlayerDataFromDisk")]
	internal static class ServerProfileDataPatch
	{
		private static bool Prefix(PlayerProfile __instance, ref ZPackage __result)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			if (!CharacterLoad.IsLoading(__instance))
			{
				return true;
			}
			__result = new ZPackage(CharacterLoad.LoadingPayload);
			return false;
		}
	}
	[HarmonyPatch(typeof(Game), "Update")]
	internal static class CharacterIntroPatch
	{
		private static void Prefix(ref bool ___m_queuedIntro, ref bool ___m_inIntro)
		{
			if ((Object)(object)ZNet.instance != (Object)null && !ZNet.instance.IsServer() && ZNet.instance.IsCurrentServerDedicated())
			{
				___m_queuedIntro = false;
				___m_inIntro = false;
			}
		}
	}
	[HarmonyPatch(typeof(Game), "Awake")]
	internal static class CharacterSessionPatch
	{
		private static void Prefix()
		{
			CharacterLoad.Reset();
		}
	}
	internal static class CharacterRejection
	{
		internal static void Register(ZRpc rpc)
		{
			ConnectionFailureMessages.Clear("Landoria.ServerShield.Client");
			rpc.Register<string, string>("Landoria.ServerShield.Rejection", (Action<ZRpc, string, string>)Receive);
		}

		private static void Receive(ZRpc rpc, string requestId, string message)
		{
			if (!CharacterLoad.IsPending(rpc, requestId))
			{
				return;
			}
			CharacterLoad.Rejected = true;
			ConnectionFailureMessages.Push("Landoria.ServerShield.Client", message);
			try
			{
				rpc.Invoke("Landoria.ServerShield.RejectionAck", new object[1] { requestId });
			}
			catch (Exception message2)
			{
				NetworkLog.Log.LogError(message2);
			}
		}
	}
	[HarmonyPatch]
	internal static class ClientMap
	{
		private static ZPackage snapshot;

		private static readonly Queue<Tuple<Vector3, float>> exploration = new Queue<Tuple<Vector3, float>>();

		internal static bool Ready;

		private static bool applying;

		internal static bool Active
		{
			get
			{
				if ((Object)(object)ZNet.instance != (Object)null && !ZNet.instance.IsServer())
				{
					return ZNet.instance.IsCurrentServerDedicated();
				}
				return false;
			}
		}

		internal static void Reset()
		{
			snapshot = null;
			exploration.Clear();
			Ready = false;
			ClientMapPins.Reset();
		}

		internal static void Receive(ZRpc rpc, ZPackage package)
		{
			if (Active && rpc == ZNet.instance.GetServerRPC())
			{
				snapshot = package;
				exploration.Clear();
				Ready = false;
			}
		}

		internal static void ReceiveExplore(ZRpc rpc, Vector3 position, float radius)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			if (Active && rpc == ZNet.instance.GetServerRPC())
			{
				exploration.Enqueue(Tuple.Create<Vector3, float>(position, radius));
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Minimap), "Update")]
		private static void Update(Minimap __instance, bool ___m_hasGenerated, List<PinData> ___m_pins)
		{
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			if (!Active || !___m_hasGenerated || CharacterLoad.Profile == null)
			{
				return;
			}
			try
			{
				applying = true;
				if (snapshot != null)
				{
					byte[] data = snapshot.ReadByteArray();
					int num = snapshot.ReadInt();
					if (num < 0 || num > 10000)
					{
						throw new InvalidOperationException("Invalid server pin count.");
					}
					List<string> list = new List<string>();
					for (int i = 0; i < num; i++)
					{
						list.Add(snapshot.ReadString());
					}
					Apply(__instance, data);
					ClientMapPins.Bind(___m_pins, list);
					snapshot = null;
					Ready = true;
					NetworkLog.Log.LogInfo($"Restored server map and {num} pins.");
				}
				if (Ready)
				{
					while (exploration.Count > 0)
					{
						Tuple<Vector3, float> tuple = exploration.Dequeue();
						Explore(__instance, tuple.Item1, tuple.Item2);
					}
					ClientMapPins.Update(___m_pins);
				}
			}
			catch (Exception message)
			{
				NetworkLog.Log.LogError(message);
				snapshot = null;
				Ready = false;
				exploration.Clear();
			}
			finally
			{
				applying = false;
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(Minimap), "LoadMapData")]
		private static bool LocalLoad()
		{
			return !Active;
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(Minimap), "SaveMapData")]
		private static bool LocalSave()
		{
			return !Active;
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(Minimap), "Explore", new Type[]
		{
			typeof(int),
			typeof(int)
		})]
		private static bool LocalExploration()
		{
			if (Active)
			{
				return applying;
			}
			return true;
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(Minimap), "ExploreOthers")]
		private static bool SharedExploration()
		{
			if (Active)
			{
				return applying;
			}
			return true;
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(Minimap), "AddSharedMapData")]
		private static bool SharedImport()
		{
			return !Active;
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(Minimap), "UpdateExplore")]
		private static bool AutoExplore()
		{
			return !Active;
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(Minimap), "SetMapData")]
		private static bool LocalMapReplacement()
		{
			if (Active)
			{
				return applying;
			}
			return true;
		}

		[HarmonyReversePatch(/*Could not decode attribute arguments.*/)]
		[HarmonyPatch(typeof(Minimap), "SetMapData")]
		private static void Apply(Minimap instance, byte[] data)
		{
			throw new NotImplementedException();
		}

		[HarmonyReversePatch(/*Could not decode attribute arguments.*/)]
		[HarmonyPatch(typeof(Minimap), "Explore", new Type[]
		{
			typeof(Vector3),
			typeof(float)
		})]
		private static void Explore(Minimap instance, Vector3 position, float radius)
		{
			throw new NotImplementedException();
		}
	}
	internal static class ClientMapPins
	{
		private sealed class Pin
		{
			internal PinData Visual;

			internal string Id;

			internal MapPinData Saved;
		}

		private static readonly List<Pin> pins = new List<Pin>();

		private static Pin pendingPin;

		private static MapPinData pendingData;

		private static string pendingId;

		private static MapPinOperation operation;

		internal static void Reset()
		{
			pins.Clear();
			pendingPin = null;
			pendingData = null;
			pendingId = null;
		}

		internal static void Bind(List<PinData> visuals, List<string> ids)
		{
			Reset();
			List<PinData> list = visuals.Where((PinData pin) => pin.m_save).ToList();
			if (list.Count != ids.Count)
			{
				throw new InvalidOperationException("Server pins do not match the map snapshot.");
			}
			for (int num = 0; num < list.Count; num++)
			{
				pins.Add(new Pin
				{
					Visual = list[num],
					Id = ids[num],
					Saved = Data(list[num])
				});
			}
		}

		internal static void Update(List<PinData> visuals)
		{
			if (pendingId != null)
			{
				return;
			}
			foreach (Pin pin in pins)
			{
				if (!visuals.Contains(pin.Visual))
				{
					Send(pin, MapPinOperation.Delete, pin.Saved);
					return;
				}
				MapPinData mapPinData = Data(pin.Visual);
				if (!mapPinData.SameAs(pin.Saved))
				{
					Send(pin, MapPinOperation.Update, mapPinData);
					return;
				}
			}
			PinData val = ((IEnumerable<PinData>)visuals).FirstOrDefault((Func<PinData, bool>)((PinData pin) => pin.m_save && !pins.Any((Pin known) => known.Visual == pin)));
			if (val != null)
			{
				Send(new Pin
				{
					Visual = val
				}, MapPinOperation.Create, Data(val));
			}
		}

		private static void Send(Pin pin, MapPinOperation kind, MapPinData data)
		{
			ZRpc serverRPC = ZNet.instance.GetServerRPC();
			if (serverRPC == null || !serverRPC.IsConnected())
			{
				return;
			}
			MapPinRequest mapPinRequest = new MapPinRequest
			{
				Name = data.Name,
				X = data.X,
				Y = data.Y,
				Z = data.Z,
				Type = data.Type,
				Checked = data.Checked
			};
			pendingId = Guid.NewGuid().ToString("D");
			pendingPin = pin;
			pendingData = data;
			operation = kind;
			mapPinRequest.Request = pendingId;
			mapPinRequest.Kind = kind;
			mapPinRequest.Id = pin.Id;
			try
			{
				serverRPC.Invoke("Landoria.ServerShield.MapPinRequest", new object[1] { WireJson.Write(mapPinRequest) });
			}
			catch (Exception message)
			{
				NetworkLog.Log.LogError(message);
				pendingId = null;
			}
		}

		internal static void Receive(ZRpc rpc, string request, bool success, string result)
		{
			if (!ClientMap.Active || rpc != ZNet.instance.GetServerRPC() || request != pendingId || pendingPin == null)
			{
				return;
			}
			if (!success)
			{
				ClientMap.Ready = false;
				MessageHud instance = MessageHud.instance;
				if (instance != null)
				{
					instance.ShowMessage((MessageType)2, result, 0, (Sprite)null, false, true);
				}
			}
			else if (operation == MapPinOperation.Delete)
			{
				pins.Remove(pendingPin);
			}
			else
			{
				pendingPin.Id = result;
				pendingPin.Saved = pendingData;
				if (operation == MapPinOperation.Create)
				{
					pins.Add(pendingPin);
				}
			}
			pendingId = null;
			pendingPin = null;
			pendingData = null;
		}

		private static MapPinData Data(PinData pin)
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Expected I4, but got Unknown
			return new MapPinData
			{
				Name = (pin.m_name ?? ""),
				X = pin.m_pos.x,
				Y = pin.m_pos.y,
				Z = pin.m_pos.z,
				Type = (int)pin.m_type,
				Checked = pin.m_checked
			};
		}
	}
	[HarmonyPatch]
	internal static class ClientSpawnArea
	{
		internal static bool IsReady(Vector3 point, ZDO reserved)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			Vector2s zone = ZoneSystem.GetZone(point);
			if (!ZoneSystem.instance.IsZoneLoaded(zone))
			{
				return false;
			}
			List<ZDO> list = new List<ZDO>();
			ZDOMan.instance.FindSectorObjects(zone, new SimulationDistance(1, 0, false), list, (List