Decompiled source of ImReave Twitch Integration v0.10.12

plugins/ImReave_Twitch_Integration.dll

Decompiled 2 months ago
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Net.WebSockets;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using ExitGames.Client.Photon;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Peak.UI;
using Photon.Pun;
using Photon.Realtime;
using Photon.Voice;
using Photon.Voice.Unity;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using Zorro.Core;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("ImReave_Twitch_Integration")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.10.12.0")]
[assembly: AssemblyInformationalVersion("0.10.12")]
[assembly: AssemblyProduct("ImReave_Twitch_Integration")]
[assembly: AssemblyTitle("ImReave_Twitch_Integration")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.10.12.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace PeakTwitchIntegration
{
	internal sealed class BanishmentController : MonoBehaviour
	{
		private sealed class GhostChoice
		{
			internal int ActorNumber { get; }

			internal string Name { get; }

			internal GhostChoice(int actorNumber, string name)
			{
				ActorNumber = actorNumber;
				Name = name;
			}
		}

		private sealed class GhostChoiceRow
		{
			internal int ActorNumber { get; }

			internal GameObject Root { get; }

			internal Image Background { get; }

			internal TextMeshProUGUI Name { get; }

			internal GhostChoiceRow(int actorNumber, GameObject root, Image background, TextMeshProUGUI name)
			{
				ActorNumber = actorNumber;
				Root = root;
				Background = background;
				Name = name;
			}
		}

		private sealed class GhostVisibilityState
		{
			private readonly Renderer[] _renderers;

			private readonly bool[] _originalEnabled;

			internal PlayerGhost Ghost { get; }

			internal GhostVisibilityState(PlayerGhost ghost)
			{
				Ghost = ghost;
				_renderers = ((Component)ghost).GetComponentsInChildren<Renderer>(true);
				_originalEnabled = new bool[_renderers.Length];
				for (int i = 0; i < _renderers.Length; i++)
				{
					_originalEnabled[i] = (Object)(object)_renderers[i] != (Object)null && _renderers[i].enabled;
				}
			}

			internal void Hide()
			{
				for (int i = 0; i < _renderers.Length; i++)
				{
					if ((Object)(object)_renderers[i] != (Object)null)
					{
						_renderers[i].enabled = false;
					}
				}
			}

			internal void Restore()
			{
				for (int i = 0; i < _renderers.Length; i++)
				{
					if ((Object)(object)_renderers[i] != (Object)null)
					{
						_renderers[i].enabled = _originalEnabled[i];
					}
				}
			}
		}

		internal const string PrefabName = "ImReave_BanishmentCross";

		internal const ushort ItemId = 64871;

		internal const DataEntryKey BoundGhostActorKey = (DataEntryKey)201;

		private const byte BanishRequestEventCode = 182;

		private const byte BanishStateEventCode = 183;

		private const byte BanishResultEventCode = 184;

		private const string BanishRoomKeyPrefix = "PTI_BANISH_";

		private const string BeachSpawnRunKey = "PTI_BANISH_BEACH_RUN";

		private const float BeachSpawnReadyDelay = 7f;

		private const float RoomStateSyncIntervalSeconds = 0.25f;

		private const float CrossLootChancePerSlot = 0.005f;

		private static readonly (Key Key, string Label)[] GhostSelectionKeys = new(Key, string)[26]
		{
			((Key)15, "A"),
			((Key)33, "S"),
			((Key)18, "D"),
			((Key)20, "F"),
			((Key)21, "G"),
			((Key)22, "H"),
			((Key)24, "J"),
			((Key)25, "K"),
			((Key)26, "L"),
			((Key)31, "Q"),
			((Key)37, "W"),
			((Key)19, "E"),
			((Key)32, "R"),
			((Key)34, "T"),
			((Key)40, "Z"),
			((Key)35, "U"),
			((Key)23, "I"),
			((Key)29, "O"),
			((Key)30, "P"),
			((Key)39, "Y"),
			((Key)38, "X"),
			((Key)17, "C"),
			((Key)36, "V"),
			((Key)16, "B"),
			((Key)28, "N"),
			((Key)27, "M")
		};

		private static readonly SpawnPool[] CrossLuggagePools;

		private static int _suppressInputThroughFrame;

		private readonly HashSet<int> _banishedActors = new HashSet<int>();

		private readonly Dictionary<int, int> _pendingItemBindings = new Dictionary<int, int>();

		private readonly Dictionary<int, GhostVisibilityState> _hiddenGhosts = new Dictionary<int, GhostVisibilityState>();

		private Room? _trackedRoom;

		private GameObject? _itemPrefab;

		private Texture2D? _itemIcon;

		private float _nextRegistrationAttempt;

		private float _nextRoomStateSyncAt;

		private float _nextRoomSweep;

		private float _beachReadySince = -1f;

		private string _locallySpawnedRunId = string.Empty;

		private bool _inputOpen;

		private bool _submissionPending;

		private BanishmentItemBehaviour? _inputItem;

		private GameObject? _inputRoot;

		private TextMeshProUGUI? _inputMessage;

		private RectTransform? _ghostListContent;

		private Button? _banishButton;

		private TextMeshProUGUI? _banishButtonLabel;

		private readonly List<GhostChoice> _ghostChoices = new List<GhostChoice>();

		private readonly List<GhostChoiceRow> _ghostRows = new List<GhostChoiceRow>();

		private int _selectedGhostActorNumber = -1;

		private string _ghostListSignature = string.Empty;

		private float _nextGhostListRefreshAt;

		private bool _previousItemSwitchBlocked;

		private CursorLockMode _previousCursorLock;

		private bool _previousCursorVisible;

		private int _lastSubmitFrame = -1;

		private GameObject? _toastRoot;

		private TextMeshProUGUI? _toastLabel;

		private string _toastText = string.Empty;

		private float _toastUntil;

		private GameObject? _banishedRoot;

		internal static bool IsInputOpen
		{
			get
			{
				if ((Object)(object)Plugin.Banishment != (Object)null)
				{
					if (!Plugin.Banishment._inputOpen)
					{
						return Time.frameCount <= _suppressInputThroughFrame;
					}
					return true;
				}
				return false;
			}
		}

		internal static bool IsSelectionWindowOpen
		{
			get
			{
				if ((Object)(object)Plugin.Banishment != (Object)null)
				{
					return Plugin.Banishment._inputOpen;
				}
				return false;
			}
		}

		internal static void ConsumePauseInput(CharacterInput input)
		{
			BanishmentController banishment = Plugin.Banishment;
			if ((Object)(object)banishment != (Object)null && banishment._inputOpen && input.pauseWasPressed)
			{
				banishment.CloseInput();
			}
			if (IsInputOpen)
			{
				SuppressCharacterInput(input);
			}
		}

		internal bool IsActorBanished(int actorNumber)
		{
			return _banishedActors.Contains(actorNumber);
		}

		private void Awake()
		{
			PhotonNetwork.NetworkingClient.EventReceived += OnPhotonEvent;
		}

		private void Update()
		{
			TryRegisterItemPrefab();
			SynchronizeRoomState();
			ResolvePendingItemBindings();
			UpdateInputWindow();
			UpdateHostBanishments();
			UpdateBanishedGhostVisibility();
			TrySpawnBeachCross();
		}

		private void LateUpdate()
		{
			UpdateStatusOverlays();
		}

		internal void Open(BanishmentItemBehaviour source)
		{
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			Item item = source.Item;
			Character localCharacter = Character.localCharacter;
			if ((Object)(object)localCharacter == (Object)null || (Object)(object)localCharacter.data == (Object)null || localCharacter.data.dead || (Object)(object)item == (Object)null || (Object)(object)item.holderCharacter != (Object)(object)localCharacter || (Object)(object)localCharacter.data.currentItem != (Object)(object)item)
			{
				return;
			}
			int boundActorNumber = source.BoundActorNumber;
			if (boundActorNumber > 0 && IsActorBanished(boundActorNumber))
			{
				ShowToast("DIESES KREUZ HAT BEREITS EINEN GEIST GEBUNDEN.", 4f);
				return;
			}
			EnsureInputUi();
			_inputItem = source;
			_inputOpen = true;
			_submissionPending = false;
			_lastSubmitFrame = -1;
			_selectedGhostActorNumber = -1;
			_ghostListSignature = string.Empty;
			_nextGhostListRefreshAt = 0f;
			((TMP_Text)_inputMessage).text = "WÄHLE EINEN VERFÜGBAREN GEIST AUS";
			((Graphic)_inputMessage).color = Color32.op_Implicit(new Color32((byte)218, (byte)232, (byte)220, byte.MaxValue));
			_inputRoot.SetActive(true);
			RefreshGhostChoices(force: true);
			_previousCursorLock = Cursor.lockState;
			_previousCursorVisible = Cursor.visible;
			Cursor.lockState = (CursorLockMode)1;
			Cursor.visible = false;
			if ((Object)(object)localCharacter.input != (Object)null)
			{
				_previousItemSwitchBlocked = localCharacter.input.itemSwitchBlocked;
				localCharacter.input.itemSwitchBlocked = true;
				SuppressCharacterInput(localCharacter.input);
			}
		}

		private void CloseInput()
		{
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			if (_inputOpen)
			{
				_inputOpen = false;
				_submissionPending = false;
				_inputItem = null;
				_selectedGhostActorNumber = -1;
				_suppressInputThroughFrame = Time.frameCount + 1;
				if ((Object)(object)_inputRoot != (Object)null)
				{
					_inputRoot.SetActive(false);
				}
				Character localCharacter = Character.localCharacter;
				if ((Object)(object)localCharacter != (Object)null && (Object)(object)localCharacter.input != (Object)null)
				{
					localCharacter.input.itemSwitchBlocked = _previousItemSwitchBlocked;
					localCharacter.input.pauseWasPressed = false;
					SuppressCharacterInput(localCharacter.input);
				}
				Cursor.lockState = _previousCursorLock;
				Cursor.visible = _previousCursorVisible;
				if ((Object)(object)EventSystem.current != (Object)null)
				{
					EventSystem.current.SetSelectedGameObject((GameObject)null);
				}
			}
		}

		private void UpdateInputWindow()
		{
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			if (!_inputOpen)
			{
				return;
			}
			Character localCharacter = Character.localCharacter;
			if ((Object)(object)localCharacter == (Object)null || (Object)(object)localCharacter.data == (Object)null || localCharacter.data.dead || (Object)(object)_inputItem == (Object)null || (Object)(object)_inputItem.Item == (Object)null || (Object)(object)_inputItem.Item.holderCharacter != (Object)(object)localCharacter)
			{
				CloseInput();
				return;
			}
			if ((Object)(object)localCharacter.input != (Object)null)
			{
				localCharacter.input.itemSwitchBlocked = true;
				SuppressCharacterInput(localCharacter.input);
			}
			Cursor.lockState = (CursorLockMode)1;
			Cursor.visible = false;
			RefreshGhostChoices(force: false);
			Keyboard current = Keyboard.current;
			if (current == null)
			{
				return;
			}
			if (((ButtonControl)current.escapeKey).wasPressedThisFrame)
			{
				CloseInput();
				return;
			}
			if (!_submissionPending)
			{
				int num = Mathf.Min(_ghostChoices.Count, GhostSelectionKeys.Length);
				for (int i = 0; i < num; i++)
				{
					if (((ButtonControl)current[GhostSelectionKeys[i].Key]).wasPressedThisFrame)
					{
						SelectGhost(_ghostChoices[i].ActorNumber);
						return;
					}
				}
			}
			if (((ButtonControl)current.enterKey).wasPressedThisFrame || ((ButtonControl)current.numpadEnterKey).wasPressedThisFrame)
			{
				TrySubmitBanishment();
			}
		}

		private void SelectGhost(int actorNumber)
		{
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			if (_inputOpen && !_submissionPending)
			{
				GhostChoice ghostChoice = _ghostChoices.FirstOrDefault((GhostChoice candidate) => candidate.ActorNumber == actorNumber);
				if (ghostChoice == null)
				{
					RefreshGhostChoices(force: true);
					return;
				}
				_selectedGhostActorNumber = actorNumber;
				((TMP_Text)_inputMessage).text = "AUSGEWÄHLT: " + ghostChoice.Name.ToUpperInvariant();
				((Graphic)_inputMessage).color = Color32.op_Implicit(new Color32((byte)139, (byte)235, (byte)201, byte.MaxValue));
				RefreshGhostRowStyles();
			}
		}

		private void TrySubmitBanishment()
		{
			if (_inputOpen && !_submissionPending && _lastSubmitFrame != Time.frameCount)
			{
				_lastSubmitFrame = Time.frameCount;
				SubmitBanishment();
			}
		}

		private void SubmitBanishment()
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Expected O, but got Unknown
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			BanishmentItemBehaviour? inputItem = _inputItem;
			PhotonView val = ((inputItem != null) ? ((Component)inputItem).GetComponent<PhotonView>() : null);
			GhostChoice ghostChoice = _ghostChoices.FirstOrDefault((GhostChoice choice) => choice.ActorNumber == _selectedGhostActorNumber);
			if (ghostChoice == null)
			{
				((TMP_Text)_inputMessage).text = "WÄHLE ZUERST EINEN GEIST AUS";
				((Graphic)_inputMessage).color = Color32.op_Implicit(new Color32((byte)235, (byte)71, (byte)62, byte.MaxValue));
				return;
			}
			if (!PhotonNetwork.InRoom || (Object)(object)val == (Object)null || val.ViewID == 0)
			{
				((TMP_Text)_inputMessage).text = "DAS KREUZ IST NOCH NICHT NETZWERKBEREIT";
				((Graphic)_inputMessage).color = Color32.op_Implicit(new Color32((byte)235, (byte)71, (byte)62, byte.MaxValue));
				return;
			}
			if (!PhotonNetwork.RaiseEvent((byte)182, (object)new object[2] { val.ViewID, ghostChoice.ActorNumber }, new RaiseEventOptions
			{
				Receivers = (ReceiverGroup)2
			}, SendOptions.SendReliable))
			{
				((TMP_Text)_inputMessage).text = "ANFRAGE KONNTE NICHT GESENDET WERDEN";
				((Graphic)_inputMessage).color = Color32.op_Implicit(new Color32((byte)235, (byte)71, (byte)62, byte.MaxValue));
				return;
			}
			_submissionPending = true;
			((TMP_Text)_inputMessage).text = "AUSWAHL WIRD VOM HOST GEPRÜFT ...";
			((Graphic)_inputMessage).color = Color32.op_Implicit(new Color32((byte)218, (byte)232, (byte)220, byte.MaxValue));
			RefreshGhostRowStyles();
		}

		internal static void SuppressCharacterInput(CharacterInput input)
		{
			//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_0011: Unknown result type (might be due to invalid IL or missing references)
			input.movementInput = Vector2.zero;
			input.lookInput = Vector2.zero;
			input.scrollInput = 0f;
			input.crouchIsPressed = false;
			input.crouchWasPressed = false;
			input.crouchToggleWasPressed = false;
			input.sprintIsPressed = false;
			input.sprintToggleIsPressed = false;
			input.sprintWasPressed = false;
			input.sprintToggleWasPressed = false;
			input.pauseWasPressed = false;
			input.jumpWasPressed = false;
			input.jumpIsPressed = false;
			input.interactWasPressed = false;
			input.interactIsPressed = false;
			input.interactWasReleased = false;
			input.dropWasPressed = false;
			input.dropIsPressed = false;
			input.dropWasReleased = false;
			input.usePrimaryWasPressed = false;
			input.usePrimaryIsPressed = false;
			input.usePrimaryWasReleased = false;
			input.useSecondaryWasPressed = false;
			input.useSecondaryIsPressed = false;
			input.useSecondaryWasReleased = false;
			input.pingWasPressed = false;
			input.selectSlotForwardWasPressed = false;
			input.selectSlotBackwardWasPressed = false;
			input.unselectSlotWasPressed = false;
			input.selectBackpackWasPressed = false;
			input.scrollBackwardWasPressed = false;
			input.scrollForwardWasPressed = false;
			input.scrollBackwardIsPressed = false;
			input.scrollForwardIsPressed = false;
			input.emoteIsPressed = false;
			input.spectateLeftWasPressed = false;
			input.spectateRightWasPressed = false;
			input.pushToTalkPressed = false;
		}

		private void OnPhotonEvent(EventData eventData)
		{
			try
			{
				bool flag = PhotonNetwork.MasterClient != null && eventData.Sender == PhotonNetwork.MasterClient.ActorNumber;
				if (eventData.Code == 182 && PhotonNetwork.IsMasterClient && eventData.CustomData is object[] data)
				{
					ReceiveBanishRequest(eventData.Sender, data);
				}
				else if (eventData.Code == 183 && flag && eventData.CustomData is object[] data2)
				{
					ReceiveBanishState(data2);
				}
				else if (eventData.Code == 184 && flag && eventData.CustomData is object[] data3)
				{
					ReceiveBanishResult(data3);
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("Ignored invalid Banishment network event: " + ex.Message));
			}
		}

		private void ReceiveBanishRequest(int senderActorNumber, object[] data)
		{
			if (data.Length < 2)
			{
				return;
			}
			int num = Convert.ToInt32(data[0]);
			int requestedActorNumber = ((data[1] is string) ? (-1) : Convert.ToInt32(data[1]));
			string requestedName = ((data[1] is string text) ? text.Trim() : string.Empty);
			PhotonView photonView = PhotonNetwork.GetPhotonView(num);
			BanishmentItemBehaviour banishmentItemBehaviour = (((Object)(object)photonView != (Object)null) ? ((Component)photonView).GetComponent<BanishmentItemBehaviour>() : null);
			object obj;
			if (banishmentItemBehaviour == null)
			{
				obj = null;
			}
			else
			{
				Item item = banishmentItemBehaviour.Item;
				obj = ((item != null) ? item.holderCharacter : null);
			}
			Character val = (Character)obj;
			if (!((Object)(object)banishmentItemBehaviour == (Object)null) && !((Object)(object)val == (Object)null) && !((Object)(object)val.data == (Object)null) && !val.data.dead)
			{
				PhotonView photonView2 = ((MonoBehaviourPun)val).photonView;
				if (photonView2 != null)
				{
					Player owner = photonView2.Owner;
					if (((owner != null) ? new int?(owner.ActorNumber) : ((int?)null)) == senderActorNumber && !((Object)(object)val.data.currentItem != (Object)(object)banishmentItemBehaviour.Item))
					{
						int boundActorNumber = banishmentItemBehaviour.BoundActorNumber;
						if (boundActorNumber > 0 && IsActorBanished(boundActorNumber))
						{
							SendResult(senderActorNumber, success: false, "Dieses Kreuz hat bereits einen Geist gebunden.");
							return;
						}
						List<Character> list = (from character in Character.AllCharacters.Where(delegate(Character character)
							{
								if ((Object)(object)character != (Object)null && (Object)(object)character.data != (Object)null && !character.isBot)
								{
									PhotonView photonView3 = ((MonoBehaviourPun)character).photonView;
									if (((photonView3 != null) ? photonView3.Owner : null) != null)
									{
										if (requestedActorNumber <= 0)
										{
											return string.Equals(GetBestName(character).Trim(), requestedName, StringComparison.OrdinalIgnoreCase);
										}
										return ((MonoBehaviourPun)character).photonView.Owner.ActorNumber == requestedActorNumber;
									}
								}
								return false;
							})
							group character by ((MonoBehaviourPun)character).photonView.Owner.ActorNumber into @group
							select @group.First()).ToList();
						if (list.Count == 0)
						{
							SendResult(senderActorNumber, success: false, "Spieler ist nicht bekannt.");
							return;
						}
						if (list.Count > 1)
						{
							SendResult(senderActorNumber, success: false, "Spielername ist in dieser Lobby nicht eindeutig.");
							return;
						}
						Character val2 = list[0];
						if (!val2.data.dead)
						{
							SendResult(senderActorNumber, success: false, "Dieser Spieler ist noch nicht tot.");
							return;
						}
						int actorNumber = ((MonoBehaviourPun)val2).photonView.Owner.ActorNumber;
						if (IsActorBanished(actorNumber))
						{
							SendResult(senderActorNumber, success: false, "Dieser Geist ist bereits gebannt.");
							return;
						}
						SetRoomBanishment(actorNumber, banished: true);
						BroadcastBanishState(actorNumber, num, banished: true);
						SendResult(senderActorNumber, success: true, GetBestName(val2) + " wurde an das Grabkreuz gebunden.");
						Plugin.Log.LogInfo((object)$"Banishment: actor {senderActorNumber} bound ghost {actorNumber} ({GetBestName(val2)}).");
						return;
					}
				}
			}
			SendResult(senderActorNumber, success: false, "Das Kreuz wird nicht von dir gehalten.");
		}

		private void ReceiveBanishState(object[] data)
		{
			if (data.Length >= 3)
			{
				int actorNumber = Convert.ToInt32(data[0]);
				int itemViewId = Convert.ToInt32(data[1]);
				bool banished = Convert.ToBoolean(data[2]);
				ApplyBanishState(actorNumber, itemViewId, banished);
			}
		}

		private void ReceiveBanishResult(object[] data)
		{
			//IL_0089: 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)
			if (data.Length < 2)
			{
				return;
			}
			bool num = Convert.ToBoolean(data[0]);
			string text = Convert.ToString(data[1]) ?? string.Empty;
			if (num)
			{
				CloseInput();
				ShowToast("BANISHMENT: " + text, 5f);
				return;
			}
			_submissionPending = false;
			if (_inputOpen && (Object)(object)_inputMessage != (Object)null)
			{
				RefreshGhostChoices(force: true);
				((TMP_Text)_inputMessage).text = text.ToUpperInvariant();
				((Graphic)_inputMessage).color = Color32.op_Implicit(new Color32((byte)235, (byte)71, (byte)62, byte.MaxValue));
				RefreshGhostRowStyles();
			}
			else
			{
				ShowToast("NICHT MÖGLICH: " + text, 4f);
			}
		}

		private static void SendResult(int actorNumber, bool success, string message)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			object[] obj = new object[2] { success, message };
			RaiseEventOptions val = new RaiseEventOptions();
			val.TargetActors = new int[1] { actorNumber };
			PhotonNetwork.RaiseEvent((byte)184, (object)obj, val, SendOptions.SendReliable);
		}

		private static void BroadcastBanishState(int actorNumber, int itemViewId, bool banished)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Expected O, but got Unknown
			PhotonNetwork.RaiseEvent((byte)183, (object)new object[3] { actorNumber, itemViewId, banished }, new RaiseEventOptions
			{
				Receivers = (ReceiverGroup)1
			}, SendOptions.SendReliable);
		}

		private void ApplyBanishState(int actorNumber, int itemViewId, bool banished)
		{
			bool flag;
			if (banished)
			{
				flag = _banishedActors.Add(actorNumber);
				if (itemViewId > 0)
				{
					PhotonView photonView = PhotonNetwork.GetPhotonView(itemViewId);
					BanishmentItemBehaviour banishmentItemBehaviour = (((Object)(object)photonView != (Object)null) ? ((Component)photonView).GetComponent<BanishmentItemBehaviour>() : null);
					if ((Object)(object)banishmentItemBehaviour != (Object)null)
					{
						banishmentItemBehaviour.SetBoundActor(actorNumber);
					}
					else
					{
						_pendingItemBindings[itemViewId] = actorNumber;
					}
				}
			}
			else
			{
				flag = _banishedActors.Remove(actorNumber);
				RestoreGhostVisibility(actorNumber);
				BanishmentItemBehaviour[] array = Object.FindObjectsByType<BanishmentItemBehaviour>((FindObjectsInactive)1, (FindObjectsSortMode)0);
				foreach (BanishmentItemBehaviour banishmentItemBehaviour2 in array)
				{
					if (banishmentItemBehaviour2.BoundActorNumber == actorNumber)
					{
						banishmentItemBehaviour2.SetBoundActor(-1);
					}
				}
			}
			if (flag)
			{
				Plugin.Poltergeist?.OnBanishmentChanged(actorNumber, banished);
			}
		}

		private void UpdateBanishedGhostVisibility()
		{
			Character val = default(Character);
			foreach (int banishedActor in _banishedActors)
			{
				if (PlayerHandler.TryGetCharacter(banishedActor, ref val) && !((Object)(object)val == (Object)null) && !((Object)(object)val.Ghost == (Object)null))
				{
					PlayerGhost ghost = val.Ghost;
					if (!_hiddenGhosts.TryGetValue(banishedActor, out GhostVisibilityState value) || (Object)(object)value.Ghost != (Object)(object)ghost)
					{
						value?.Restore();
						value = new GhostVisibilityState(ghost);
						_hiddenGhosts[banishedActor] = value;
					}
					value.Hide();
				}
			}
			int[] array = _hiddenGhosts.Keys.ToArray();
			foreach (int num in array)
			{
				if (!_banishedActors.Contains(num))
				{
					RestoreGhostVisibility(num);
				}
			}
		}

		private void RestoreGhostVisibility(int actorNumber)
		{
			if (_hiddenGhosts.TryGetValue(actorNumber, out GhostVisibilityState value))
			{
				value.Restore();
				_hiddenGhosts.Remove(actorNumber);
			}
		}

		private void ResolvePendingItemBindings()
		{
			if (_pendingItemBindings.Count == 0)
			{
				return;
			}
			List<int> list = new List<int>();
			foreach (KeyValuePair<int, int> pendingItemBinding in _pendingItemBindings)
			{
				PhotonView photonView = PhotonNetwork.GetPhotonView(pendingItemBinding.Key);
				BanishmentItemBehaviour banishmentItemBehaviour = (((Object)(object)photonView != (Object)null) ? ((Component)photonView).GetComponent<BanishmentItemBehaviour>() : null);
				if (!((Object)(object)banishmentItemBehaviour == (Object)null))
				{
					banishmentItemBehaviour.SetBoundActor(pendingItemBinding.Value);
					list.Add(pendingItemBinding.Key);
				}
			}
			foreach (int item in list)
			{
				_pendingItemBindings.Remove(item);
			}
		}

		private unsafe void SynchronizeRoomState()
		{
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			Room currentRoom = PhotonNetwork.CurrentRoom;
			if (currentRoom != _trackedRoom)
			{
				int[] array = _banishedActors.ToArray();
				foreach (int actorNumber in array)
				{
					ApplyBanishState(actorNumber, 0, banished: false);
				}
				_trackedRoom = currentRoom;
				_pendingItemBindings.Clear();
				_beachReadySince = -1f;
				_locallySpawnedRunId = string.Empty;
				_nextRoomStateSyncAt = 0f;
			}
			if (currentRoom == null || Time.unscaledTime < _nextRoomStateSyncAt)
			{
				return;
			}
			_nextRoomStateSyncAt = Time.unscaledTime + 0.25f;
			DictionaryEntryEnumerator enumerator = ((RoomInfo)currentRoom).CustomProperties.GetEnumerator();
			try
			{
				while (((DictionaryEntryEnumerator)(ref enumerator)).MoveNext())
				{
					if (TryReadBanishedActor(((DictionaryEntryEnumerator)(ref enumerator)).Current, out var actorNumber2) && !_banishedActors.Contains(actorNumber2))
					{
						ApplyBanishState(actorNumber2, 0, banished: true);
					}
				}
			}
			finally
			{
				((IDisposable)(*(DictionaryEntryEnumerator*)(&enumerator))/*cast due to .constrained prefix*/).Dispose();
			}
		}

		private static bool TryReadBanishedActor(DictionaryEntry entry, out int actorNumber)
		{
			actorNumber = -1;
			if (!(entry.Key is string text) || !text.StartsWith("PTI_BANISH_", StringComparison.Ordinal))
			{
				return false;
			}
			bool flag = default(bool);
			int num;
			if (int.TryParse(text.Substring("PTI_BANISH_".Length), out actorNumber) && actorNumber > 0)
			{
				object value = entry.Value;
				if (value is bool)
				{
					flag = (bool)value;
					num = 1;
				}
				else
				{
					num = 0;
				}
			}
			else
			{
				num = 0;
			}
			return (byte)((uint)num & (flag ? 1u : 0u)) != 0;
		}

		private static void SetRoomBanishment(int actorNumber, bool banished)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			Room currentRoom = PhotonNetwork.CurrentRoom;
			if (currentRoom != null && PhotonNetwork.IsMasterClient)
			{
				Hashtable val = new Hashtable { [(object)("PTI_BANISH_" + actorNumber)] = banished };
				currentRoom.SetCustomProperties(val, (Hashtable)null, (WebFlags)null);
			}
		}

		private void UpdateHostBanishments()
		{
			if (!PhotonNetwork.InRoom || !PhotonNetwork.IsMasterClient || Time.unscaledTime < _nextRoomSweep)
			{
				return;
			}
			_nextRoomSweep = Time.unscaledTime + 0.5f;
			int[] array = _banishedActors.ToArray();
			Character val = default(Character);
			foreach (int num in array)
			{
				Room currentRoom = PhotonNetwork.CurrentRoom;
				if (((currentRoom != null) ? currentRoom.GetPlayer(num, false) : null) == null)
				{
					ClearBanishment(num);
				}
				else if (PlayerHandler.TryGetCharacter(num, ref val) && (Object)(object)val != (Object)null && (Object)(object)val.data != (Object)null && !val.data.dead)
				{
					ClearBanishment(num);
				}
			}
		}

		private void ClearBanishment(int actorNumber)
		{
			SetRoomBanishment(actorNumber, banished: false);
			BroadcastBanishState(actorNumber, 0, banished: false);
			ApplyBanishState(actorNumber, 0, banished: false);
			Plugin.Log.LogInfo((object)$"Banishment cleared for actor {actorNumber} after revive/leave.");
		}

		private void TryRegisterItemPrefab()
		{
			//IL_0204: Unknown result type (might be due to invalid IL or missing references)
			//IL_0232: Unknown result type (might be due to invalid IL or missing references)
			//IL_0237: Unknown result type (might be due to invalid IL or missing references)
			//IL_023e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0243: Unknown result type (might be due to invalid IL or missing references)
			//IL_0276: Unknown result type (might be due to invalid IL or missing references)
			//IL_027b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0286: Unknown result type (might be due to invalid IL or missing references)
			//IL_029c: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0306: Expected O, but got Unknown
			//IL_031a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0325: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_itemPrefab != (Object)null || Time.unscaledTime < _nextRegistrationAttempt)
			{
				return;
			}
			_nextRegistrationAttempt = Time.unscaledTime + 1f;
			try
			{
				ItemDatabase instance = SingletonAsset<ItemDatabase>.Instance;
				if ((Object)(object)instance == (Object)null || instance.itemLookup == null)
				{
					return;
				}
				Item val = ((IEnumerable<Item>)instance.itemLookup.Values).FirstOrDefault((Func<Item, bool>)((Item item) => (Object)(object)item != (Object)null && ((Object)((Component)item).gameObject).name == "ImReave_BanishmentCross"));
				Item val2 = default(Item);
				if ((Object)(object)val != (Object)null)
				{
					_itemPrefab = ((Component)val).gameObject;
					RegisterPhotonPrefab(_itemPrefab);
				}
				else if (instance.itemLookup.ContainsKey(64871))
				{
					Plugin.Log.LogError((object)$"Banishment Cross could not register: item ID {(ushort)64871} is already used.");
					_nextRegistrationAttempt = Time.unscaledTime + 30f;
				}
				else if (ItemDatabase.TryGetItem("Compass", ref val2) && !((Object)(object)val2 == (Object)null))
				{
					bool activeSelf = ((Component)val2).gameObject.activeSelf;
					GameObject val3;
					try
					{
						((Component)val2).gameObject.SetActive(false);
						val3 = Object.Instantiate<GameObject>(((Component)val2).gameObject);
					}
					finally
					{
						((Component)val2).gameObject.SetActive(activeSelf);
					}
					val3.SetActive(false);
					((Object)val3).name = "ImReave_BanishmentCross";
					Object.DontDestroyOnLoad((Object)(object)val3);
					((Object)val3).hideFlags = (HideFlags)61;
					CompassPointer componentInChildren = val3.GetComponentInChildren<CompassPointer>(true);
					if ((Object)(object)componentInChildren != (Object)null)
					{
						Object.DestroyImmediate((Object)(object)componentInChildren);
					}
					ItemActionBase[] componentsInChildren = val3.GetComponentsInChildren<ItemActionBase>(true);
					for (int num = 0; num < componentsInChildren.Length; num++)
					{
						Object.DestroyImmediate((Object)(object)componentsInChildren[num]);
					}
					Renderer[] componentsInChildren2 = val3.GetComponentsInChildren<Renderer>(true);
					for (int num = 0; num < componentsInChildren2.Length; num++)
					{
						Object.DestroyImmediate((Object)(object)componentsInChildren2[num]);
					}
					Collider[] componentsInChildren3 = val3.GetComponentsInChildren<Collider>(true);
					for (int num = 0; num < componentsInChildren3.Length; num++)
					{
						Object.DestroyImmediate((Object)(object)componentsInChildren3[num]);
					}
					Item component = val3.GetComponent<Item>();
					component.itemID = 64871;
					component.itemTags = (ItemTags)2049;
					component.mass = 3.5f;
					component.throwForceMultiplier = 0.85f;
					component.defaultPos = new Vector3(0.28f, -0.18f, 0.9f);
					component.defaultForward = Vector3.forward;
					component.rightHandOnly = true;
					component.usingTimePrimary = 0f;
					component.totalUses = -1;
					component.showUseProgress = false;
					component.canUseOnFriend = false;
					component.UIData = new ItemUIData
					{
						itemName = "Banishment Cross",
						icon = (_itemIcon = CreateItemIcon()),
						hasMainInteract = true,
						mainInteractPrompt = "banish ghost",
						hasSecondInteract = false,
						canDrop = true,
						canPocket = true,
						canBackpack = true,
						canThrow = true,
						iconPositionOffset = Vector3.zero,
						iconRotationOffset = new Vector3(0f, 0f, -6f),
						iconScaleOffset = 1.08f
					};
					LootData obj = val3.GetComponent<LootData>() ?? val3.AddComponent<LootData>();
					obj.Rarity = (Rarity)2;
					obj.spawnLocations = (SpawnPool)1963064320;
					obj.rarityOverrides = new List<ItemRarityOverride>();
					obj.banInSolo = false;
					obj.excludeFromCustomRunSelection = false;
					obj.excludeBasedOnCustomRunSetting = false;
					BuildCrossModel(val3, val2);
					val3.AddComponent<BanishmentItemBehaviour>();
					instance.itemLookup.Add(64871, component);
					RegisterPhotonPrefab(val3);
					LootData.PopulateLootData();
					ApplyCrossLootProbability();
					_itemPrefab = val3;
					Plugin.Log.LogInfo((object)"Registered the Banishment Cross as a native pickup with a 0.5% chance per luggage item slot.");
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("Banishment Cross registration will retry: " + ex.Message));
			}
		}

		internal static void ApplyCrossLootProbability()
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			if (LootData.AllSpawnWeightData == null)
			{
				return;
			}
			SpawnPool[] crossLuggagePools = CrossLuggagePools;
			foreach (SpawnPool key in crossLuggagePools)
			{
				if (LootData.AllSpawnWeightData.TryGetValue(key, out var value) && value.ContainsKey(64871))
				{
					ApplyCrossLootProbability(value);
				}
			}
		}

		internal static void ApplyCrossLootProbability(Dictionary<ushort, int> weights)
		{
			if (!weights.ContainsKey(64871))
			{
				return;
			}
			long num = 0L;
			foreach (KeyValuePair<ushort, int> weight in weights)
			{
				if (weight.Key != 64871 && weight.Value > 0)
				{
					num += weight.Value;
				}
			}
			if (num > 0)
			{
				int value = Math.Max(1, (int)Math.Round((float)num * 0.005f / 0.995f));
				weights[64871] = value;
			}
		}

		private static void RegisterPhotonPrefab(GameObject prefab)
		{
			IPunPrefabPool prefabPool = PhotonNetwork.PrefabPool;
			((DefaultPool)(((prefabPool is DefaultPool) ? prefabPool : null) ?? throw new InvalidOperationException("PEAK is using a non-default Photon prefab pool; the cross cannot be registered safely."))).ResourceCache["0_Items/ImReave_BanishmentCross"] = prefab;
		}

		private static void BuildCrossModel(GameObject prefab, Item sourceItem)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: 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_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b8: 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_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0207: Unknown result type (might be due to invalid IL or missing references)
			//IL_0213: Unknown result type (might be due to invalid IL or missing references)
			//IL_022e: 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_0256: Unknown result type (might be due to invalid IL or missing references)
			//IL_0262: Unknown result type (might be due to invalid IL or missing references)
			//IL_027d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0282: Unknown result type (might be due to invalid IL or missing references)
			//IL_0296: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0316: Unknown result type (might be due to invalid IL or missing references)
			//IL_0322: 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_0342: Unknown result type (might be due to invalid IL or missing references)
			//IL_0356: 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_0390: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a4: 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_03df: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Banishment Cross Visual");
			val.transform.SetParent(prefab.transform, false);
			val.layer = prefab.layer;
			val.transform.localPosition = new Vector3(0f, -0.01f, 0f);
			val.transform.localRotation = Quaternion.Euler(2f, 0f, 0f);
			Renderer componentInChildren = ((Component)sourceItem).GetComponentInChildren<Renderer>(true);
			Material material = CreateTintedMaterial((componentInChildren != null) ? componentInChildren.sharedMaterial : null, Color32.op_Implicit(new Color32((byte)70, (byte)58, (byte)52, byte.MaxValue)), "Banishment weathered wood");
			Material material2 = CreateTintedMaterial((componentInChildren != null) ? componentInChildren.sharedMaterial : null, Color32.op_Implicit(new Color32((byte)14, (byte)16, (byte)15, byte.MaxValue)), "Banishment black edge");
			Material material3 = CreateTintedMaterial((componentInChildren != null) ? componentInChildren.sharedMaterial : null, Color32.op_Implicit(new Color32((byte)91, (byte)102, (byte)94, byte.MaxValue)), "Banishment tarnished metal");
			Material material4 = CreateTintedMaterial((componentInChildren != null) ? componentInChildren.sharedMaterial : null, Color32.op_Implicit(new Color32((byte)100, (byte)222, (byte)181, byte.MaxValue)), "Banishment ghost glow");
			CreatePrimitivePart(val.transform, "Vertical black silhouette", (PrimitiveType)3, new Vector3(0f, 0.01f, 0.015f), Quaternion.Euler(0f, 0f, 4f), new Vector3(0.19f, 0.7f, 0.13f), material2);
			CreatePrimitivePart(val.transform, "Weathered upright", (PrimitiveType)3, new Vector3(0f, 0.01f, -0.01f), Quaternion.Euler(0f, 0f, 4f), new Vector3(0.145f, 0.64f, 0.135f), material);
			CreatePrimitivePart(val.transform, "Horizontal black silhouette", (PrimitiveType)3, new Vector3(-0.012f, 0.14f, 0.018f), Quaternion.Euler(0f, 0f, -7f), new Vector3(0.54f, 0.19f, 0.13f), material2);
			CreatePrimitivePart(val.transform, "Weathered crossbar", (PrimitiveType)3, new Vector3(-0.012f, 0.14f, -0.012f), Quaternion.Euler(0f, 0f, -7f), new Vector3(0.485f, 0.14f, 0.135f), material);
			CreatePrimitivePart(val.transform, "Old iron nail left", (PrimitiveType)0, new Vector3(-0.155f, 0.16f, -0.09f), Quaternion.identity, new Vector3(0.035f, 0.035f, 0.02f), material3);
			CreatePrimitivePart(val.transform, "Old iron nail right", (PrimitiveType)0, new Vector3(0.145f, 0.12f, -0.09f), Quaternion.identity, new Vector3(0.035f, 0.035f, 0.02f), material3);
			CreatePrimitivePart(val.transform, "Ghost seal rim", (PrimitiveType)0, new Vector3(0f, 0.12f, -0.105f), Quaternion.identity, new Vector3(0.285f, 0.285f, 0.055f), material2);
			CreatePrimitivePart(val.transform, "Ghost seal", (PrimitiveType)0, new Vector3(0f, 0.12f, -0.137f), Quaternion.identity, new Vector3(0.235f, 0.235f, 0.04f), material4);
			CreatePrimitivePart(val.transform, "Cracked lower binding", (PrimitiveType)3, new Vector3(0.025f, -0.2f, -0.09f), Quaternion.Euler(0f, 0f, -19f), new Vector3(0.045f, 0.17f, 0.025f), material3);
			BoxCollider obj = prefab.AddComponent<BoxCollider>();
			obj.center = new Vector3(0f, 0.01f, 0f);
			obj.size = new Vector3(0.56f, 0.72f, 0.18f);
		}

		private static GameObject CreatePrimitivePart(Transform parent, string name, PrimitiveType primitiveType, Vector3 localPosition, Quaternion localRotation, Vector3 localScale, Material material)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			GameObject obj = GameObject.CreatePrimitive(primitiveType);
			((Object)obj).name = name;
			obj.transform.SetParent(parent, false);
			obj.transform.localPosition = localPosition;
			obj.transform.localRotation = localRotation;
			obj.transform.localScale = localScale;
			obj.layer = ((Component)parent).gameObject.layer;
			Collider component = obj.GetComponent<Collider>();
			if ((Object)(object)component != (Object)null)
			{
				Object.DestroyImmediate((Object)(object)component);
			}
			MeshRenderer component2 = obj.GetComponent<MeshRenderer>();
			((Renderer)component2).sharedMaterial = material;
			((Renderer)component2).enabled = true;
			return obj;
		}

		private static Material CreateTintedMaterial(Material? source, Color color, string materialName)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			Material val = new Material(Shader.Find("Universal Render Pipeline/Lit") ?? Shader.Find("Universal Render Pipeline/Simple Lit") ?? Shader.Find("Standard") ?? Shader.Find("Sprites/Default") ?? ((source != null) ? source.shader : null));
			((Object)val).name = materialName;
			((Object)val).hideFlags = (HideFlags)61;
			string[] array = new string[4] { "_Color", "_BaseColor", "_SkinColor", "_PlayerColor" };
			foreach (string text in array)
			{
				if (val.HasProperty(text))
				{
					val.SetColor(text, color);
				}
			}
			if (val.HasProperty("_Glossiness"))
			{
				val.SetFloat("_Glossiness", 0.06f);
			}
			if (val.HasProperty("_Smoothness"))
			{
				val.SetFloat("_Smoothness", 0.06f);
			}
			if (val.HasProperty("_AlphaClip"))
			{
				val.SetFloat("_AlphaClip", 0f);
			}
			if (val.HasProperty("_Surface"))
			{
				val.SetFloat("_Surface", 0f);
			}
			if (val.HasProperty("_ZWrite"))
			{
				val.SetFloat("_ZWrite", 1f);
			}
			val.renderQueue = -1;
			return val;
		}

		private static Texture2D CreateItemIcon()
		{
			//IL_000c: 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_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: 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_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Expected O, but got Unknown
			Texture2D val = new Texture2D(128, 128, (TextureFormat)4, false)
			{
				name = "Banishment Cross icon",
				hideFlags = (HideFlags)61,
				filterMode = (FilterMode)0,
				wrapMode = (TextureWrapMode)1
			};
			Color32[] array = Enumerable.Repeat<Color32>(new Color32((byte)0, (byte)0, (byte)0, (byte)0), 16384).ToArray();
			DrawRect(array, 128, 49, 12, 81, 116, new Color32((byte)12, (byte)14, (byte)13, byte.MaxValue));
			DrawRect(array, 128, 55, 15, 75, 112, new Color32((byte)72, (byte)59, (byte)52, byte.MaxValue));
			DrawRect(array, 128, 18, 62, 110, 91, new Color32((byte)12, (byte)14, (byte)13, byte.MaxValue));
			DrawRect(array, 128, 23, 67, 105, 86, new Color32((byte)72, (byte)59, (byte)52, byte.MaxValue));
			DrawDisc(array, 128, 64, 77, 20, new Color32((byte)10, (byte)12, (byte)11, byte.MaxValue));
			DrawDisc(array, 128, 64, 77, 15, new Color32((byte)100, (byte)222, (byte)181, byte.MaxValue));
			DrawDisc(array, 128, 59, 80, 3, new Color32((byte)8, (byte)10, (byte)9, byte.MaxValue));
			DrawDisc(array, 128, 69, 80, 3, new Color32((byte)8, (byte)10, (byte)9, byte.MaxValue));
			DrawRect(array, 128, 59, 70, 69, 73, new Color32((byte)8, (byte)10, (byte)9, byte.MaxValue));
			val.SetPixels32(array);
			val.Apply(false, true);
			return val;
		}

		private static void DrawRect(Color32[] pixels, int width, int xMin, int yMin, int xMax, int yMax, Color32 color)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			for (int i = Mathf.Max(0, yMin); i < Mathf.Min(width, yMax); i++)
			{
				for (int j = Mathf.Max(0, xMin); j < Mathf.Min(width, xMax); j++)
				{
					pixels[i * width + j] = color;
				}
			}
		}

		private static void DrawDisc(Color32[] pixels, int width, int centerX, int centerY, int radius, Color32 color)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			int num = radius * radius;
			for (int i = centerY - radius; i <= centerY + radius; i++)
			{
				for (int j = centerX - radius; j <= centerX + radius; j++)
				{
					if (j >= 0 && i >= 0 && j < width && i < width && (j - centerX) * (j - centerX) + (i - centerY) * (i - centerY) <= num)
					{
						pixels[i * width + j] = color;
					}
				}
			}
		}

		private void TrySpawnBeachCross()
		{
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: 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_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: 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_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Expected O, but got Unknown
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_itemPrefab == (Object)null || !PhotonNetwork.InRoom || !PhotonNetwork.IsMasterClient || (Object)(object)Character.localCharacter == (Object)null || Character.localCharacter.inAirport || (Object)(object)RunManager.Instance == (Object)null || RunManager.Instance.RunId == Guid.Empty || !MapHandler.Exists || (int)MapHandler.CurrentSegmentNumber != 0 || SpawnPoint.allSpawnPoints.Count == 0)
			{
				_beachReadySince = -1f;
				return;
			}
			string text = RunManager.Instance.RunId.ToString("N");
			Room currentRoom = PhotonNetwork.CurrentRoom;
			if (string.Equals(_locallySpawnedRunId, text, StringComparison.Ordinal) || (((Dictionary<object, object>)(object)((RoomInfo)currentRoom).CustomProperties).TryGetValue((object)"PTI_BANISH_BEACH_RUN", out object value) && string.Equals(Convert.ToString(value), text, StringComparison.Ordinal)))
			{
				return;
			}
			if (_beachReadySince < 0f)
			{
				_beachReadySince = Time.unscaledTime;
			}
			else if (!(Time.unscaledTime - _beachReadySince < 7f))
			{
				Vector3 val = FindBeachSpawnPosition();
				Quaternion val2 = Quaternion.Euler(0f, 18f, 0f);
				GameObject val3 = PhotonNetwork.InstantiateItemRoom("ImReave_BanishmentCross", val, val2, true);
				Item val4 = (((Object)(object)val3 != (Object)null) ? val3.GetComponent<Item>() : null);
				if ((Object)(object)val4 == (Object)null)
				{
					_beachReadySince = Time.unscaledTime;
					return;
				}
				val4.SetKinematicNetworked(true, val, val2);
				_locallySpawnedRunId = text;
				currentRoom.SetCustomProperties(new Hashtable { [(object)"PTI_BANISH_BEACH_RUN"] = text }, (Hashtable)null, (WebFlags)null);
				Plugin.Log.LogInfo((object)$"Spawned the guaranteed Banishment Cross at the beach ({val}).");
			}
		}

		private static Vector3 FindBeachSpawnPosition()
		{
			//IL_002f: 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_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: 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_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: 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_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			List<SpawnPoint> list = SpawnPoint.allSpawnPoints.Where((SpawnPoint point) => (Object)(object)point != (Object)null).ToList();
			Vector3 val = Vector3.zero;
			foreach (SpawnPoint item in list)
			{
				val += ((Component)item).transform.position;
			}
			val /= (float)Mathf.Max(1, list.Count);
			Vector3 val2 = Vector3.ProjectOnPlane(((Component)list.OrderBy((SpawnPoint point) => point.index).First()).transform.right, Vector3.up);
			Vector3 val3 = ((Vector3)(ref val2)).normalized;
			if (((Vector3)(ref val3)).sqrMagnitude < 0.01f)
			{
				val3 = Vector3.right;
			}
			Vector3 val4 = val + val3 * 2.1f;
			RaycastHit val5 = default(RaycastHit);
			if (Physics.Raycast(val4 + Vector3.up * 6f, Vector3.down, ref val5, 18f, -1, (QueryTriggerInteraction)1))
			{
				return ((RaycastHit)(ref val5)).point + Vector3.up * 0.38f;
			}
			return val4 + Vector3.up * 0.6f;
		}

		private void EnsureInputUi()
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Expected O, but got Unknown
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: 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_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: 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_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: 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_01a4: 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_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d1: 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_01e1: Invalid comparison between Unknown and I4
			//IL_021a: Unknown result type (might be due to invalid IL or missing references)
			//IL_021f: Unknown result type (might be due to invalid IL or missing references)
			//IL_022e: Unknown result type (might be due to invalid IL or missing references)
			//IL_023d: Unknown result type (might be due to invalid IL or missing references)
			//IL_024c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0270: Unknown result type (might be due to invalid IL or missing references)
			//IL_027f: Unknown result type (might be due to invalid IL or missing references)
			//IL_028e: Unknown result type (might be due to invalid IL or missing references)
			//IL_029d: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_0309: Unknown result type (might be due to invalid IL or missing references)
			//IL_0310: Expected O, but got Unknown
			//IL_0340: Unknown result type (might be due to invalid IL or missing references)
			//IL_035a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0374: Unknown result type (might be due to invalid IL or missing references)
			//IL_038e: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03be: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c8: Expected O, but got Unknown
			//IL_0431: Unknown result type (might be due to invalid IL or missing references)
			//IL_0440: Unknown result type (might be due to invalid IL or missing references)
			//IL_044f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0462: Unknown result type (might be due to invalid IL or missing references)
			//IL_0489: Unknown result type (might be due to invalid IL or missing references)
			//IL_048f: Invalid comparison between Unknown and I4
			//IL_04c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_04cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_04db: 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_04f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0503: Unknown result type (might be due to invalid IL or missing references)
			//IL_0509: Invalid comparison between Unknown and I4
			if (!((Object)(object)_inputRoot != (Object)null))
			{
				TMP_FontAsset font = ResolveGameFont();
				_inputRoot = new GameObject("ImReave Banishment Input", new Type[3]
				{
					typeof(RectTransform),
					typeof(Canvas),
					typeof(CanvasScaler)
				});
				_inputRoot.transform.SetParent(((Component)this).transform, false);
				Canvas component = _inputRoot.GetComponent<Canvas>();
				component.renderMode = (RenderMode)0;
				component.sortingOrder = 330;
				CanvasScaler component2 = _inputRoot.GetComponent<CanvasScaler>();
				component2.uiScaleMode = (ScaleMode)1;
				component2.referenceResolution = new Vector2(1920f, 1080f);
				component2.matchWidthOrHeight = 0.5f;
				GameObject obj = CreateUiPanel(_inputRoot.transform, "Background shade", Vector2.zero, Vector2.one, Vector2.zero, Vector2.zero, new Color32((byte)5, (byte)7, (byte)6, (byte)145));
				((Graphic)obj.GetComponent<Image>()).raycastTarget = true;
				GameObject val = CreateUiPanel(obj.transform, "Banishment panel", new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(-360f, -330f), new Vector2(360f, 330f), new Color32((byte)18, (byte)24, (byte)21, (byte)250));
				CreateUiBorder(val.transform, new Color32((byte)100, (byte)222, (byte)181, byte.MaxValue), 5f);
				((TMP_Text)CreateUiText(val.transform, "Title", font, 34f, Color32.op_Implicit(new Color32((byte)139, (byte)235, (byte)201, byte.MaxValue)), new Vector2(0.5f, 1f), new Vector2(0f, -40f), new Vector2(660f, 52f))).text = (((int)LocalizedText.CURRENT_LANGUAGE == 3) ? "GEIST VERBANNEN" : "BANISH GHOST");
				_inputMessage = CreateUiText(val.transform, "Message", font, 19f, Color32.op_Implicit(new Color32((byte)218, (byte)232, (byte)220, byte.MaxValue)), new Vector2(0.5f, 1f), new Vector2(0f, -84f), new Vector2(650f, 38f));
				GameObject val2 = CreateUiPanel(val.transform, "Available ghosts", new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(-310f, -205f), new Vector2(310f, 205f), new Color32((byte)8, (byte)12, (byte)10, byte.MaxValue));
				((Graphic)val2.GetComponent<Image>()).raycastTarget = true;
				val2.AddComponent<RectMask2D>();
				ScrollRect val3 = val2.AddComponent<ScrollRect>();
				val3.horizontal = false;
				val3.vertical = true;
				val3.movementType = (MovementType)2;
				val3.scrollSensitivity = 28f;
				GameObject val4 = new GameObject("Ghost choices", new Type[1] { typeof(RectTransform) });
				val4.transform.SetParent(val2.transform, false);
				_ghostListContent = val4.GetComponent<RectTransform>();
				_ghostListContent.anchorMin = new Vector2(0f, 1f);
				_ghostListContent.anchorMax = new Vector2(1f, 1f);
				_ghostListContent.pivot = new Vector2(0.5f, 1f);
				_ghostListContent.offsetMin = new Vector2(10f, 0f);
				_ghostListContent.offsetMax = new Vector2(-10f, 0f);
				VerticalLayoutGroup obj2 = val4.AddComponent<VerticalLayoutGroup>();
				((LayoutGroup)obj2).padding = new RectOffset(5, 5, 7, 7);
				((HorizontalOrVerticalLayoutGroup)obj2).spacing = 7f;
				((LayoutGroup)obj2).childAlignment = (TextAnchor)1;
				((HorizontalOrVerticalLayoutGroup)obj2).childControlWidth = true;
				((HorizontalOrVerticalLayoutGroup)obj2).childControlHeight = true;
				((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandWidth = true;
				((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandHeight = false;
				val4.AddComponent<ContentSizeFitter>().verticalFit = (FitMode)2;
				val3.viewport = val2.GetComponent<RectTransform>();
				val3.content = _ghostListContent;
				_banishButton = CreateUiButton(val.transform, "Banish selected ghost", font, new Vector2(0.5f, 0f), new Vector2(0f, 67f), new Vector2(310f, 52f), new Color32((byte)75, (byte)151, (byte)119, byte.MaxValue), TrySubmitBanishment, out _banishButtonLabel);
				((TMP_Text)_banishButtonLabel).text = (((int)LocalizedText.CURRENT_LANGUAGE == 3) ? "GEIST VERBANNEN" : "BANISH GHOST");
				((TMP_Text)CreateUiText(val.transform, "Instructions", font, 18f, Color32.op_Implicit(new Color32((byte)205, (byte)218, (byte)208, byte.MaxValue)), new Vector2(0.5f, 0f), new Vector2(0f, 25f), new Vector2(650f, 34f))).text = (((int)LocalizedText.CURRENT_LANGUAGE == 3) ? "BUCHSTABENTASTE WÄHLT AUS  •  [ENTER] VERBANNT  •  [ESC] ABBRECHEN" : "PRESS A LETTER TO SELECT  •  [ENTER] BANISHES  •  [ESC] CANCELS");
				_inputRoot.SetActive(false);
			}
		}

		private void RefreshGhostChoices(bool force)
		{
			//IL_048e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0493: Unknown result type (might be due to invalid IL or missing references)
			//IL_0201: Unknown result type (might be due to invalid IL or missing references)
			//IL_0206: Unknown result type (might be due to invalid IL or missing references)
			//IL_020b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0210: Unknown result type (might be due to invalid IL or missing references)
			//IL_0220: Unknown result type (might be due to invalid IL or missing references)
			//IL_023d: Unknown result type (might be due to invalid IL or missing references)
			//IL_027c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0281: 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_02a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02da: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_030d: Unknown result type (might be due to invalid IL or missing references)
			//IL_032f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0339: Expected O, but got Unknown
			//IL_035f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0364: Unknown result type (might be due to invalid IL or missing references)
			//IL_0373: Unknown result type (might be due to invalid IL or missing references)
			//IL_0382: Unknown result type (might be due to invalid IL or missing references)
			//IL_0391: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_03eb: 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_0409: Unknown result type (might be due to invalid IL or missing references)
			//IL_04da: Unknown result type (might be due to invalid IL or missing references)
			//IL_04df: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_ghostListContent == (Object)null || (!force && Time.unscaledTime < _nextGhostListRefreshAt))
			{
				return;
			}
			_nextGhostListRefreshAt = Time.unscaledTime + 0.25f;
			List<GhostChoice> list = (from character in Character.AllCharacters
				where (Object)(object)character != (Object)null && (Object)(object)character.data != (Object)null && character.data.dead && !character.isBot && (Object)(object)((MonoBehaviourPun)character).photonView != (Object)null && ((MonoBehaviourPun)character).photonView.Owner != null && !IsActorBanished(((MonoBehaviourPun)character).photonView.Owner.ActorNumber)
				group character by ((MonoBehaviourPun)character).photonView.Owner.ActorNumber into @group
				select new GhostChoice(@group.Key, GetBestName(@group.First()).Trim())).OrderBy<GhostChoice, string>((GhostChoice choice) => choice.Name, StringComparer.OrdinalIgnoreCase).ToList();
			string text = string.Join("|", list.Select((GhostChoice choice) => $"{choice.ActorNumber}:{choice.Name}"));
			if (!force && string.Equals(text, _ghostListSignature, StringComparison.Ordinal))
			{
				return;
			}
			_ghostListSignature = text;
			_ghostChoices.Clear();
			_ghostChoices.AddRange(list);
			if (!_ghostChoices.Any((GhostChoice choice) => choice.ActorNumber == _selectedGhostActorNumber))
			{
				_selectedGhostActorNumber = -1;
			}
			foreach (GhostChoiceRow ghostRow in _ghostRows)
			{
				if ((Object)(object)ghostRow.Root != (Object)null)
				{
					Object.Destroy((Object)(object)ghostRow.Root);
				}
			}
			_ghostRows.Clear();
			TMP_FontAsset font = ResolveGameFont();
			for (int num = 0; num < _ghostChoices.Count; num++)
			{
				GhostChoice ghostChoice = _ghostChoices[num];
				string text2 = ((num < GhostSelectionKeys.Length) ? GhostSelectionKeys[num].Label : "•");
				GameObject val = CreateUiPanel((Transform)(object)_ghostListContent, $"Ghost {ghostChoice.ActorNumber}", Vector2.zero, Vector2.one, Vector2.zero, Vector2.zero, new Color32((byte)27, (byte)37, (byte)32, byte.MaxValue));
				val.GetComponent<RectTransform>().sizeDelta = new Vector2(0f, 48f);
				LayoutElement obj = val.AddComponent<LayoutElement>();
				obj.preferredHeight = 48f;
				obj.minHeight = 48f;
				Image component = val.GetComponent<Image>();
				((Graphic)component).raycastTarget = true;
				Button obj2 = val.AddComponent<Button>();
				ColorBlock colors = ((Selectable)obj2).colors;
				((ColorBlock)(ref colors)).normalColor = Color.white;
				((ColorBlock)(ref colors)).highlightedColor = Color32.op_Implicit(new Color32((byte)147, (byte)222, (byte)190, byte.MaxValue));
				((ColorBlock)(ref colors)).pressedColor = Color32.op_Implicit(new Color32((byte)95, (byte)174, (byte)140, byte.MaxValue));
				((ColorBlock)(ref colors)).selectedColor = ((ColorBlock)(ref colors)).highlightedColor;
				((ColorBlock)(ref colors)).disabledColor = Color32.op_Implicit(new Color32((byte)70, (byte)76, (byte)72, (byte)180));
				((ColorBlock)(ref colors)).colorMultiplier = 1f;
				((Selectable)obj2).colors = colors;
				int actorNumber = ghostChoice.ActorNumber;
				((UnityEvent)obj2.onClick).AddListener((UnityAction)delegate
				{
					SelectGhost(actorNumber);
				});
				((TMP_Text)CreateUiText(val.transform, "Selection key", font, 23f, Color32.op_Implicit(new Color32((byte)139, (byte)235, (byte)201, byte.MaxValue)), new Vector2(0f, 0.5f), new Vector2(34f, 0f), new Vector2(52f, 38f))).text = "[" + text2 + "]";
				TextMeshProUGUI val2 = CreateUiText(val.transform, "Ghost name", font, 24f, Color32.op_Implicit(new Color32((byte)226, (byte)236, (byte)229, byte.MaxValue)), new Vector2(0.5f, 0.5f), new Vector2(25f, 0f), new Vector2(500f, 38f));
				((TMP_Text)val2).text = ghostChoice.Name.ToUpperInvariant();
				_ghostRows.Add(new GhostChoiceRow(ghostChoice.ActorNumber, val, component, val2));
			}
			if (_ghostChoices.Count == 0)
			{
				((TMP_Text)_inputMessage).text = "KEIN VERFÜGBARER GEIST IN DER LOBBY";
				((Graphic)_inputMessage).color = Color32.op_Implicit(new Color32((byte)235, (byte)71, (byte)62, byte.MaxValue));
			}
			else if (_selectedGhostActorNumber <= 0 && !_submissionPending)
			{
				((TMP_Text)_inputMessage).text = "WÄHLE EINEN VERFÜGBAREN GEIST AUS";
				((Graphic)_inputMessage).color = Color32.op_Implicit(new Color32((byte)218, (byte)232, (byte)220, byte.MaxValue));
			}
			RefreshGhostRowStyles();
		}

		private void RefreshGhostRowStyles()
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: 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)
			foreach (GhostChoiceRow ghostRow in _ghostRows)
			{
				bool flag = ghostRow.ActorNumber == _selectedGhostActorNumber;
				((Graphic)ghostRow.Background).color = Color32.op_Implicit(flag ? new Color32((byte)55, (byte)112, (byte)88, byte.MaxValue) : new Color32((byte)27, (byte)37, (byte)32, byte.MaxValue));
				((Graphic)ghostRow.Name).color = Color32.op_Implicit(flag ? new Color32(byte.MaxValue, byte.MaxValue, (byte)235, byte.MaxValue) : new Color32((byte)226, (byte)236, (byte)229, byte.MaxValue));
			}
			if ((Object)(object)_banishButton != (Object)null)
			{
				((Selectable)_banishButton).interactable = _selectedGhostActorNumber > 0 && !_submissionPending;
			}
		}

		private void UpdateStatusOverlays()
		{
			if (!string.IsNullOrEmpty(_toastText) && Time.unscaledTime < _toastUntil)
			{
				EnsureStatusUi();
				_toastRoot.SetActive(true);
				((TMP_Text)_toastLabel).text = _toastText.ToUpperInvariant();
			}
			else if ((Object)(object)_toastRoot != (Object)null)
			{
				_toastRoot.SetActive(false);
			}
			Character localCharacter = Character.localCharacter;
			PhotonView val = (((Object)(object)localCharacter != (Object)null) ? ((MonoBehaviourPun)localCharacter).photonView : null);
			if ((Object)(object)localCharacter != (Object)null && (Object)(object)localCharacter.data != (Object)null && localCharacter.data.dead && (Object)(object)val != (Object)null && val.Owner != null && IsActorBanished(val.Owner.ActorNumber))
			{
				EnsureStatusUi();
				_banishedRoot.SetActive(true);
			}
			else if ((Object)(object)_banishedRoot != (Object)null)
			{
				_banishedRoot.SetActive(false);
			}
		}

		private void ShowToast(string message, float seconds)
		{
			_toastText = message;
			_toastUntil = Time.unscaledTime + seconds;
		}

		private void EnsureStatusUi()
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Expected O, but got Unknown
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: 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)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: 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_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: 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_01f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_022c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0231: Unknown result type (might be due to invalid IL or missing references)
			//IL_0240: Unknown result type (might be due to invalid IL or missing references)
			//IL_0245: Unknown result type (might be due to invalid IL or missing references)
			//IL_0254: Unknown result type (might be due to invalid IL or missing references)
			//IL_025e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0264: Invalid comparison between Unknown and I4
			if (!((Object)(object)_toastRoot != (Object)null))
			{
				TMP_FontAsset font = ResolveGameFont();
				GameObject val = new GameObject("ImReave Banishment Status", new Type[3]
				{
					typeof(RectTransform),
					typeof(Canvas),
					typeof(CanvasScaler)
				});
				val.transform.SetParent(((Component)this).transform, false);
				Canvas component = val.GetComponent<Canvas>();
				component.renderMode = (RenderMode)0;
				component.sortingOrder = 270;
				CanvasScaler component2 = val.GetComponent<CanvasScaler>();
				component2.uiScaleMode = (ScaleMode)1;
				component2.referenceResolution = new Vector2(1920f, 1080f);
				component2.matchWidthOrHeight = 0.5f;
				_toastRoot = CreateUiPanel(val.transform, "Toast", new Vector2(0.5f, 0f), new Vector2(0.5f, 0f), new Vector2(-380f, 74f), new Vector2(380f, 128f), new Color32((byte)16, (byte)22, (byte)19, (byte)238));
				CreateUiBorder(_toastRoot.transform, new Color32((byte)100, (byte)222, (byte)181, byte.MaxValue), 4f);
				_toastLabel = CreateUiText(_toastRoot.transform, "Toast text", font, 18f, Color.white, new Vector2(0.5f, 0.5f), Vector2.zero, new Vector2(730f, 46f));
				_banishedRoot = CreateUiPanel(val.transform, "Banished warning", new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(-330f, -92f), new Vector2(330f, -36f), new Color32((byte)28, (byte)15, (byte)19, (byte)240));
				CreateUiBorder(_banishedRoot.transform, new Color32((byte)199, (byte)65, (byte)81, byte.MaxValue), 4f);
				((TMP_Text)CreateUiText(_banishedRoot.transform, "Warning text", font, 20f, Color32.op_Implicit(new Color32((byte)246, (byte)134, (byte)145, byte.MaxValue)), new Vector2(0.5f, 0.5f), Vector2.zero, new Vector2(630f, 48f))).text = (((int)LocalizedText.CURRENT_LANGUAGE == 3) ? "VERBANNT  •  AN DAS GRABKREUZ GEBUNDEN" : "BANISHED  •  BOUND TO THE GRAVE CROSS");
				_toastRoot.SetActive(false);
				_banishedRoot.SetActive(false);
			}
		}

		private static GameObject CreateUiPanel(Transform parent, string name, Vector2 anchorMin, Vector2 anchorMax, Vector2 offsetMin, Vector2 offsetMax, Color32 color)
		{
			//IL_002e: 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_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: 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_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: 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)
			//IL_007d: Expected O, but got Unknown
			GameObject val = new GameObject(name, new Type[3]
			{
				typeof(RectTransform),
				typeof(CanvasRenderer),
				typeof(Image)
			});
			val.transform.SetParent(parent, false);
			RectTransform component = val.GetComponent<RectTransform>();
			component.anchorMin = anchorMin;
			component.anchorMax = anchorMax;
			component.offsetMin = offsetMin;
			component.offsetMax = offsetMax;
			Image component2 = val.GetComponent<Image>();
			((Graphic)component2).color = Color32.op_Implicit(color);
			((Graphic)component2).raycastTarget = false;
			return val;
		}

		private static Button CreateUiButton(Transform parent, string name, TMP_FontAsset font, Vector2 anchor, Vector2 anchoredPosition, Vector2 size, Color32 color, Action onClick, out TextMeshProUGUI label)
		{
			//IL_0010: 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_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: 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_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: 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_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: 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)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Expected O, but got Unknown
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = CreateUiPanel(parent, name, anchor, anchor, anchoredPosition - size * 0.5f, anchoredPosition + size * 0.5f, color);
			((Graphic)val.GetComponent<Image>()).raycastTarget = true;
			Button obj = val.AddComponent<Button>();
			ColorBlock colors = ((Selectable)obj).colors;
			((ColorBlock)(ref colors)).normalColor = Color.white;
			((ColorBlock)(ref colors)).highlightedColor = Color32.op_Implicit(new Color32((byte)151, (byte)230, (byte)195, byte.MaxValue));
			((ColorBlock)(ref colors)).pressedColor = Color32.op_Implicit(new Color32((byte)87, (byte)172, (byte)135, byte.MaxValue));
			((ColorBlock)(ref colors)).selectedColor = ((ColorBlock)(ref colors)).highlightedColor;
			((ColorBlock)(ref colors)).disabledColor = Color32.op_Implicit(new Color32((byte)72, (byte)78, (byte)74, (byte)190));
			((ColorBlock)(ref colors)).colorMultiplier = 1f;
			((Selectable)obj).colors = colors;
			((UnityEvent)obj.onClick).AddListener((UnityAction)delegate
			{
				onClick();
			});
			label = CreateUiText(val.transform, "Label", font, 23f, Color.white, new Vector2(0.5f, 0.5f), Vector2.zero, size - new Vector2(18f, 8f));
			return obj;
		}

		private static void CreateUiBorder(Transform parent, Color32 color, float thickness)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: 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_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: 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_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: 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)
			CreateUiPanel(parent, "Top", new Vector2(0f, 1f), Vector2.one, new Vector2(0f, 0f - thickness), Vector2.zero, color);
			CreateUiPanel(parent, "Bottom", Vector2.zero, new Vector2(1f, 0f), Vector2.zero, new Vector2(0f, thickness), color);
			CreateUiPanel(parent, "Left", Vector2.zero, new Vector2(0f, 1f), Vector2.zero, new Vector2(thickness, 0f), color);
			CreateUiPanel(parent, "Right", new Vector2(1f, 0f), Vector2.one, new Vector2(0f - thickness, 0f), Vector2.zero, color);
		}

		private static TextMeshProUGUI CreateUiText(Transform parent, string name, TMP_FontAsset font, float fontSize, Color color, Vector2 anchor, Vector2 anchoredPosition, Vector2 size)
		{
			//IL_002e: 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_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: 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)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name, new Type[3]
			{
				typeof(RectTransform),
				typeof(CanvasRenderer),
				typeof(TextMeshProUGUI)
			});
			val.transform.SetParent(parent, false);
			RectTransform component = val.GetComponent<RectTransform>();
			component.anchorMin = anchor;
			component.anchorMax = anchor;
			component.pivot = new Vector2(0.5f, 0.5f);
			component.anchoredPosition = anchoredPosition;
			component.sizeDelta = size;
			TextMeshProUGUI component2 = val.GetComponent<TextMeshProUGUI>();
			((TMP_Text)component2).font = font;
			((TMP_Text)component2).fontSize = fontSize;
			((TMP_Text)component2).fontSizeMax = fontSize;
			((TMP_Text)component2).fontSizeMin = Mathf.Max(12f, fontSize * 0.65f);
			((TMP_Text)component2).enableAutoSizing = true;
			((TMP_Text)component2).fontStyle = (FontStyles)1;
			((TMP_Text)component2).alignment = (TextAlignmentOptions)514;
			((Graphic)component2).color = color;
			((TMP_Text)component2).textWrappingMode = (TextWrappingModes)1;
			((TMP_Text)component2).overflowMode = (TextOverflowModes)3;
			((TMP_Text)component2).outlineWidth = 0.14f;
			((TMP_Text)component2).outlineColor = new Color32((byte)4, (byte)7, (byte)5, byte.MaxValue);
			((Graphic)component2).raycastTarget = false;
			return component2;
		}

		private static TMP_FontAsset ResolveGameFont()
		{
			GUIManager instance = GUIManager.instance;
			object obj;
			if (instance == null)
			{
				obj = null;
			}
			else
			{
				TextMeshProUGUI spectatingNameText = instance.spectatingNameText;
				obj = ((spectatingNameText != null) ? ((TMP_Text)spectatingNameText).font : null);
			}
			if (obj == null)
			{
				if (instance == null)
				{
					obj = null;
				}
				else
				{
					TextMeshProUGUI itemPromptMain = instance.itemPromptMain;
					obj = ((itemPromptMain != null) ? ((TMP_Text)itemPromptMain).font : null);
				}
				if (obj == null)
				{
					TextMeshProUGUI obj2 = Object.FindAnyObjectByType<TextMeshProUGUI>();
					obj = ((obj2 != null) ? ((TMP_Text)obj2).font : null) ?? TMP_Settings.defaultFontAsset;
				}
			}
			if (obj == null)
			{
				throw new InvalidOperationException("PEAK's TextMesh Pro font is not available.");
			}
			return (TMP_FontAsset)obj;
		}

		internal static string GetBestName(Character character)
		{
			PhotonView photonView = ((MonoBehaviourPun)character).photonView;
			object obj;
			if (photonView == null)
			{
				obj = null;
			}
			else
			{
				Player owner = photonView.Owner;
				obj = ((owner != null) ? owner.NickName : null);
			}
			if (obj == null)
			{
				obj = string.Empty;
			}
			string text = (string)obj;
			string text2;
			if (string.IsNullOrWhiteSpace(text))
			{
				text2 = character.characterName;
				if (text2 == null)
				{
					return "Unknown player";
				}
			}
			else
			{
				text2 = text;
			}
			return text2;
		}

		private void OnDestroy()
		{
			CloseInput();
			PhotonNetwork.NetworkingClient.EventReceived -= OnPhotonEvent;
			foreach (GhostVisibilityState value in _hiddenGhosts.Values)
			{
				value.Restore();
			}
			_hiddenGhosts.Clear();
			if ((Object)(object)_itemPrefab != (Object)null)
			{
				IPunPrefabPool prefabPool = PhotonNetwork.PrefabPool;
				((DefaultPool)(((prefabPool is DefaultPool) ? prefabPool : null)?)).ResourceCache.Remove("0_Items/ImReave_BanishmentCross");
				Object.Destroy((Object)(object)_itemPrefab);
			}
			if ((Object)(object)_itemIcon != (Object)null)
			{
				Object.Destroy((Object)(object)_itemIcon);
			}
		}

		static BanishmentController()
		{
			SpawnPool[] array = new SpawnPool[12];
			RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/);
			CrossLuggagePools = (SpawnPool[])(object)array;
			_suppressInputThroughFrame = -1;
		}
	}
	internal sealed class BanishmentItemBehaviour : ItemComponent
	{
		private int _visualizedActor = int.MinValue;

		private float _nextPortraitRetryAt;

		private float _nextPortraitLogAt;

		private GameObject? _portraitRoot;

		private RawImage? _facePlate;

		private RawImage? _leftEye;

		private RawImage? _rightEye;

		private RawImage? _mouth;

		private TextMeshProUGUI? _nameLabel;

		internal Item Item => base.item;

		internal int BoundActorNumber
		{
			get
			{
				if ((Object)(object)base.item == (Object)null || base.item.data == null)
				{
					return -1;
				}
				IntItemData val = default(IntItemData);
				if (!base.item.data.TryGetDataEntry<IntItemData>((DataEntryKey)201, ref val))
				{
					return -1;
				}
				return val.Value;
			}
		}

		public override void Awake()
		{
			((ItemComponent)this).Awake();
			BuildPortrait();
		}

		public override void OnEnable()
		{
			((MonoBehaviourPunCallbacks)this).OnEnable();
			if ((Object)(object)base.item == (Object)null)
			{
				base.item = ((Component)this).GetComponent<Item>();
			}
			Item item = base.item;
			item.OnPrimaryFinishedCast = (Action)Delegate.Combine(item.OnPrimaryFinishedCast, new Action(OnPrimaryFinished));
		}

		public override void OnDisable()
		{
			if ((Object)(object)base.item != (Object)null)
			{
				Item item = base.item;
				item.OnPrimaryFinishedCast = (Action)Delegate.Remove(item.OnPrimaryFinishedCast, new Action(OnPrimaryFinished));
			}
			((MonoBehaviourPunCallbacks)this).OnDisable();
		}

		private void Update()
		{
			int boundActorNumber = BoundActorNumber;
			int num = ((boundActorNumber > 0 && (Object)(object)Plugin.Banishment != (Object)null && Plugin.Banishment.IsActorBanished(boundActorNumber)) ? boundActorNumber : (-1));
			if (_visualizedActor != num && Time.unscaledTime >= _nextPortraitRetryAt)
			{
				RefreshPortrait(num);
			}
		}

		private void OnPrimaryFinished()
		{
			Plugin.Banishment?.Open(this);
		}

		internal void SetBoundActor(int actorNumber)
		{
			if (!((Object)(object)base.item == (Object)null))
			{
				base.item.GetData<IntItemData>((DataEntryKey)201).Value = actorNumber;
				RefreshPortrait(actorNumber);
				PhotonView component = ((Component)this).GetComponent<PhotonView>();
				if ((Object)(object)component != (Object)null && component.IsMine && base.item.data != null)
				{
					component.RPC("SetItemInstanceDataRPC", (RpcTarget)1, new object[1] { base.item.data });
				}
			}
		}

		public override void OnInstanceDataSet()
		{
			RefreshPortrait(BoundActorNumber);
		}

		private void BuildPortrait()
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Expected O, but got Unknown
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_028d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0293: Expected O, but got Unknown
			//IL_02bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_0337: Unknown result type (might be due to invalid IL or missing references)
			//IL_033c: Unknown result type (might be due to invalid IL or missing references)
			//IL_035c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0361: Unknown result type (might be due to invalid IL or missing references)
			Transform obj = ((Component)this).transform.Find("Banishment Cross Visual/Ghost seal");
			Transform val = ((obj != null) ? obj.parent : null) ?? ((Component)this).transform;
			_portraitRoot = new GameObject("Bound Ghost Portrait", new Type[2]
			{
				typeof(RectTransform),
				typeof(Canvas)
			});
			_portraitRoot.transform.SetParent(val, false);
			_portraitRoot.transform.localPosition = new Vector3(0f, 0.12f, -0.166f);
			_portraitRoot.transform.localRotation = Quaternion.Euler(0f, 0f, 0f);
			_portraitRoot.transform.localScale = Vector3.one * 0.001f;
			Canvas component = _portraitRoot.GetComponent<Canvas>();
			component.renderMode = (RenderMode)2;
			component.sortingOrder = 20;
			_portraitRoot.GetComponent<RectTransform>().sizeDelta = new Vector2(240f, 280f);
			_facePlate = CreateRawImage(_portraitRoot.transform, "Face plate", Vector2.zero, new Vector2(218f, 218f));
			_facePlate.texture = (Texture)(object)CreateDiscTexture();
			_leftEye = CreateRawImage(_portraitRoot.transform, "Left eye", new Vector2(-49f, 26f), new Vector2(70f, 70f));
			_rightEye = CreateRawImage(_portraitRoot.transform, "Right eye", new Vector2(49f, 26f), new Vector2(70f, 70f));
			_mouth = CreateRawImage(_portraitRoot.transform, "Mouth", new Vector2(0f, -42f), new Vector2(88f, 54f));
			GUIManager instance = GUIManager.instance;
			object obj2;
			if (instance == null)
			{
				obj2 = null;
			}
			else
			{
				TextMeshProUGUI spectatingNameText = instance.spectatingNameText;
				obj2 = ((spectatingNameText != null) ? ((TMP_Text)spectatingNameText).font : null);
			}
			if (obj2 == null)
			{
				GUIManager instance2 = GUIManager.instance;
				if (instance2 == null)
				{
					obj2 = null;
				}
				else
				{
					TextMeshProUGUI itemPromptMain = instance2.