Decompiled source of WindyLab IdentityCard v0.1.10

BonelabRP.Identite.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text.Json;
using BoneLib;
using BoneLib.BoneMenu;
using BoneLib.BoneMenu.UI;
using BonelabRP.Identite;
using HarmonyLib;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSLZ.Marrow;
using Il2CppSLZ.Marrow.Data;
using Il2CppSLZ.Marrow.Interaction;
using Il2CppSLZ.Marrow.Warehouse;
using Il2CppTMPro;
using LabFusion.Entities;
using LabFusion.Network;
using LabFusion.Network.Serialization;
using LabFusion.Player;
using LabFusion.RPC;
using LabFusion.SDK.Modules;
using LabFusion.Scene;
using MelonLoader;
using MelonLoader.Utils;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: MelonInfo(typeof(IdentityMod), "BonelabRP Identite", "0.1.10", "Romu", null)]
[assembly: MelonGame("Stress Level Zero", "BONELAB")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("BonelabRP.Identite")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("BonelabRP.Identite")]
[assembly: AssemblyTitle("BonelabRP.Identite")]
[assembly: AssemblyVersion("1.0.0.0")]
[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 BonelabRP.Identite
{
	public static class IdentityBirthInput
	{
		public static string Format(string text, string previous = "")
		{
			if (text == null)
			{
				text = "";
			}
			if (previous == null)
			{
				previous = "";
			}
			if (previous.EndsWith("/", StringComparison.Ordinal) && text == previous.Substring(0, previous.Length - 1) && text.Length > 0)
			{
				text = text.Substring(0, text.Length - 1);
			}
			string text2 = new string(text.Where((char c) => c >= '0' && c <= '9').Take(8).ToArray());
			if (text2.Length < 2)
			{
				return text2;
			}
			if (text2.Length == 2)
			{
				return text2 + "/";
			}
			if (text2.Length < 4)
			{
				return text2.Substring(0, 2) + "/" + text2.Substring(2);
			}
			return text2.Substring(0, 2) + "/" + text2.Substring(2, 2) + "/" + text2.Substring(4);
		}

		public static string Normalize(string text)
		{
			text = (text ?? "").Trim();
			if (text.Any((char c) => (c < '0' || c > '9') && c != '/'))
			{
				return text;
			}
			string text2 = text.Replace("/", "");
			return (text2.Length == 8) ? (text2.Substring(0, 2) + "/" + text2.Substring(2, 2) + "/" + text2.Substring(4)) : text;
		}
	}
	public static class IdentityBirthKeyboard
	{
		private static Keyboard active;

		private static string previous = "";

		public static void Connect(Keyboard keyboard, GUIStringElement element)
		{
			active = null;
			previous = "";
			if (((element != null) ? element.BackingElement : null) == IdentityMod.Instance?.BirthElement)
			{
				active = keyboard;
				TMP_InputField inputField = keyboard.InputField;
				previous = ((inputField != null) ? inputField.text : null) ?? "";
			}
		}

		public static void Poll()
		{
			if ((Object)(object)active == (Object)null || (Object)(object)active.InputField == (Object)null)
			{
				return;
			}
			TMP_InputField inputField = active.InputField;
			string text = inputField.text ?? "";
			if (!(text == previous))
			{
				string text2 = IdentityBirthInput.Format(text, previous);
				if (text2 != text)
				{
					inputField.SetTextWithoutNotify(text2);
					inputField.caretPosition = text2.Length;
				}
				previous = text2;
			}
		}

		public static void Clear()
		{
			active = null;
			previous = "";
		}
	}
	[HarmonyPatch(typeof(Keyboard), "ConnectElement")]
	public static class IdentityBirthConnectPatch
	{
		[HarmonyPostfix]
		public static void Postfix(Keyboard __instance, GUIStringElement __0)
		{
			IdentityBirthKeyboard.Connect(__instance, __0);
		}
	}
	public sealed class IdentityMod : MelonMod
	{
		private sealed class Card
		{
			public NetworkEntity Entity;

			public GameObject Body;

			public bool Pending;

			public float Started;

			public bool Parked = true;

			public long Placement;
		}

		public const string Barcode = "SLZ.BONELAB.Content.Spawnable.PropIDCard";

		private readonly ConcurrentQueue<(ulong Actor, IdentityCommand Command)> commands = new ConcurrentQueue<(ulong, IdentityCommand)>();

		private readonly ConcurrentQueue<IdentityState> states = new ConcurrentQueue<IdentityState>();

		private readonly Dictionary<ulong, Card> cards = new Dictionary<ulong, Card>();

		private readonly Dictionary<ulong, IdentityState> views = new Dictionary<ulong, IdentityState>();

		private readonly Dictionary<ulong, IdentitySurface> surfaces = new Dictionary<ulong, IdentitySurface>();

		private readonly Dictionary<ulong, double> rates = new Dictionary<ulong, double>();

		private bool english;

		private readonly IdentityPortrait portrait = new IdentityPortrait();

		private IdentityStore store;

		private IdentityProfile draft = new IdentityProfile();

		private CardLayout layout = new CardLayout();

		private string directory;

		private string session = "";

		private string clientSession = "";

		private string scene = "";

		private bool connected;

		private bool wasHost;

		private bool loading;

		private int generation;

		private float nextSync;

		private float nextTick;

		private float nextWarning;

		private FunctionElement statusElement;

		private string status = "Rejoindre Fusion.";

		private string deferred = "";

		private readonly IdentityParking parking = new IdentityParking();

		private long placements;

		private Spawnable spawnable;

		public StringElement BirthElement { get; private set; }

		public static IdentityMod Instance { get; private set; }

		public void Enqueue(ulong actor, IdentityCommand c)
		{
			if (commands.Count < 128)
			{
				commands.Enqueue((actor, c));
			}
		}

		public void EnqueueState(IdentityState s)
		{
			if (states.Count < 128)
			{
				states.Enqueue(s);
			}
		}

		public override void OnInitializeMelon()
		{
			Instance = this;
			directory = Path.Combine(MelonEnvironment.UserDataDirectory, "BonelabRP.Identite");
			Directory.CreateDirectory(directory);
			try
			{
				english = File.Exists(Path.Combine(directory, "langue.txt")) && File.ReadAllText(Path.Combine(directory, "langue.txt")).Trim() == "en-US";
				if (File.Exists(Path.Combine(directory, "ma-fiche.json")))
				{
					draft = JsonSerializer.Deserialize<IdentityProfile>(File.ReadAllText(Path.Combine(directory, "ma-fiche.json"))) ?? new IdentityProfile();
				}
				if (File.Exists(Path.Combine(directory, "placement.json")))
				{
					layout = JsonSerializer.Deserialize<CardLayout>(File.ReadAllText(Path.Combine(directory, "placement.json"))) ?? new CardLayout();
				}
				ValidateLayout();
			}
			catch (Exception ex)
			{
				layout = new CardLayout();
				((MelonBase)this).LoggerInstance.Warning(ex.Message);
			}
			IdentityTransport.Register();
			((MelonBase)this).HarmonyInstance.PatchAll(typeof(IdentityMod).Assembly);
			Menu();
			((MelonBase)this).LoggerInstance.Msg("Carte d’identité RP : BoneMenu > Identité RP.");
		}

		private void Notice(string text)
		{
			status = text;
			if (statusElement != null)
			{
				((Element)statusElement).ElementName = "État : " + text;
			}
			((MelonBase)this).LoggerInstance.Msg("Identité : " + text);
		}

		private void SaveDraft()
		{
			File.WriteAllText(Path.Combine(directory, "ma-fiche.json"), JsonSerializer.Serialize(draft, new JsonSerializerOptions
			{
				WriteIndented = true
			}));
		}

		private void Send(string op)
		{
			try
			{
				if (!NetworkInfo.HasServer || PlayerIDManager.LocalID == null)
				{
					throw new InvalidOperationException("Rejoindre une session Fusion.");
				}
				if (op != "sync" && clientSession == "")
				{
					deferred = op;
					Notice("Synchronisation avec l’hôte…");
					Send("sync");
					return;
				}
				if (op != "sync")
				{
					Notice((op == "spawn") ? "Demande de sortie envoyée…" : "Enregistrement envoyé…");
				}
				IdentityCommand identityCommand = new IdentityCommand
				{
					Operation = op,
					Session = clientSession,
					Profile = ((op == "save" || op == "spawn") ? draft : null)
				};
				if (NetworkInfo.IsHost)
				{
					Enqueue(PlayerIDManager.LocalPlatformID, identityCommand);
				}
				else
				{
					IdentityTransport.Send(identityCommand);
				}
			}
			catch (Exception ex)
			{
				Notice(ex.Message);
			}
		}

		private void Menu()
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01da: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0214: Unknown result type (might be due to invalid IL or missing references)
			Page val = Page.Root.CreatePage("Identité RP", Color.cyan, 0, true);
			Page val2 = val.CreatePage("Langue de la carte / Card language", Color.white, 0, true);
			val2.CreateFunction("Français", Color.white, (Action)delegate
			{
				SetLanguage(value: false);
			});
			val2.CreateFunction("English (US)", Color.white, (Action)delegate
			{
				SetLanguage(value: true);
			});
			statusElement = val.CreateFunction("État : " + status, Color.white, (Action)delegate
			{
				Notice(status);
			});
			Page val3 = val.CreatePage("Ma fiche RP", Color.white, 0, true);
			val3.CreateString("NOM", Color.white, draft.LastName, (Action<string>)delegate(string v)
			{
				draft.LastName = v;
				SaveDraft();
			});
			val3.CreateString("PRÉNOM", Color.white, draft.FirstName, (Action<string>)delegate(string v)
			{
				draft.FirstName = v;
				SaveDraft();
			});
			draft.BirthDate = IdentityBirthInput.Normalize(draft.BirthDate);
			BirthElement = val3.CreateString("Naissance (8 chiffres)", Color.white, draft.BirthDate, (Action<string>)delegate(string v)
			{
				draft.BirthDate = IdentityBirthInput.Format(v);
				BirthElement.Value = draft.BirthDate;
				SaveDraft();
			});
			val3.CreateString("Lieu de naissance", Color.white, draft.BirthPlace, (Action<string>)delegate(string v)
			{
				draft.BirthPlace = v;
				SaveDraft();
			});
			val3.CreateString("Nationalité", Color.white, draft.Nationality, (Action<string>)delegate(string v)
			{
				draft.Nationality = v;
				SaveDraft();
			});
			val3.CreateString("Sexe (facultatif)", Color.white, draft.Sex, (Action<string>)delegate(string v)
			{
				draft.Sex = v;
				SaveDraft();
			});
			val3.CreateFunction("Enregistrer auprès du serveur", Color.green, (Action)delegate
			{
				Send("save");
			});
			val.CreateFunction("Photographier mon avatar", Color.cyan, (Action)delegate
			{
				portrait.Capture(delegate(string s)
				{
					draft.Photo = s;
					SaveDraft();
					Notice("Photo prête. Enregistre ta fiche pour l’appliquer.");
				}, Notice);
			});
			val.CreateFunction("Importer portrait.jpg (160 × 200)", Color.white, (Action)delegate
			{
				try
				{
					draft.Photo = Convert.ToBase64String(File.ReadAllBytes(Path.Combine(directory, "portrait.jpg")));
					IdentityRules.Photo(draft.Photo);
					SaveDraft();
					Notice("Photo importée. Enregistre ta fiche.");
				}
				catch (Exception ex)
				{
					Notice(ex.Message);
				}
			});
			val.CreateFunction("Sortir / rappeler ma carte", Color.green, (Action)delegate
			{
				Send("spawn");
			});
		}

		private void SetLanguage(bool value)
		{
			try
			{
				File.WriteAllText(Path.Combine(directory, "langue.txt"), value ? "en-US" : "fr-FR");
				english = value;
				foreach (IdentitySurface value2 in surfaces.Values)
				{
					value2.Dispose();
				}
				surfaces.Clear();
				Notice(value ? "Card language: English (US). Dates: MM/DD/YYYY." : "Carte en français. Dates : JJ/MM/AAAA.");
			}
			catch (Exception ex)
			{
				Notice(ex.Message);
			}
		}

		private void ValidateLayout()
		{
			if (!float.IsFinite(layout.Scale) || layout.Scale < 0.25f || layout.Scale > 2f || !float.IsFinite(layout.X) || Math.Abs(layout.X) > 0.1f || !float.IsFinite(layout.Y) || Math.Abs(layout.Y) > 0.1f || !float.IsFinite(layout.Z) || Math.Abs(layout.Z) > 0.1f || !float.IsFinite(layout.Rotation))
			{
				throw new InvalidDataException("Placement de carte invalide.");
			}
		}

		public override void OnUpdate()
		{
			try
			{
				IdentityBirthKeyboard.Poll();
				if (!NetworkInfo.HasServer || PlayerIDManager.LocalID == null)
				{
					if (connected)
					{
						Reset();
					}
					return;
				}
				bool isHost = NetworkInfo.IsHost;
				if (!connected || wasHost != isHost)
				{
					Reset();
					connected = true;
					wasHost = isHost;
					if (isHost)
					{
						store = new IdentityStore(Path.Combine(directory, "identites-serveur.json"));
						session = Guid.NewGuid().ToString("N");
						clientSession = session;
					}
				}
				if (isHost && store == null)
				{
					throw new InvalidOperationException("Base d’identités indisponible : consulter la première erreur dans Latest.log.");
				}
				bool flag = FusionSceneManager.IsLoading();
				string text = FusionSceneManager.Barcode ?? "";
				if (scene != text || loading != flag)
				{
					ClearCards();
					scene = text;
					loading = flag;
					nextSync = 0f;
				}
				IdentityState result;
				while (states.TryDequeue(out result))
				{
					Accept(result);
				}
				if (isHost)
				{
					int num = 16;
					(ulong, IdentityCommand) result2;
					while (num-- > 0 && commands.TryDequeue(out result2))
					{
						Handle(result2.Item1, result2.Item2);
					}
					if (Time.realtimeSinceStartup >= nextTick)
					{
						nextTick = Time.realtimeSinceStartup + 1f;
						ulong[] array = cards.Keys.ToArray();
						foreach (ulong num2 in array)
						{
							PlayerID playerID = PlayerIDManager.GetPlayerID(num2);
							if (playerID == null || !playerID.IsValid)
							{
								Remove(num2);
								Broadcast(new IdentityState
								{
									Session = session,
									Scene = scene,
									Kind = "remove",
									Owner = num2
								});
							}
							else if (cards[num2].Parked && !cards[num2].Pending && (Object)(object)cards[num2].Body != (Object)null && Held(cards[num2].Body))
							{
								cards[num2].Parked = false;
								Broadcast(State(num2));
							}
							else if (cards[num2].Pending && Time.realtimeSinceStartup - cards[num2].Started > 30f)
							{
								Remove(num2);
								Reply(num2, "Préparation expirée. Réessayer.");
							}
						}
					}
				}
				if (Time.realtimeSinceStartup >= nextSync)
				{
					nextSync = Time.realtimeSinceStartup + 10f;
					Send("sync");
				}
				if (!loading)
				{
					parking.Tick(isHost ? (from p in cards
						where p.Value.Entity != null && p.Value.Entity.IsRegistered
						select new IdentityState
						{
							Owner = p.Key,
							Device = p.Value.Entity.ID,
							Parked = p.Value.Parked,
							Placement = p.Value.Placement
						}) : views.Values.Where((IdentityState v) => v.Scene == scene && v.Device.HasValue));
				}
				if (loading)
				{
					return;
				}
				foreach (KeyValuePair<ulong, IdentityState> view in views)
				{
					IdentityState value = view.Value;
					if (value.Scene != scene || !value.Device.HasValue || value.Profile == null)
					{
						continue;
					}
					if (!surfaces.TryGetValue(view.Key, out var value2))
					{
						GameObject val = Resolve(value.Device.Value);
						if ((Object)(object)val != (Object)null)
						{
							value2 = new IdentitySurface(val, value.Profile, value.Layout, english);
							surfaces[view.Key] = value2;
						}
					}
					if (value2 != null)
					{
						if (!value2.Alive)
						{
							value2.Dispose();
							surfaces.Remove(view.Key);
						}
						else
						{
							value2.Tick();
						}
					}
				}
			}
			catch (Exception ex)
			{
				if (Time.realtimeSinceStartup >= nextWarning)
				{
					nextWarning = Time.realtimeSinceStartup + 5f;
					((MelonBase)this).LoggerInstance.Warning(ex.ToString());
					Notice("Erreur : " + ex.Message);
				}
			}
		}

		private IdentityState State(ulong owner)
		{
			Card value;
			Card value2;
			return new IdentityState
			{
				Session = session,
				Scene = scene,
				Owner = owner,
				Profile = store?.Get(owner),
				Device = ((cards.TryGetValue(owner, out value) && value.Entity != null && value.Entity.IsRegistered) ? new ushort?(value.Entity.ID) : ((ushort?)null)),
				Layout = layout,
				Parked = (cards.TryGetValue(owner, out value2) && value2.Parked),
				Placement = (value2?.Placement ?? 0)
			};
		}

		private void Reply(ulong owner, string notice = "")
		{
			IdentityState identityState = State(owner);
			identityState.Notice = notice;
			To(identityState, owner);
		}

		private void To(IdentityState s, ulong actor)
		{
			PlayerID playerID = PlayerIDManager.GetPlayerID(actor);
			if (playerID != null && playerID.IsValid)
			{
				if (playerID.IsMe)
				{
					EnqueueState(s);
				}
				else
				{
					IdentityTransport.Reply(s, playerID.SmallID);
				}
			}
		}

		private void Broadcast(IdentityState s)
		{
			foreach (PlayerID playerID in PlayerIDManager.PlayerIDs)
			{
				if (playerID != null && playerID.IsValid)
				{
					To(s, playerID.PlatformID);
				}
			}
		}

		private void Handle(ulong actor, IdentityCommand c)
		{
			if (store == null || c.Protocol != 2)
			{
				return;
			}
			try
			{
				if (c.Operation == "sync")
				{
					To(new IdentityState
					{
						Session = session,
						Scene = scene,
						Kind = "hello"
					}, actor);
					Reply(actor);
					ulong[] array = cards.Keys.ToArray();
					foreach (ulong num in array)
					{
						if (num != actor)
						{
							To(State(num), actor);
						}
					}
					return;
				}
				if (c.Session != session)
				{
					throw new InvalidOperationException("Synchroniser avant de réessayer.");
				}
				rates.TryGetValue(actor, out var value);
				if ((double)Time.realtimeSinceStartup - value < 0.5)
				{
					throw new InvalidOperationException("Attendre avant de réessayer.");
				}
				rates[actor] = Time.realtimeSinceStartup;
				if (c.Operation == "save")
				{
					store.Save(actor, c.Profile);
					Reply(actor, "Fiche enregistrée.");
					if (cards.ContainsKey(actor))
					{
						Broadcast(State(actor));
					}
					return;
				}
				if (c.Operation == "spawn")
				{
					if (c.Profile != null)
					{
						store.Save(actor, c.Profile);
					}
					Spawn(actor);
					return;
				}
				throw new InvalidOperationException("Action inconnue.");
			}
			catch (Exception ex)
			{
				Reply(actor, ex.Message);
			}
		}

		internal static GameObject Resolve(ushort id)
		{
			NetworkEntity entity = NetworkEntityManager.IDManager.RegisteredEntities.GetEntity(id);
			object result;
			if (entity == null)
			{
				result = null;
			}
			else
			{
				IMarrowEntityExtender extender = entity.GetExtender<IMarrowEntityExtender>();
				if (extender == null)
				{
					result = null;
				}
				else
				{
					MarrowEntity marrowEntity = extender.MarrowEntity;
					result = ((marrowEntity != null) ? ((Component)marrowEntity).gameObject : null);
				}
			}
			return (GameObject)result;
		}

		private static bool Held(GameObject body)
		{
			NetworkPlayer val = default(NetworkPlayer);
			foreach (PlayerID playerID in PlayerIDManager.PlayerIDs)
			{
				if (playerID == null || !playerID.IsValid || !NetworkPlayerManager.TryGetPlayer(playerID.SmallID, ref val) || !val.HasRig)
				{
					continue;
				}
				Hand[] array = (Hand[])(object)new Hand[2]
				{
					val.RigRefs.LeftHand,
					val.RigRefs.RightHand
				};
				foreach (Hand val2 in array)
				{
					GameObject val3 = ((val2 != null) ? val2.m_CurrentAttachedGO : null);
					if ((Object)(object)val3 != (Object)null && ((Object)(object)val3 == (Object)(object)body || val3.transform.IsChildOf(body.transform) || body.transform.IsChildOf(val3.transform)))
					{
						return true;
					}
				}
			}
			return false;
		}

		private void Spawn(ulong actor)
		{
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02df: Expected O, but got Unknown
			//IL_0367: Unknown result type (might be due to invalid IL or missing references)
			//IL_037c: Unknown result type (might be due to invalid IL or missing references)
			//IL_037e: Unknown result type (might be due to invalid IL or missing references)
			//IL_038b: Unknown result type (might be due to invalid IL or missing references)
			//IL_039a: Unknown result type (might be due to invalid IL or missing references)
			//IL_039f: Unknown result type (might be due to invalid IL or missing references)
			//IL_03af: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0302: Unknown result type (might be due to invalid IL or missing references)
			//IL_0310: Expected O, but got Unknown
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_01db: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
			if (loading)
			{
				throw new InvalidOperationException("Attendre le chargement.");
			}
			if (store.Get(actor) == null)
			{
				throw new InvalidOperationException("Enregistrer ta fiche RP d’abord.");
			}
			PlayerID playerID = PlayerIDManager.GetPlayerID(actor);
			NetworkPlayer val = default(NetworkPlayer);
			if (playerID == null || !playerID.IsValid || !NetworkSceneManager.InCurrentLevel(playerID) || !NetworkPlayerManager.TryGetPlayer(playerID.SmallID, ref val) || !val.HasRig || (Object)(object)val.RigRefs.Head == (Object)null)
			{
				throw new InvalidOperationException("Avatar indisponible.");
			}
			Transform head = val.RigRefs.Head;
			Vector3 position = head.position + head.forward * 0.4f - Vector3.up * 0.2f;
			if (cards.TryGetValue(actor, out var value))
			{
				if (value.Pending)
				{
					throw new InvalidOperationException("Carte en préparation.");
				}
				if ((Object)(object)value.Body != (Object)null && value.Entity != null && value.Entity.IsRegistered)
				{
					if (Held(value.Body))
					{
						throw new InvalidOperationException("Relâcher la carte avant de la rappeler.");
					}
					NetworkEntityManager.TakeOwnership(value.Entity);
					value.Body.transform.position = position;
					value.Body.transform.rotation = Quaternion.Euler(0f, head.eulerAngles.y, 0f);
					foreach (Rigidbody componentsInChild in value.Body.GetComponentsInChildren<Rigidbody>())
					{
						componentsInChild.velocity = Vector3.zero;
						componentsInChild.angularVelocity = Vector3.zero;
					}
					value.Parked = true;
					value.Placement = ++placements;
					parking.Hold(State(actor), value.Body);
					Broadcast(State(actor));
					Reply(actor, "Carte rappelée devant toi • saisis-la.");
					return;
				}
				Remove(actor);
			}
			if (cards.Count >= 32)
			{
				throw new InvalidOperationException("Maximum de 32 cartes physiques.");
			}
			if (AssetWarehouse.Instance == null)
			{
				throw new InvalidOperationException("Catalogue indisponible.");
			}
			if (spawnable == null)
			{
				SpawnableCrateReference val2 = new SpawnableCrateReference("SLZ.BONELAB.Content.Spawnable.PropIDCard");
				SpawnableCrate val3 = default(SpawnableCrate);
				if (!((CrateReferenceT<SpawnableCrate>)(object)val2).TryGetCrate(ref val3))
				{
					throw new InvalidOperationException("Prop - ID Card absent du catalogue.");
				}
				spawnable = new Spawnable
				{
					crateRef = val2
				};
			}
			Card card = new Card
			{
				Pending = true,
				Started = Time.realtimeSinceStartup
			};
			cards[actor] = card;
			int gen = generation;
			Reply(actor, "Spawn Fusion en préparation…");
			try
			{
				NetworkAssetSpawner.Spawn(new SpawnRequestInfo
				{
					Spawnable = spawnable,
					Position = position,
					Rotation = Quaternion.Euler(0f, head.eulerAngles.y, 0f),
					SpawnEffect = false,
					SpawnSource = (EntitySource)1,
					SpawnCallback = delegate(SpawnCallbackInfo info)
					{
						//IL_0065: 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_0042: Unknown result type (might be due to invalid IL or missing references)
						if (gen != generation || !cards.TryGetValue(actor, out var value2) || value2 != card)
						{
							Despawn(info.Entity);
						}
						else
						{
							card.Pending = false;
							card.Entity = info.Entity;
							card.Body = info.Spawned;
							if ((Object)(object)card.Body == (Object)null || card.Entity == null)
							{
								Remove(actor);
								Reply(actor, "Spawn de carte échoué.");
							}
							else
							{
								card.Parked = true;
								card.Placement = ++placements;
								parking.Hold(State(actor), card.Body);
								Broadcast(State(actor));
								Reply(actor, "Carte suspendue devant toi • saisis-la.");
							}
						}
					}
				});
			}
			catch
			{
				cards.Remove(actor);
				throw;
			}
		}

		private static void Despawn(NetworkEntity e)
		{
			//IL_0021: 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)
			if (e != null && e.IsRegistered && NetworkInfo.IsHost && NetworkInfo.HasServer)
			{
				NetworkAssetSpawner.Despawn(new DespawnRequestInfo
				{
					EntityID = e.ID,
					DespawnEffect = false
				});
			}
		}

		private void Remove(ulong id)
		{
			if (cards.Remove(id, out var value))
			{
				Despawn(value.Entity);
			}
			if (surfaces.Remove(id, out var value2))
			{
				value2.Dispose();
			}
			views.Remove(id);
		}

		private void Accept(IdentityState s)
		{
			if (s.Protocol != 2 || !Guid.TryParseExact(s.Session, "N", out var _) || s.Scene != scene)
			{
				return;
			}
			if (s.Kind == "hello")
			{
				if (clientSession != s.Session)
				{
					ClearVisuals();
					clientSession = s.Session;
				}
				if (deferred != "")
				{
					string op = deferred;
					deferred = "";
					Send(op);
				}
			}
			else
			{
				if (s.Session != clientSession)
				{
					return;
				}
				if (s.Notice != "")
				{
					Notice(s.Notice);
				}
				if (s.Kind == "remove")
				{
					if (surfaces.Remove(s.Owner, out var value))
					{
						value.Dispose();
					}
					views.Remove(s.Owner);
				}
				else
				{
					if (s.Profile == null)
					{
						return;
					}
					IdentityRules.Validate(s.Profile, s.Owner, DateTime.Today);
					if (views.Count >= 32 && !views.ContainsKey(s.Owner))
					{
						return;
					}
					if (s.Layout == null)
					{
						CardLayout cardLayout = (s.Layout = new CardLayout());
					}
					if (views.TryGetValue(s.Owner, out var value2) && JsonSerializer.Serialize(value2.Profile) == JsonSerializer.Serialize(s.Profile) && value2.Device == s.Device && JsonSerializer.Serialize(value2.Layout) == JsonSerializer.Serialize(s.Layout))
					{
						views[s.Owner] = s;
						return;
					}
					if (surfaces.Remove(s.Owner, out var value3))
					{
						value3.Dispose();
					}
					views[s.Owner] = s;
				}
			}
		}

		private void ClearVisuals()
		{
			parking.Clear();
			foreach (IdentitySurface value in surfaces.Values)
			{
				value.Dispose();
			}
			surfaces.Clear();
			views.Clear();
		}

		private void ClearCards()
		{
			generation++;
			foreach (Card value in cards.Values)
			{
				Despawn(value.Entity);
			}
			cards.Clear();
			ClearVisuals();
			spawnable = null;
		}

		private void Reset()
		{
			ClearCards();
			store = null;
			session = (clientSession = (scene = ""));
			commands.Clear();
			states.Clear();
			rates.Clear();
			connected = false;
			deferred = "";
			nextSync = (nextTick = 0f);
		}

		public override void OnDeinitializeMelon()
		{
			IdentityBirthKeyboard.Clear();
			Reset();
			portrait.Dispose();
			Instance = null;
		}
	}
	public sealed class IdentityProfile
	{
		public ulong Owner { get; set; }

		public string Number { get; set; } = "";

		public string Issued { get; set; } = "";

		public string LastName { get; set; } = "";

		public string FirstName { get; set; } = "";

		public string BirthDate { get; set; } = "";

		public string BirthPlace { get; set; } = "";

		public string Nationality { get; set; } = "";

		public string Sex { get; set; } = "";

		public string Photo { get; set; } = "";
	}
	public sealed class CardLayout
	{
		public float X { get; set; }

		public float Y { get; set; }

		public float Z { get; set; }

		public float Scale { get; set; } = 1f;

		public float Rotation { get; set; }
	}
	public sealed class IdentityCommand
	{
		public int Protocol { get; set; } = 2;

		public string Session { get; set; } = "";

		public string Operation { get; set; } = "";

		public IdentityProfile Profile { get; set; }
	}
	public sealed class IdentityState
	{
		public int Protocol { get; set; } = 2;

		public string Session { get; set; } = "";

		public string Scene { get; set; } = "";

		public string Kind { get; set; } = "upsert";

		public string Notice { get; set; } = "";

		public ulong Owner { get; set; }

		public ushort? Device { get; set; }

		public bool Parked { get; set; }

		public long Placement { get; set; }

		public IdentityProfile Profile { get; set; }

		public CardLayout Layout { get; set; } = new CardLayout();
	}
	public static class IdentityRules
	{
		public const int PhotoBytes = 16384;

		private static string Text(string s, int max, bool required = false)
		{
			s = (s ?? "").Trim();
			if (s.Length > max || s.Any(char.IsControl) || (required && s.Length == 0))
			{
				throw new InvalidOperationException("Champ vide ou trop long.");
			}
			return s;
		}

		public static byte[] Photo(string s)
		{
			if (string.IsNullOrEmpty(s))
			{
				return Array.Empty<byte>();
			}
			if (s.Length > 22000)
			{
				throw new InvalidOperationException("Photo trop volumineuse.");
			}
			byte[] array;
			try
			{
				array = Convert.FromBase64String(s);
			}
			catch (FormatException)
			{
				throw new InvalidOperationException("Photo invalide.");
			}
			if (array.Length < 4 || array.Length > 16384 || array[0] != byte.MaxValue || array[1] != 216 || array[^2] != byte.MaxValue || array[^1] != 217)
			{
				throw new InvalidOperationException("Photo JPEG invalide (16 Ko maximum).");
			}
			if (!Jpeg(array))
			{
				throw new InvalidOperationException("Photo JPEG : dimensions maximum 160 × 200.");
			}
			return array;
		}

		public static bool Jpeg(byte[] bytes, int maxWidth = 160, int maxHeight = 200)
		{
			if (bytes == null || bytes.Length < 16 || bytes.Length > 16384 || bytes[0] != byte.MaxValue || bytes[1] != 216 || bytes[^2] != byte.MaxValue || bytes[^1] != 217)
			{
				return false;
			}
			int i = 2;
			bool result = false;
			while (i + 1 < bytes.Length)
			{
				if (bytes[i++] != byte.MaxValue)
				{
					return false;
				}
				for (; i < bytes.Length && bytes[i] == byte.MaxValue; i++)
				{
				}
				if (i >= bytes.Length)
				{
					return false;
				}
				int num = bytes[i++];
				switch (num)
				{
				case 218:
					return result;
				default:
					if (num != 0)
					{
						if (num >= 208 && num <= 215)
						{
							break;
						}
						if (i + 2 > bytes.Length)
						{
							return false;
						}
						int num2 = (bytes[i] << 8) | bytes[i + 1];
						if (num2 < 2 || i + num2 > bytes.Length)
						{
							return false;
						}
						if (num >= 192 && num <= 207 && num != 192 && num != 194 && num != 196 && num != 200 && num != 204)
						{
							return false;
						}
						if (num == 192 || num == 194)
						{
							if (num2 < 8 || bytes[i + 2] != 8)
							{
								return false;
							}
							int num3 = (bytes[i + 3] << 8) | bytes[i + 4];
							int num4 = (bytes[i + 5] << 8) | bytes[i + 6];
							if (num4 < 1 || num3 < 1 || num4 > maxWidth || num3 > maxHeight)
							{
								return false;
							}
							result = true;
						}
						i += num2;
						break;
					}
					goto case 216;
				case 216:
				case 217:
					return false;
				}
			}
			return false;
		}

		public static IdentityProfile Validate(IdentityProfile p, ulong actor, DateTime today)
		{
			if (p == null)
			{
				throw new InvalidOperationException("Identité manquante.");
			}
			if (!DateTime.TryParseExact(IdentityBirthInput.Normalize(p.BirthDate), "dd/MM/yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out var result) || result.Date > today.Date || result.Year < 1900)
			{
				throw new InvalidOperationException("Naissance : JJ/MM/AAAA entre 1900 et aujourd’hui.");
			}
			Photo(p.Photo);
			return new IdentityProfile
			{
				Owner = actor,
				LastName = Text(p.LastName, 32, required: true),
				FirstName = Text(p.FirstName, 32, required: true),
				BirthDate = result.ToString("dd/MM/yyyy", CultureInfo.InvariantCulture),
				BirthPlace = Text(p.BirthPlace, 48, required: true),
				Nationality = Text(p.Nationality, 32, required: true),
				Sex = Text(p.Sex, 24),
				Photo = (p.Photo ?? "")
			};
		}
	}
	public sealed class IdentityStore
	{
		private readonly string file;

		private Dictionary<ulong, IdentityProfile> profiles;

		public IdentityStore(string file)
		{
			this.file = file;
			profiles = (File.Exists(file) ? (JsonSerializer.Deserialize<Dictionary<ulong, IdentityProfile>>(File.ReadAllText(file)) ?? throw new InvalidDataException("Fichier d’identités vide.")) : new Dictionary<ulong, IdentityProfile>());
			foreach (KeyValuePair<ulong, IdentityProfile> profile in profiles)
			{
				if (profile.Key != profile.Value.Owner || string.IsNullOrEmpty(profile.Value.Number))
				{
					throw new InvalidDataException("Base d’identités incohérente.");
				}
				IdentityRules.Validate(profile.Value, profile.Key, DateTime.Today);
			}
			if (profiles.Values.Select((IdentityProfile p) => p.Number).Distinct().Count() != profiles.Count)
			{
				throw new InvalidDataException("Numéros dupliqués.");
			}
		}

		public IdentityProfile Get(ulong owner)
		{
			IdentityProfile value;
			return profiles.TryGetValue(owner, out value) ? JsonSerializer.Deserialize<IdentityProfile>(JsonSerializer.Serialize(value)) : null;
		}

		public IdentityProfile Save(ulong actor, IdentityProfile input)
		{
			IdentityProfile p = IdentityRules.Validate(input, actor, DateTime.Today);
			if (profiles.TryGetValue(actor, out var value))
			{
				p.Number = value.Number;
				p.Issued = value.Issued;
			}
			else
			{
				do
				{
					p.Number = "RP-" + Guid.NewGuid().ToString("N").Substring(0, 12)
						.ToUpperInvariant();
				}
				while (profiles.Values.Any((IdentityProfile x) => x.Number == p.Number));
				p.Issued = DateTime.Today.ToString("dd/MM/yyyy", CultureInfo.InvariantCulture);
			}
			Dictionary<ulong, IdentityProfile> value2 = new Dictionary<ulong, IdentityProfile>(profiles) { [actor] = p };
			Directory.CreateDirectory(Path.GetDirectoryName(Path.GetFullPath(file)));
			string text = file + ".tmp";
			File.WriteAllText(text, JsonSerializer.Serialize(value2, new JsonSerializerOptions
			{
				WriteIndented = true
			}));
			if (File.Exists(file))
			{
				File.Copy(file, file + ".bak", overwrite: true);
			}
			File.Move(text, file, overwrite: true);
			profiles = value2;
			return Get(actor);
		}
	}
	public sealed class IdentityParking
	{
		private sealed class State
		{
			public GameObject Body;

			public Rigidbody[] Bodies;

			public bool[] OriginalGravity;

			public long Revision;

			public bool Suspended;

			public bool Released;
		}

		private readonly Dictionary<ushort, State> states = new Dictionary<ushort, State>();

		private static bool Holds(Hand hand, GameObject body)
		{
			GameObject val = ((hand != null) ? hand.m_CurrentAttachedGO : null);
			return (Object)(object)val != (Object)null && ((Object)(object)val == (Object)(object)body || val.transform.IsChildOf(body.transform) || body.transform.IsChildOf(val.transform));
		}

		private static bool AnyoneHolds(GameObject body)
		{
			if (Holds(Player.LeftHand, body) || Holds(Player.RightHand, body))
			{
				return true;
			}
			NetworkPlayer val = default(NetworkPlayer);
			foreach (PlayerID playerID in PlayerIDManager.PlayerIDs)
			{
				if (playerID != null && playerID.IsValid && NetworkPlayerManager.TryGetPlayer(playerID.SmallID, ref val) && val.HasRig && (Holds(val.RigRefs.LeftHand, body) || Holds(val.RigRefs.RightHand, body)))
				{
					return true;
				}
			}
			return false;
		}

		private static void Release(State s)
		{
			if (!s.Suspended)
			{
				return;
			}
			for (int i = 0; i < s.Bodies.Length; i++)
			{
				if ((Object)(object)s.Bodies[i] != (Object)null)
				{
					s.Bodies[i].useGravity = s.OriginalGravity[i];
				}
			}
			s.Suspended = false;
		}

		public void Hold(IdentityState d, GameObject supplied = null)
		{
			//IL_025c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0269: Unknown result type (might be due to invalid IL or missing references)
			//IL_020d: Unknown result type (might be due to invalid IL or missing references)
			//IL_021a: Unknown result type (might be due to invalid IL or missing references)
			if (!d.Device.HasValue)
			{
				return;
			}
			if (!states.TryGetValue(d.Device.Value, out var value))
			{
				if (!d.Parked)
				{
					return;
				}
				GameObject val = supplied ?? IdentityMod.Resolve(d.Device.Value);
				if ((Object)(object)val == (Object)null)
				{
					return;
				}
				Il2CppArrayBase<Rigidbody> componentsInChildren = val.GetComponentsInChildren<Rigidbody>();
				value = (states[d.Device.Value] = new State
				{
					Body = val,
					Bodies = Il2CppArrayBase<Rigidbody>.op_Implicit(componentsInChildren),
					OriginalGravity = ((IEnumerable<Rigidbody>)componentsInChildren).Select((Rigidbody rb) => rb.useGravity).ToArray(),
					Revision = d.Placement
				});
			}
			if ((Object)(object)value.Body == (Object)null)
			{
				states.Remove(d.Device.Value);
				return;
			}
			if (value.Revision != d.Placement)
			{
				Release(value);
				value.Revision = d.Placement;
				value.Released = false;
				value.OriginalGravity = value.Bodies.Select((Rigidbody rb) => (Object)(object)rb != (Object)null && rb.useGravity).ToArray();
			}
			if (!d.Parked || AnyoneHolds(value.Body))
			{
				Release(value);
				value.Released = true;
			}
			else
			{
				if (value.Released)
				{
					return;
				}
				if (value.Suspended)
				{
					Rigidbody[] bodies = value.Bodies;
					foreach (Rigidbody val2 in bodies)
					{
						if ((Object)(object)val2 != (Object)null)
						{
							val2.velocity = Vector3.zero;
							val2.angularVelocity = Vector3.zero;
						}
					}
					return;
				}
				Rigidbody[] bodies2 = value.Bodies;
				foreach (Rigidbody val3 in bodies2)
				{
					if ((Object)(object)val3 != (Object)null)
					{
						val3.velocity = Vector3.zero;
						val3.angularVelocity = Vector3.zero;
						val3.useGravity = false;
					}
				}
				value.Suspended = true;
			}
		}

		public void Tick(IEnumerable<IdentityState> catalog)
		{
			IdentityState[] array = catalog.Where((IdentityState identityState) => identityState.Device.HasValue).ToArray();
			HashSet<ushort> active = array.Select((IdentityState identityState) => identityState.Device.Value).ToHashSet();
			ushort[] array2 = states.Keys.Where((ushort id) => !active.Contains(id)).ToArray();
			foreach (ushort key in array2)
			{
				Release(states[key]);
				states.Remove(key);
			}
			IdentityState[] array3 = array;
			foreach (IdentityState d in array3)
			{
				Hold(d);
			}
		}

		public void Clear()
		{
			foreach (State value in states.Values)
			{
				Release(value);
			}
			states.Clear();
		}
	}
	public sealed class IdentityPortrait : IDisposable
	{
		private GameObject go;

		private Camera camera;

		private RenderTexture target;

		private Texture2D pixels;

		private bool disposed;

		public bool Busy { get; private set; }

		public void Capture(Action<string> done, Action<string> fail)
		{
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Expected O, but got Unknown
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Expected O, but got Unknown
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Expected O, but got Unknown
			if (Busy)
			{
				return;
			}
			if ((Object)(object)Player.Head == (Object)null)
			{
				fail("Avatar indisponible.");
				return;
			}
			if ((Object)(object)go == (Object)null)
			{
				go = new GameObject("RP_IdentityPortraitCamera");
				camera = go.AddComponent<Camera>();
				((Behaviour)camera).enabled = false;
				camera.stereoTargetEye = (StereoTargetEyeMask)0;
				camera.fieldOfView = 35f;
				camera.nearClipPlane = 0.04f;
				camera.farClipPlane = 30f;
				camera.cullingMask = -33;
				camera.clearFlags = (CameraClearFlags)1;
				camera.allowHDR = false;
				camera.allowMSAA = false;
				target = new RenderTexture(160, 200, 24, (RenderTextureFormat)0);
				target.Create();
				pixels = new Texture2D(160, 200, (TextureFormat)3, false);
			}
			Transform head = Player.Head;
			Vector3 val = head.position - Vector3.up * 0.08f;
			((Component)camera).transform.position = head.position + head.forward * 0.8f;
			((Component)camera).transform.rotation = Quaternion.LookRotation(val - ((Component)camera).transform.position, Vector3.up);
			camera.aspect = 0.8f;
			camera.targetTexture = target;
			((Behaviour)camera).enabled = true;
			Busy = true;
			MelonCoroutines.Start(Read(done, fail));
		}

		private IEnumerator Read(Action<string> done, Action<string> fail)
		{
			yield return (object)new WaitForEndOfFrame();
			if (disposed)
			{
				Busy = false;
				yield break;
			}
			try
			{
				((Behaviour)camera).enabled = false;
				RenderTexture old = RenderTexture.active;
				try
				{
					RenderTexture.active = target;
					pixels.ReadPixels(new Rect(0f, 0f, 160f, 200f), 0, 0, false);
					pixels.Apply(false, false);
				}
				finally
				{
					RenderTexture.active = old;
				}
				byte[] bytes = null;
				int[] array = new int[4] { 65, 45, 25, 15 };
				foreach (int q in array)
				{
					bytes = ((IEnumerable<byte>)ImageConversion.EncodeToJPG(pixels, q)).ToArray();
					if (bytes.Length <= 16384)
					{
						break;
					}
				}
				string photo = Convert.ToBase64String(bytes);
				IdentityRules.Photo(photo);
				done(photo);
			}
			catch (Exception ex)
			{
				Exception e = ex;
				fail(e.Message);
			}
			finally
			{
				if ((Object)(object)camera != (Object)null)
				{
					((Behaviour)camera).enabled = false;
				}
				Busy = false;
			}
		}

		public void Dispose()
		{
			disposed = true;
			if ((Object)(object)camera != (Object)null)
			{
				((Behaviour)camera).enabled = false;
			}
			if ((Object)(object)go != (Object)null)
			{
				Object.Destroy((Object)(object)go);
			}
			if ((Object)(object)target != (Object)null)
			{
				target.Release();
				Object.Destroy((Object)(object)target);
			}
			if ((Object)(object)pixels != (Object)null)
			{
				Object.Destroy((Object)(object)pixels);
			}
		}
	}
	public sealed class IdentitySurface : IDisposable
	{
		private readonly GameObject body;

		private readonly GameObject root;

		private readonly List<Action> restoreRenderers = new List<Action>();

		private readonly HashSet<Renderer> hiddenRenderers = new HashSet<Renderer>();

		private readonly bool english;

		private readonly IdentityProfile profile;

		private readonly CardLayout layout;

		private readonly List<GameObject> faces = new List<GameObject>();

		private Texture2D portrait;

		private Texture2D roundedTexture;

		private Sprite roundedSprite;

		private Vector3 previousMin;

		private Vector3 previousMax;

		private Vector3 previousBodyScale;

		private int stableSamples;

		private readonly List<Vector3> facePositions = new List<Vector3>();

		private readonly List<Vector3> faceScales = new List<Vector3>();

		private readonly List<Quaternion> faceRotations = new List<Quaternion>();

		private bool fitted;

		private float next;

		private Vector3 fittedMin;

		private Vector3 fittedMax;

		private Vector3 fittedBodyScale;

		public bool Alive => (Object)(object)body != (Object)null;

		public IdentitySurface(GameObject body, IdentityProfile profile, CardLayout layout, bool english = false)
		{
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Expected O, but got Unknown
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Expected O, but got Unknown
			this.english = english;
			this.body = body;
			this.profile = profile;
			this.layout = layout;
			root = new GameObject("RP_IdentityCard_UI");
			root.transform.SetParent(body.transform, false);
			root.SetActive(false);
			CreateRoundedSprite();
			if (profile.Photo != "")
			{
				portrait = new Texture2D(2, 2, (TextureFormat)3, false);
				if (!ImageConversion.LoadImage(portrait, Il2CppStructArray<byte>.op_Implicit(IdentityRules.Photo(profile.Photo)), false))
				{
					Object.Destroy((Object)(object)portrait);
					portrait = null;
				}
			}
		}

		private GameObject Element(Transform parent, string name, float x, float y, float w, float h)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_0024: 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)
			GameObject val = new GameObject(name);
			val.layer = 5;
			RectTransform val2 = val.AddComponent<RectTransform>();
			((Transform)val2).SetParent(parent, false);
			val2.anchoredPosition = new Vector2(x, y);
			val2.sizeDelta = new Vector2(w, h);
			return val;
		}

		private void Panel(Transform parent, float x, float y, float w, float h, Color color)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			Image val = Element(parent, "Panel", x, y, w, h).AddComponent<Image>();
			((Graphic)val).color = color;
			((Graphic)val).raycastTarget = false;
		}

		private void Text(Transform parent, string text, float x, float y, float w, float h, float size, Color color)
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			TextMeshProUGUI val = Element(parent, "Label", x, y, w, h).AddComponent<TextMeshProUGUI>();
			((TMP_Text)val).font = TMP_Settings.defaultFontAsset;
			((TMP_Text)val).text = text;
			((TMP_Text)val).fontSize = size;
			((TMP_Text)val).fontStyle = (FontStyles)1;
			((Graphic)val).color = color;
			((TMP_Text)val).richText = false;
			((TMP_Text)val).enableWordWrapping = true;
			((TMP_Text)val).enableAutoSizing = true;
			((TMP_Text)val).fontSizeMax = size;
			((TMP_Text)val).fontSizeMin = size * 0.8f;
			((TMP_Text)val).alignment = (TextAlignmentOptions)513;
			((Graphic)val).raycastTarget = false;
		}

		private void Field(Transform p, string label, string value, float y)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			Text(p, label, 160f, y, 600f, 28f, 24f, new Color(0.35f, 0.43f, 0.5f, 1f));
			Text(p, value, 160f, y - 35f, 600f, 52f, 40f, new Color(0.05f, 0.12f, 0.18f, 1f));
		}

		private void Draw(Transform p)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_02af: Unknown result type (might be due to invalid IL or missing references)
			//IL_0309: Unknown result type (might be due to invalid IL or missing references)
			//IL_033e: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ad: Unknown result type (might be due to invalid IL or missing references)
			Panel(p, 0f, 0f, 1000f, 630f, new Color(0.93f, 0.96f, 0.97f, 1f));
			Panel(p, 0f, 245f, 1000f, 140f, new Color(0.03f, 0.16f, 0.27f, 1f));
			Text(p, english ? "IDENTIFICATION CARD" : "CARTE D’IDENTITÉ", 15f, 269f, 870f, 50f, 42f, Color.white);
			Text(p, "Document Officiel - WindyLab City", 15f, 219f, 870f, 30f, 18f, new Color(0.68f, 0.86f, 0.91f, 1f));
			Panel(p, -335f, -15f, 255f, 330f, new Color(0.76f, 0.83f, 0.87f, 1f));
			if ((Object)(object)portrait != (Object)null)
			{
				RawImage val = Element(p, "Portrait", -335f, -15f, 250f, 312f).AddComponent<RawImage>();
				val.texture = (Texture)(object)portrait;
				((Graphic)val).raycastTarget = false;
			}
			else
			{
				Text(p, english ? "ADD\nPHOTO" : "PHOTO\nÀ AJOUTER", -335f, -15f, 210f, 100f, 25f, new Color(0.2f, 0.3f, 0.4f, 1f));
			}
			Field(p, english ? "LAST NAME" : "NOM", profile.LastName, 157f);
			Field(p, english ? "FIRST NAME" : "PRÉNOM", profile.FirstName, 76f);
			Field(p, english ? "DATE OF BIRTH" : "DATE DE NAISSANCE", DisplayDate(profile.BirthDate), -5f);
			Field(p, english ? "PLACE OF BIRTH" : "LIEU DE NAISSANCE", profile.BirthPlace, -86f);
			Text(p, english ? "NATIONALITY / SEX" : "NATIONALITÉ / SEXE", 110f, -175f, 600f, 28f, 23f, new Color(0.35f, 0.43f, 0.5f, 1f));
			Text(p, profile.Nationality + "  •  " + profile.Sex, 110f, -209f, 600f, 52f, 36f, new Color(0.05f, 0.12f, 0.18f, 1f));
			Panel(p, 0f, -280f, 1000f, 70f, new Color(0.82f, 0.89f, 0.91f, 1f));
			Text(p, profile.Number + (english ? "   •   Issued " : "   •   Émise le ") + DisplayDate(profile.Issued), 0f, -280f, 910f, 48f, 26f, new Color(0.05f, 0.12f, 0.18f, 1f));
		}

		public void Tick()
		{
			//IL_023d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0242: Unknown result type (might be due to invalid IL or missing references)
			//IL_024b: Unknown result type (might be due to invalid IL or missing references)
			//IL_024d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0252: Unknown result type (might be due to invalid IL or missing references)
			//IL_0257: Unknown result type (might be due to invalid IL or missing references)
			//IL_0267: Unknown result type (might be due to invalid IL or missing references)
			//IL_0269: Unknown result type (might be due to invalid IL or missing references)
			//IL_026e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0273: Unknown result type (might be due to invalid IL or missing references)
			//IL_0283: Unknown result type (might be due to invalid IL or missing references)
			//IL_0285: Unknown result type (might be due to invalid IL or missing references)
			//IL_028a: Unknown result type (might be due to invalid IL or missing references)
			//IL_028f: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0300: Unknown result type (might be due to invalid IL or missing references)
			//IL_0305: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0315: Unknown result type (might be due to invalid IL or missing references)
			//IL_0317: Unknown result type (might be due to invalid IL or missing references)
			//IL_031c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0321: Unknown result type (might be due to invalid IL or missing references)
			//IL_0331: Unknown result type (might be due to invalid IL or missing references)
			//IL_0333: Unknown result type (might be due to invalid IL or missing references)
			//IL_0338: Unknown result type (might be due to invalid IL or missing references)
			//IL_033d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_036e: Unknown result type (might be due to invalid IL or missing references)
			//IL_036f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0375: Unknown result type (might be due to invalid IL or missing references)
			//IL_0376: Unknown result type (might be due to invalid IL or missing references)
			//IL_037c: Unknown result type (might be due to invalid IL or missing references)
			//IL_037d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0396: Unknown result type (might be due to invalid IL or missing references)
			//IL_0397: Unknown result type (might be due to invalid IL or missing references)
			//IL_0398: Unknown result type (might be due to invalid IL or missing references)
			//IL_039d: Unknown result type (might be due to invalid IL or missing references)
			//IL_039f: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03af: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0403: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_041a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0411: Unknown result type (might be due to invalid IL or missing references)
			//IL_0454: Unknown result type (might be due to invalid IL or missing references)
			//IL_044b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0442: Unknown result type (might be due to invalid IL or missing references)
			//IL_0488: Unknown result type (might be due to invalid IL or missing references)
			//IL_048d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0492: Unknown result type (might be due to invalid IL or missing references)
			//IL_049f: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_04bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_04de: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_0505: Unknown result type (might be due to invalid IL or missing references)
			//IL_050a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0511: Unknown result type (might be due to invalid IL or missing references)
			//IL_0516: Unknown result type (might be due to invalid IL or missing references)
			//IL_051b: Unknown result type (might be due to invalid IL or missing references)
			//IL_051d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0522: Unknown result type (might be due to invalid IL or missing references)
			//IL_0594: Unknown result type (might be due to invalid IL or missing references)
			//IL_059b: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_05a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0576: Unknown result type (might be due to invalid IL or missing references)
			//IL_057d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0558: Unknown result type (might be due to invalid IL or missing references)
			//IL_055f: Unknown result type (might be due to invalid IL or missing references)
			//IL_05b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_05e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_05f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_05f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_05fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_05fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_05fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0606: Unknown result type (might be due to invalid IL or missing references)
			//IL_062c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0631: Unknown result type (might be due to invalid IL or missing references)
			//IL_0636: Unknown result type (might be due to invalid IL or missing references)
			//IL_058d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0586: Unknown result type (might be due to invalid IL or missing references)
			//IL_056f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0568: Unknown result type (might be due to invalid IL or missing references)
			//IL_065c: Unknown result type (might be due to invalid IL or missing references)
			//IL_065e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0672: Unknown result type (might be due to invalid IL or missing references)
			//IL_0677: Unknown result type (might be due to invalid IL or missing references)
			//IL_067c: Unknown result type (might be due to invalid IL or missing references)
			//IL_067e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0680: Unknown result type (might be due to invalid IL or missing references)
			//IL_0688: Unknown result type (might be due to invalid IL or missing references)
			//IL_068d: Unknown result type (might be due to invalid IL or missing references)
			//IL_068f: Unknown result type (might be due to invalid IL or missing references)
			//IL_06a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_06ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_06b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_083c: Unknown result type (might be due to invalid IL or missing references)
			//IL_083d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0843: Unknown result type (might be due to invalid IL or missing references)
			//IL_0844: Unknown result type (might be due to invalid IL or missing references)
			//IL_084a: Unknown result type (might be due to invalid IL or missing references)
			//IL_084b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0702: Unknown result type (might be due to invalid IL or missing references)
			//IL_0709: Expected O, but got Unknown
			//IL_073b: Unknown result type (might be due to invalid IL or missing references)
			//IL_074d: Unknown result type (might be due to invalid IL or missing references)
			//IL_075c: Unknown result type (might be due to invalid IL or missing references)
			//IL_076b: Unknown result type (might be due to invalid IL or missing references)
			//IL_07bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_07ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_080d: Unknown result type (might be due to invalid IL or missing references)
			//IL_081b: Unknown result type (might be due to invalid IL or missing references)
			//IL_06ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_06da: Unknown result type (might be due to invalid IL or missing references)
			//IL_06ea: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)body == (Object)null)
			{
				return;
			}
			if (fitted)
			{
				ApplyFit();
			}
			if (Time.realtimeSinceStartup < next)
			{
				return;
			}
			next = Time.realtimeSinceStartup + (fitted ? 0.5f : 0.15f);
			HidePropMeshes();
			Vector3 val = default(Vector3);
			((Vector3)(ref val))..ctor(float.MaxValue, float.MaxValue, float.MaxValue);
			Vector3 val2 = default(Vector3);
			((Vector3)(ref val2))..ctor(float.MinValue, float.MinValue, float.MinValue);
			bool flag = false;
			Vector3 val4 = default(Vector3);
			foreach (Renderer componentsInChild in body.GetComponentsInChildren<Renderer>())
			{
				if ((Object)(object)componentsInChild == (Object)null || ((Component)componentsInChild).transform.IsChildOf(root.transform))
				{
					continue;
				}
				MeshFilter component = ((Component)componentsInChild).GetComponent<MeshFilter>();
				object obj = ((component != null) ? component.sharedMesh : null);
				if (obj == null)
				{
					SkinnedMeshRenderer component2 = ((Component)componentsInChild).GetComponent<SkinnedMeshRenderer>();
					obj = ((component2 != null) ? component2.sharedMesh : null);
				}
				Mesh val3 = (Mesh)obj;
				if (!((Object)(object)val3 == (Object)null))
				{
					Bounds bounds = val3.bounds;
					for (int i = 0; i < 8; i++)
					{
						((Vector3)(ref val4))..ctor(((i & 1) == 0) ? ((Bounds)(ref bounds)).min.x : ((Bounds)(ref bounds)).max.x, ((i & 2) == 0) ? ((Bounds)(ref bounds)).min.y : ((Bounds)(ref bounds)).max.y, ((i & 4) == 0) ? ((Bounds)(ref bounds)).min.z : ((Bounds)(ref bounds)).max.z);
						Vector3 val5 = body.transform.InverseTransformPoint(((Component)componentsInChild).transform.TransformPoint(val4));
						val = Vector3.Min(val, val5);
						val2 = Vector3.Max(val2, val5);
						flag = true;
					}
				}
			}
			if (!flag)
			{
				if (!fitted)
				{
					root.SetActive(false);
				}
				return;
			}
			Vector3 lossyScale = body.transform.lossyScale;
			Vector3 val6;
			if (fitted)
			{
				val6 = val - fittedMin;
				if (!(((Vector3)(ref val6)).sqrMagnitude > 1E-08f))
				{
					val6 = val2 - fittedMax;
					if (!(((Vector3)(ref val6)).sqrMagnitude > 1E-08f))
					{
						val6 = lossyScale - fittedBodyScale;
						if (!(((Vector3)(ref val6)).sqrMagnitude > 1E-08f))
						{
							if (!root.activeSelf)
							{
								root.SetActive(true);
							}
							ApplyFit();
							return;
						}
					}
				}
			}
			if (!fitted)
			{
				root.SetActive(false);
			}
			val6 = val - previousMin;
			if (((Vector3)(ref val6)).sqrMagnitude < 1E-08f)
			{
				val6 = val2 - previousMax;
				if (((Vector3)(ref val6)).sqrMagnitude < 1E-08f)
				{
					val6 = lossyScale - previousBodyScale;
					if (((Vector3)(ref val6)).sqrMagnitude < 1E-08f)
					{
						stableSamples++;
						goto IL_036d;
					}
				}
			}
			stableSamples = 0;
			goto IL_036d;
			IL_036d:
			previousMin = val;
			previousMax = val2;
			previousBodyScale = lossyScale;
			if (stableSamples < 2)
			{
				return;
			}
			Vector3 val7 = val2 - val;
			int num = ((!(val7.x <= val7.y) || !(val7.x <= val7.z)) ? ((val7.y <= val7.z) ? 1 : 2) : 0);
			Vector3 val8 = (Vector3)(num switch
			{
				1 => Vector3.up, 
				0 => Vector3.right, 
				_ => Vector3.forward, 
			});
			float num2 = ((num == 0) ? val7.y : val7.x);
			float num3 = ((num == 2) ? val7.y : val7.z);
			float num4 = Mathf.Max(num2, num3);
			float num5 = Mathf.Min(num2, num3);
			float num6 = num switch
			{
				1 => val7.y, 
				0 => val7.x, 
				_ => val7.z, 
			};
			if (num4 < 0.001f || num5 < 0.001f)
			{
				return;
			}
			Vector3 val9 = body.transform.TransformPoint(Vector3.zero);
			val6 = body.transform.TransformPoint(Vector3.right * val7.x) - val9;
			float magnitude = ((Vector3)(ref val6)).magnitude;
			val6 = body.transform.TransformPoint(Vector3.up * val7.y) - val9;
			float magnitude2 = ((Vector3)(ref val6)).magnitude;
			val6 = body.transform.TransformPoint(Vector3.forward * val7.z) - val9;
			float magnitude3 = ((Vector3)(ref val6)).magnitude;
			if (Mathf.Max(magnitude, Mathf.Max(magnitude2, magnitude3)) > 0.5f)
			{
				return;
			}
			Vector3 val10 = (Vector3)(num switch
			{
				1 => (val7.x < val7.z) ? Vector3.right : Vector3.forward, 
				0 => (val7.y < val7.z) ? Vector3.up : Vector3.forward, 
				_ => (val7.x < val7.y) ? Vector3.right : Vector3.up, 
			});
			Vector3 val11 = new Vector3(num4 * 0.985f / 1000f, num5 * 0.985f / 630f, Mathf.Min(num4 / 1000f, num5 / 630f)) * layout.Scale;
			Vector3 val12 = (val + val2) * 0.5f + new Vector3(layout.X, layout.Y, layout.Z);
			int num7 = 0;
			int[] array = new int[2] { 1, -1 };
			foreach (int num8 in array)
			{
				Vector3 val13 = val12 + val8 * ((float)num8 * (num6 * 0.5f + 0.0004f));
				Quaternion val14 = Quaternion.LookRotation(-val8 * (float)num8, val10) * Quaternion.Euler(0f, 0f, layout.Rotation);
				if (fitted)
				{
					facePositions[num7] = val13;
					faceRotations[num7] = val14;
					faceScales[num7] = val11;
					num7++;
					continue;
				}
				GameObject val15 = new GameObject("RP_CardFace");
				val15.layer = 5;
				RectTransform val16 = val15.AddComponent<RectTransform>();
				((Transform)val16).SetParent(root.transform, false);
				val16.sizeDelta = new Vector2(1000f, 630f);
				val15.transform.localPosition = val13;
				val15.transform.localRotation = val14;
				val15.transform.localScale = val11;
				Canvas val17 = val15.AddComponent<Canvas>();
				val17.renderMode = (RenderMode)2;
				Image val18 = val15.AddComponent<Image>();
				val18.sprite = roundedSprite;
				val18.type = (Type)1;
				((Graphic)val18).color = new Color(0.93f, 0.96f, 0.97f, 1f);
				((Graphic)val18).raycastTarget = false;
				val15.AddComponent<Mask>().showMaskGraphic = true;
				Draw(val15.transform);
				faces.Add(val15);
				facePositions.Add(val13);
				faceRotations.Add(val14);
				faceScales.Add(val11);
				num7++;
			}
			fittedMin = val;
			fittedMax = val2;
			fittedBodyScale = lossyScale;
			fitted = true;
			root.SetActive(true);
			ApplyFit();
		}

		private string DisplayDate(string value)
		{
			DateTime result;
			return (english && DateTime.TryParseExact(value, "dd/MM/yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out result)) ? result.ToString("MM/dd/yyyy", CultureInfo.InvariantCulture) : value;
		}

		private void HidePropMeshes()
		{
			foreach (Renderer renderer in body.GetComponentsInChildren<Renderer>())
			{
				if ((Object)(object)renderer == (Object)null || ((Component)renderer).transform.IsChildOf(root.transform) || hiddenRenderers.Contains(renderer))
				{
					continue;
				}
				MeshFilter component = ((Component)renderer).GetComponent<MeshFilter>();
				if ((Object)(object)((component != null) ? component.sharedMesh : null) == (Object)null)
				{
					SkinnedMeshRenderer component2 = ((Component)renderer).GetComponent<SkinnedMeshRenderer>();
					if ((Object)(object)((component2 != null) ? component2.sharedMesh : null) == (Object)null)
					{
						continue;
					}
				}
				bool original = renderer.enabled;
				renderer.enabled = false;
				hiddenRenderers.Add(renderer);
				restoreRenderers.Add(delegate
				{
					if ((Object)(object)renderer != (Object)null)
					{
						renderer.enabled = original;
					}
				});
			}
		}

		private void ApplyFit()
		{
			//IL_000c: 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_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			root.transform.localScale = Vector3.one;
			for (int i = 0; i < faces.Count; i++)
			{
				RectTransform component = faces[i].GetComponent<RectTransform>();
				component.sizeDelta = new Vector2(1000f, 630f);
				faces[i].transform.localPosition = facePositions[i];
				faces[i].transform.localRotation = faceRotations[i];
				faces[i].transform.localScale = faceScales[i];
			}
		}

		private void CreateRoundedSprite()
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			roundedTexture = new Texture2D(128, 128, (TextureFormat)4, false);
			((Object)roundedTexture).name = "RP_IdentityRoundedCorners";
			((Texture)roundedTexture).filterMode = (FilterMode)1;
			((Texture)roundedTexture).wrapMode = (TextureWrapMode)1;
			Color[] array = (Color[])(object)new Color[16384];
			for (int i = 0; i < 128; i++)
			{
				for (int j = 0; j < 128; j++)
				{
					float num = MathF.Max(MathF.Abs((float)j + 0.5f - 64f) - 40f, 0f);
					float num2 = MathF.Max(MathF.Abs((float)i + 0.5f - 64f) - 40f, 0f);
					array[i * 128 + j] = new Color(1f, 1f, 1f, Math.Clamp(0.5f - (MathF.Sqrt(num * num + num2 * num2) - 24f), 0f, 1f));
				}
			}
			roundedTexture.SetPixels(Il2CppStructArray<Color>.op_Implicit(array));
			roundedTexture.Apply(false, false);
			roundedSprite = Sprite.Create(roundedTexture, new Rect(0f, 0f, 128f, 128f), new Vector2(0.5f, 0.5f), 100f, 0u, (SpriteMeshType)0, new Vector4(24f, 24f, 24f, 24f));
		}

		public void Dispose()
		{
			foreach (Action restoreRenderer in restoreRenderers)
			{
				restoreRenderer();
			}
			restoreRenderers.Clear();
			hiddenRenderers.Clear();
			if ((Object)(object)root != (Object)null)
			{
				Object.Destroy((Object)(object)root);
			}
			if ((Object)(object)portrait != (Object)null)
			{
				Object.Destroy((Object)(object)portrait);
			}
			if ((Object)(object)roundedSprite != (Object)null)
			{
				Object.Destroy((Object)(object)roundedSprite);
			}
			if ((Object)(object)roundedTexture != (Object)null)
			{
				Object.Destroy((Object)(object)roundedTexture);
			}
		}
	}
	public sealed class IdentityPacket : INetSerializable
	{
		public byte[] Payload = Array.Empty<byte>();

		public int? GetSize()
		{
			return 4 + Payload.Length;
		}

		public void Serialize(INetSerializer serializer)
		{
			serializer.SerializeValue(ref Payload);
		}

		public static IdentityPacket From<T>(T value)
		{
			return new IdentityPacket
			{
				Payload = JsonSerializer.SerializeToUtf8Bytes(value)
			};
		}
	}
	public sealed class IdentityCommandMessage : ModuleMessageHandler
	{
		public override ExpectedReceiverType ExpectedReceiver => (ExpectedReceiverType)1;

		protected override void OnHandleMessage(ReceivedMessage message)
		{
			if (!NetworkInfo.IsHost || !((ReceivedMessage)(ref message)).IsServerHandled || !((ReceivedMessage)(ref message)).Sender.HasValue || ((ReceivedMessage)(ref message)).Bytes.Length > 32768)
			{
				return;
			}
			try
			{
				PlayerID playerID = PlayerIDManager.GetPlayerID(((ReceivedMessage)(ref message)).Sender.Value);
				if (playerID == null || !playerID.IsValid)
				{
					return;
				}
				byte[] payload = ((ReceivedMessage)(ref message)).ReadData<IdentityPacket>().Payload;
				if (payload != null && payload.Length <= 32000)
				{
					IdentityCommand identityCommand = JsonSerializer.Deserialize<IdentityCommand>(payload);
					if (identityCommand != null)
					{
						IdentityMod.Instance?.Enqueue(playerID.PlatformID, identityCommand);
					}
				}
			}
			catch (Exception)
			{
			}
		}
	}
	public sealed class IdentityStateMessage : ModuleMessageHandler
	{
		public override ExpectedReceiverType ExpectedReceiver => (ExpectedReceiverType)2;

		protected override void OnHandleMessage(ReceivedMessage message)
		{
			if (NetworkInfo.IsHost || ((ReceivedMessage)(ref message)).IsServerHandled || ((ReceivedMessage)(ref message)).Sender != 0 || ((ReceivedMessage)(ref message)).Bytes.Length > 262144)
			{
				return;
			}
			try
			{
				byte[] payload = ((ReceivedMessage)(ref message)).ReadData<IdentityPacket>().Payload;
				if (payload != null && payload.Length <= 260000)
				{
					IdentityState identityState = JsonSerializer.Deserialize<IdentityState>(payload);
					if (identityState != null && identityState.Protocol == 2)
					{
						IdentityMod.Instance?.EnqueueState(identityState);
					}
				}
			}
			catch (Exception)
			{
			}
		}
	}
	public static class IdentityTransport
	{
		public static void Register()
		{
			if (ModuleMessageManager.GetHandlerByType(typeof(IdentityCommandMessage)) == null)
			{
				ModuleMessageManager.RegisterHandler<IdentityCommandMessage>();
			}
			if (ModuleMessageManager.GetHandlerByType(typeof(IdentityStateMessage)) == null)
			{
				ModuleMessageManager.RegisterHandler<IdentityStateMessage>();
			}
		}

		public static void Send(IdentityCommand command)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			MessageRelay.RelayModule<IdentityCommandMessage, IdentityPacket>(IdentityPacket.From(command), CommonMessageRoutes.ReliableToServer);
		}

		public static void Reply(IdentityState view, byte id)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			MessageRelay.RelayModule<IdentityStateMessage, IdentityPacket>(IdentityPacket.From(view), new MessageRoute(id, (NetworkChannel)0));
		}
	}
}