Decompiled source of KayceePvP v0.1.0

plugins\KayceePvP\KayceePvP.dll

Decompiled 3 hours ago
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Security;
using System.Net.Sockets;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using DiskCardGame;
using HarmonyLib;
using InscryptionAPI.Ascension;
using InscryptionAPI.Card;
using InscryptionAPI.Dialogue;
using InscryptionAPI.Helpers;
using InscryptionAPI.Localizing;
using InscryptionAPI.Saves;
using KayceePvP.Net;
using KayceePvP.Patches;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("KayceePvP")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.1.0.0")]
[assembly: AssemblyInformationalVersion("0.1.0+adf3ca5a33fa548510640132f97ae0010ff6aa7c")]
[assembly: AssemblyProduct("KayceePvP")]
[assembly: AssemblyTitle("KayceePvP")]
[assembly: AssemblyVersion("0.1.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace KayceePvP
{
	public enum CardChoiceEventKind
	{
		Cost,
		Tribe,
		Random
	}
	public static class BalancedPathCardChoiceSeed
	{
		private const int CostDomain = 700000;

		private const int TribeDomain = 800000;

		private const int RandomDomain = 900000;

		public static bool TryGetEventKind(CardChoicesType choicesType, out CardChoiceEventKind kind)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected I4, but got Unknown
			switch ((int)choicesType)
			{
			case 1:
				kind = CardChoiceEventKind.Cost;
				return true;
			case 2:
				kind = CardChoiceEventKind.Tribe;
				return true;
			case 0:
				kind = CardChoiceEventKind.Random;
				return true;
			default:
				kind = CardChoiceEventKind.Cost;
				return false;
			}
		}

		public static bool ShouldOverride(bool isPvpRun, bool isBalancedPathMode, CardChoicesType choicesType)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			CardChoiceEventKind kind;
			if (isPvpRun && isBalancedPathMode)
			{
				return TryGetEventKind(choicesType, out kind);
			}
			return false;
		}

		public static int Compute(int sharedMapSeed, int currentNodeId, CardChoiceEventKind kind)
		{
			return sharedMapSeed + currentNodeId + DomainOffset(kind);
		}

		private static int DomainOffset(CardChoiceEventKind kind)
		{
			return kind switch
			{
				CardChoiceEventKind.Cost => 700000, 
				CardChoiceEventKind.Tribe => 800000, 
				CardChoiceEventKind.Random => 900000, 
				_ => 0, 
			};
		}
	}
	internal static class BalancedPathMap
	{
		public const int RowCount = 19;

		public static List<List<NodeData>> BuildRows()
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Expected O, but got Unknown
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected O, but got Unknown
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Expected O, but got Unknown
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Expected O, but got Unknown
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Expected O, but got Unknown
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Expected O, but got Unknown
			List<List<NodeData>> list = new List<List<NodeData>>();
			list.Add(Row(new NodeData()));
			list.Add(Row((NodeData)new TradePeltsNodeData()));
			list.Add(Row((NodeData)CardChoiceNodeData((CardChoicesType)2)));
			list.Add(Row((NodeData)CardChoiceNodeData((CardChoicesType)2)));
			list.Add(Row((NodeData)CardChoiceNodeData((CardChoicesType)2)));
			list.Add(Row((NodeData)CardChoiceNodeData((CardChoicesType)2)));
			list.Add(Row((NodeData)CardChoiceNodeData((CardChoicesType)2)));
			list.Add(Row((NodeData)CardChoiceNodeData((CardChoicesType)2)));
			list.Add(Row((NodeData)CardChoiceNodeData((CardChoicesType)2)));
			list.Add(Row((NodeData)new CardBattleNodeData
			{
				difficulty = 1
			}));
			list.Add(Row((NodeData)CardChoiceNodeData((CardChoicesType)2)));
			list.Add(Row((NodeData)CardChoiceNodeData((CardChoicesType)2)));
			list.Add(Row((NodeData)CardChoiceNodeData((CardChoicesType)2)));
			list.Add(Row((NodeData)CardChoiceNodeData((CardChoicesType)2)));
			list.Add(Row((NodeData)new CopyCardNodeData()));
			list.Add(Row((NodeData)new CardRemoveNodeData()));
			list.Add(Row((NodeData)new CardRemoveNodeData()));
			list.Add(Row((NodeData)new RareRewardNodeData()));
			list.Add(Row(new NoBattleExitNodeData()));
			return list;
		}

		private static CardChoicesNodeData CardChoiceNodeData(CardChoicesType choiceType)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			return new CardChoicesNodeData
			{
				choicesType = choiceType
			};
		}

		private static List<NodeData> Row(params NodeData[] nodes)
		{
			return new List<NodeData>(nodes);
		}
	}
	internal static class BalancedRouteMap
	{
		public const int RowCount = 20;

		public static List<List<NodeData>> BuildRows()
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Expected O, but got Unknown
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected O, but got Unknown
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Expected O, but got Unknown
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Expected O, but got Unknown
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Expected O, but got Unknown
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Expected O, but got Unknown
			//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c9: Expected O, but got Unknown
			List<List<NodeData>> list = new List<List<NodeData>>();
			list.Add(Row(new NodeData()));
			list.Add(Row((NodeData)new TradePeltsNodeData()));
			list.Add(Row((NodeData)Choices((CardChoicesType)1)));
			list.Add(Row((NodeData)Choices((CardChoicesType)1)));
			list.Add(Row((NodeData)Choices((CardChoicesType)1)));
			list.Add(Row((NodeData)Choices((CardChoicesType)1)));
			list.Add(Row((NodeData)Choices((CardChoicesType)1)));
			list.Add(Row((NodeData)Choices((CardChoicesType)1)));
			list.Add(Row((NodeData)new CardMergeNodeData()));
			list.Add(Row((NodeData)new CardStatBoostNodeData()));
			list.Add(Row((NodeData)Battle(1)));
			list.Add(Row((NodeData)Choices((CardChoicesType)1)));
			list.Add(Row((NodeData)Choices((CardChoicesType)1)));
			list.Add(Row((NodeData)Choices((CardChoicesType)1)));
			list.Add(Row((NodeData)Choices((CardChoicesType)1)));
			list.Add(Row((NodeData)new CopyCardNodeData()));
			list.Add(Row((NodeData)new DuplicateMergeNodeData()));
			list.Add(Row((NodeData)new CardStatBoostNodeData()));
			list.Add(Row((NodeData)new RareRewardNodeData()));
			list.Add(Row(new NoBattleExitNodeData()));
			return list;
		}

		private static CardChoicesNodeData Choices(CardChoicesType type)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			return new CardChoicesNodeData
			{
				choicesType = type
			};
		}

		private static CardBattleNodeData Battle(int difficulty)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			return new CardBattleNodeData
			{
				difficulty = difficulty
			};
		}

		private static List<NodeData> Row(params NodeData[] nodes)
		{
			return new List<NodeData>(nodes);
		}
	}
	internal static class CardEdits
	{
		private static readonly string MayonnaiseEnglish = PvpLocalization.L("KayceePvP.Card.Mayonnaise", "Mayonnaise", "Maionese");

		private static readonly string StepfatherEnglish = PvpLocalization.L("KayceePvP.Card.Stepfather", "Stepfather", "Padrasto");

		private static readonly string BluePenEnglish = PvpLocalization.L("KayceePvP.Card.BluePen", "Blue Pen", "Caneta Azul");

		private static readonly string CannabisEnglish = PvpLocalization.L("KayceePvP.Card.Cannabis", "Cannabis", "Cannabis");

		public static void Apply()
		{
			RenameAndReskin("Moose", MayonnaiseEnglish, "portrait_maionese.png");
			RenameAndReskin("Goat", StepfatherEnglish, "portrait_padrasto.png");
			RenameAndReskin("Mole", BluePenEnglish, "portrait_caneta_azul.png");
			RenameAndReskin("Squirrel", CannabisEnglish, "portrait_cannabis.png");
		}

		private static void RenameAndReskin(string cardName, string englishDisplayedName, string embeddedPortraitFileName)
		{
			CardInfo val = CardExtensions.CardByName((IEnumerable<CardInfo>)CardManager.BaseGameCards, cardName);
			if ((Object)(object)val == (Object)null)
			{
				Plugin.Log.LogWarning((object)("CardEdits: could not find base game card '" + cardName + "' to edit."));
				return;
			}
			CardExtensions.SetDisplayedName(val, englishDisplayedName);
			Traverse.Create((object)val).Field<string>("displayedNameLocId").Value = null;
			Texture2D imageAsTexture = TextureHelper.GetImageAsTexture(embeddedPortraitFileName, Assembly.GetExecutingAssembly(), (FilterMode)0);
			CardExtensions.SetPortrait(val, imageAsTexture, (FilterMode?)null);
			Plugin.Log.LogInfo((object)("CardEdits: renamed '" + cardName + "' to '" + englishDisplayedName + "' with a custom portrait (Portuguese translation registered separately)."));
		}
	}
	public static class CobaiasStarterDeck
	{
		public const string Title = "COBAIAS";

		public static readonly string[] CardNames = new string[3] { "PackRat", "MealWorm", "Skink" };

		public static string DeckId => "jgs.inscryption.kayceepvp_COBAIAS";

		internal static void Apply()
		{
			StarterDeckManager.New("jgs.inscryption.kayceepvp", "COBAIAS", BuildIcon(), CardNames, 0);
		}

		private static Texture2D BuildIcon()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: 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)
			Texture2D val = new Texture2D(35, 44, (TextureFormat)4, false);
			Color val2 = default(Color);
			((Color)(ref val2))..ctor(0.35f, 0.18f, 0.45f, 1f);
			Color val3 = default(Color);
			((Color)(ref val3))..ctor(0.85f, 0.75f, 0.95f, 1f);
			Color val4 = default(Color);
			((Color)(ref val4))..ctor(0.15f, 0.07f, 0.2f, 1f);
			for (int i = 0; i < 44; i++)
			{
				for (int j = 0; j < 35; j++)
				{
					bool flag = j == 0 || i == 0 || j == 34 || i == 43;
					bool flag2 = (j >= 15 && j <= 19) || (i >= 20 && i <= 24);
					val.SetPixel(j, i, flag ? val4 : (flag2 ? val3 : val2));
				}
			}
			val.Apply();
			((Object)val).name = "CobaiasStarterDeckIcon";
			return val;
		}
	}
	internal sealed class CreatorCreditOverlay : MonoBehaviour
	{
		private const string CreatorName = "YNASTRA";

		private const float AnimationInterval = 18f;

		private const float AnimationDuration = 2.4f;

		private CanvasGroup _group;

		private Text _creatorText;

		private Shadow _creatorGlow;

		private RectTransform _creatorRect;

		private Text _feedbackText;

		private float _feedbackCooldownUntil;

		internal static void RegisterLocalizedText()
		{
			PvpLocalization.L("KayceePvP.Feedback.Hint", "Press {0} to send feedback or suggestions", "Pressione {0} para enviar feedback ou sugestões");
		}

		private void Awake()
		{
			BuildUI();
			_group.alpha = 0.62f;
		}

		private void Update()
		{
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: 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_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			if (Plugin.CreatorCreditEnabled == null || !Plugin.CreatorCreditEnabled.Value)
			{
				_group.alpha = 0f;
				return;
			}
			_group.alpha = 0.62f;
			_creatorText.text = "YNASTRA";
			float num = Mathf.Repeat(Time.unscaledTime, 18f);
			float num2 = ((num < 2.4f) ? Mathf.Sin(num / 2.4f * (float)Math.PI) : 0f);
			float num3 = num2;
			_creatorRect.anchoredPosition = new Vector2(280f + num2 * 4f, 0f);
			((Graphic)_creatorText).color = Color.Lerp(new Color(0.92f, 0.83f, 0.64f, 1f), new Color(1f, 0.43f, 0.08f, 1f), num3);
			_creatorGlow.effectColor = new Color(1f, 0.22f, 0.03f, 0.12f + num3 * 0.5f);
			UpdateFeedbackLine();
		}

		private unsafe void UpdateFeedbackLine()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			KeyboardShortcut val = ((Plugin.FeedbackShortcut != null) ? Plugin.FeedbackShortcut.Value : FeedbackConfig.DefaultShortcut);
			_feedbackText.text = PvpLocalization.Format("KayceePvP.Feedback.Hint", ((object)(*(KeyboardShortcut*)(&val))/*cast due to .constrained prefix*/).ToString());
			if (!(Time.unscaledTime < _feedbackCooldownUntil) && ((KeyboardShortcut)(ref val)).IsDown())
			{
				_feedbackCooldownUntil = Time.unscaledTime + 3f;
				Plugin.Log.LogInfo((object)"feedback page requested");
				Application.OpenURL("https://github.com/Ynastra/act1pvpkayceesmod/issues/new/choose");
			}
		}

		private void BuildUI()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Expected O, but got Unknown
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: 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_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: 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_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_021c: 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_0292: Unknown result type (might be due to invalid IL or missing references)
			//IL_0298: Expected O, but got Unknown
			//IL_02bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_030e: Unknown result type (might be due to invalid IL or missing references)
			//IL_032e: 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_037f: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("KayceePvP_CreatorCredit", new Type[1] { typeof(RectTransform) });
			val.transform.SetParent(((Component)this).transform, false);
			Canvas obj = val.AddComponent<Canvas>();
			obj.renderMode = (RenderMode)0;
			obj.sortingOrder = 10;
			CanvasScaler obj2 = val.AddComponent<CanvasScaler>();
			obj2.uiScaleMode = (ScaleMode)1;
			obj2.referenceResolution = new Vector2(1920f, 1080f);
			obj2.matchWidthOrHeight = 0.5f;
			_group = val.AddComponent<CanvasGroup>();
			_group.interactable = false;
			_group.blocksRaycasts = false;
			GameObject val2 = new GameObject("Signature", new Type[1] { typeof(RectTransform) });
			val2.transform.SetParent(val.transform, false);
			RectTransform component = val2.GetComponent<RectTransform>();
			component.anchorMin = new Vector2(1f, 0f);
			component.anchorMax = new Vector2(1f, 0f);
			component.pivot = new Vector2(1f, 0f);
			component.anchoredPosition = new Vector2(-24f, 20f);
			component.sizeDelta = new Vector2(390f, 34f);
			Text obj3 = CreateText(val2.transform, "Caption", new Vector2(0f, 0f), new Vector2(273f, 34f));
			obj3.text = "KayceePvP · Designed by";
			obj3.fontSize = 17;
			obj3.alignment = (TextAnchor)5;
			((Graphic)obj3).color = new Color(0.72f, 0.68f, 0.59f, 1f);
			_creatorText = CreateText(val2.transform, "Creator", new Vector2(280f, 0f), new Vector2(110f, 34f));
			_creatorRect = ((Graphic)_creatorText).rectTransform;
			_creatorText.fontSize = 18;
			_creatorText.fontStyle = (FontStyle)1;
			_creatorText.alignment = (TextAnchor)3;
			((Graphic)_creatorText).color = new Color(0.92f, 0.83f, 0.64f, 1f);
			_creatorGlow = ((Component)_creatorText).gameObject.AddComponent<Shadow>();
			_creatorGlow.effectDistance = new Vector2(1f, -1f);
			_creatorGlow.effectColor = new Color(1f, 0.22f, 0.03f, 0.12f);
			GameObject val3 = new GameObject("FeedbackHint", new Type[1] { typeof(RectTransform) });
			val3.transform.SetParent(val.transform, false);
			RectTransform component2 = val3.GetComponent<RectTransform>();
			component2.anchorMin = new Vector2(1f, 0f);
			component2.anchorMax = new Vector2(1f, 0f);
			component2.pivot = new Vector2(1f, 0f);
			component2.anchoredPosition = new Vector2(-24f, 58f);
			component2.sizeDelta = new Vector2(440f, 26f);
			_feedbackText = CreateText(val3.transform, "FeedbackHintText", new Vector2(0f, 0f), new Vector2(440f, 26f));
			_feedbackText.fontSize = 13;
			_feedbackText.alignment = (TextAnchor)5;
			((Graphic)_feedbackText).color = new Color(0.72f, 0.68f, 0.59f, 1f);
			_feedbackText.horizontalOverflow = (HorizontalWrapMode)0;
		}

		private static Text CreateText(Transform parent, string name, Vector2 position, Vector2 size)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: 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_0043: 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_0054: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) });
			val.transform.SetParent(parent, false);
			RectTransform component = val.GetComponent<RectTransform>();
			component.anchorMin = Vector2.zero;
			component.anchorMax = Vector2.zero;
			component.pivot = Vector2.zero;
			component.anchoredPosition = position;
			component.sizeDelta = size;
			Text obj = val.AddComponent<Text>();
			obj.font = LobbyUI.ResolveGameFont();
			((Graphic)obj).raycastTarget = false;
			obj.horizontalOverflow = (HorizontalWrapMode)1;
			obj.verticalOverflow = (VerticalWrapMode)1;
			return obj;
		}
	}
	internal sealed class DeathcardNodeData : NodeData
	{
		public override string PrefabPath => "Prefabs/Map/MapNodesPart1/MapNode_CardBattle";
	}
	internal static class DuelDebug
	{
		public static void StartRandomDuel(int cardCount = 10)
		{
			if ((Object)(object)Singleton<TurnManager>.Instance == (Object)null)
			{
				Plugin.Log.LogWarning((object)"Duel debug: no TurnManager in the current scene - load into the map first.");
				return;
			}
			if (PvpRunState.IsDuelActive)
			{
				Plugin.Log.LogWarning((object)"Duel debug: a duel is already active.");
				return;
			}
			if (RunState.Run == null)
			{
				Plugin.Log.LogWarning((object)"Duel debug: no active run to source a deck from.");
				return;
			}
			List<CardInfo> list = CardManager.AllCardsCopy.Where((CardInfo c) => (Object)(object)c != (Object)null && !string.IsNullOrEmpty(((Object)c).name) && ((Object)c).name != "DeathCard" && (int)c.temple == 0).ToList();
			if (list.Count == 0)
			{
				Plugin.Log.LogWarning((object)"Duel debug: no Nature-temple cards available to build a random deck.");
				return;
			}
			((CardCollectionInfo)RunState.Run.playerDeck).Cards.Clear();
			for (int num = 0; num < cardCount; num++)
			{
				((CardCollectionInfo)RunState.Run.playerDeck).AddCard(list[Random.Range(0, list.Count)]);
			}
			PvpRunState.MatchId = Random.Range(int.MinValue, int.MaxValue);
			DuelSession.Instance.PrepareForMatch(PvpRunState.MatchId);
			LobbySession.Instance.ResetBattleFlowForMatch(PvpRunState.MatchId, "DuelDebug.StartRandomDuel (F10 fast-path)");
			DuelStart.Begin();
		}
	}
	public static class DuelDeckShuffleSeed
	{
		private const int MatchIdMultiplier = -1640531535;

		private const int BattleNumberMultiplier = 104729;

		private const int DomainSalt = 1592614637;

		public static bool ShouldOverride(bool isPvpRun, bool isDuelActive)
		{
			return isPvpRun && isDuelActive;
		}

		public static int Compute(int matchId, int battleNumber)
		{
			return (matchId * -1640531535) ^ (battleNumber * 104729) ^ 0x5EED5EED;
		}
	}
	internal static class DuelStart
	{
		public static void Begin()
		{
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Expected O, but got Unknown
			PvpCardMutations.ApplyToDeck(RunState.Run?.playerDeck);
			PvpDuelItems.ApplyForSeries(PvpRunState.MatchId);
			if ((Object)(object)Singleton<GameMap>.Instance != (Object)null)
			{
				Singleton<GameMap>.Instance.HideMapImmediate();
			}
			Singleton<ViewManager>.Instance.Controller.SwitchToControlMode((ControlMode)0, true);
			if ((Object)(object)Singleton<ItemsManager>.Instance != (Object)null)
			{
				Singleton<ItemsManager>.Instance.SetSlotsAtEdge(false, true);
			}
			if ((Object)(object)Singleton<GameFlowManager>.Instance != (Object)null)
			{
				Singleton<GameFlowManager>.Instance.CurrentGameState = (GameState)0;
			}
			PvpRunState.IsDuelActive = true;
			PvpRoundState.BeginMatch();
			LobbyMatchState.BeginMatch(PvpRunState.MatchId);
			LobbyMatchState.BeginBattle();
			DuelSession.Instance.ArmTurnOwnershipForBattle();
			Plugin.Log.LogInfo((object)$"Duel: starting with {((CardCollectionInfo)RunState.Run.playerDeck).Cards.Count} cards.");
			Telemetry.LogDuelStart((Object)(object)LobbySession.Instance != (Object)null && LobbySession.Instance.IsHost);
			LogTotemSnapshot("battle begin (battle 1)");
			Singleton<TurnManager>.Instance.StartGame(new EncounterData());
		}

		internal static void LogTotemSnapshot(string context)
		{
			string text = ((RunState.Run.totems.Count == 0) ? "none" : string.Join(" | ", RunState.Run.totems.Select((TotemDefinition t) => $"tribe={t.tribe} ability={t.ability}")));
			Plugin.Log.LogInfo((object)$"Duel (totem): SNAPSHOT at {context} | matchId={PvpRunState.MatchId} battleNumber={LobbyMatchState.BattleNumber} SELF={PvpOwnership.LocalAbsoluteSide()} ownTotems=[{text}]");
		}

		public static void BeginNextBattle()
		{
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Expected O, but got Unknown
			PvpCardMutations.ApplyToDeck(RunState.Run?.playerDeck);
			PvpDuelItems.ApplyForSeries(PvpRunState.MatchId);
			if ((Object)(object)Singleton<GameMap>.Instance != (Object)null)
			{
				Singleton<GameMap>.Instance.HideMapImmediate();
			}
			Singleton<ViewManager>.Instance.Controller.SwitchToControlMode((ControlMode)0, true);
			if ((Object)(object)Singleton<ItemsManager>.Instance != (Object)null)
			{
				Singleton<ItemsManager>.Instance.SetSlotsAtEdge(false, true);
			}
			if ((Object)(object)Singleton<GameFlowManager>.Instance != (Object)null)
			{
				Singleton<GameFlowManager>.Instance.CurrentGameState = (GameState)0;
			}
			PvpRunState.IsDuelActive = true;
			LobbyMatchState.BeginBattle();
			Plugin.Log.LogInfo((object)$"Duel: starting battle {LobbyMatchState.BattleNumber} with {((CardCollectionInfo)RunState.Run.playerDeck).Cards.Count} cards (hostWins={LobbyMatchState.HostWins} peerWins={LobbyMatchState.PeerWins}).");
			Telemetry.LogRoundBegin(LobbyMatchState.BattleNumber);
			LogTotemSnapshot($"battle begin (battle {LobbyMatchState.BattleNumber})");
			Singleton<TurnManager>.Instance.StartGame(new EncounterData());
		}
	}
	internal static class FeedbackConfig
	{
		internal const string IssuesUrl = "https://github.com/Ynastra/act1pvpkayceesmod/issues/new/choose";

		internal static readonly KeyboardShortcut DefaultShortcut = new KeyboardShortcut((KeyCode)291, Array.Empty<KeyCode>());

		internal const float CooldownSeconds = 3f;
	}
	internal sealed class FinalMatchScreen : MonoBehaviour
	{
		private const string BackgroundResourceName = "KayceePvP.Assets.tela_final_kayceepvp.png";

		private const float InputArmDelaySeconds = 0.75f;

		private GameObject _canvasRoot;

		private Text _winnerText;

		private Text _loserText;

		private Text _scoreText;

		private Text _instructionText;

		private Text _rematchStatusText;

		private float _inputArmedAt;

		private bool _resetRequested;

		private bool _previousCursorVisible;

		private CursorLockMode _previousCursorLockState;

		private bool _previousInteractionDisabled;

		private bool _previousInteractionCursorEnabled;

		public static FinalMatchScreen Instance { get; private set; }

		internal static void RegisterLocalizedText()
		{
			PvpLocalization.L("KayceePvP.Final.WinnerLine", "{0} IS THE WINNER", "{0} É O VENCEDOR");
			PvpLocalization.L("KayceePvP.Final.LoserLine", "{0} IS ABSOLUTE GARBAGE", "{0} É UM LIXO IMUNDO");
			PvpLocalization.L("KayceePvP.Final.ScoreLine", "FINAL SCORE: {0} - {1}", "PLACAR FINAL: {0} - {1}");
			PvpLocalization.L("KayceePvP.Final.Instructions", "SPACE: REMATCH WITH THE SAME DECKS   ·   N: NEW PREPARATION AND NEW LOBBY\nESC OR ENTER: CLOSE THE GAME", "ESPAÇO: REVANCHE COM OS MESMOS DECKS   ·   N: NOVA PREPARAÇÃO E NOVO LOBBY\nESC OU ENTER: FECHAR O JOGO");
			PvpLocalization.L("KayceePvP.Final.ClosingGame", "CLOSING THE GAME...", "FECHANDO O JOGO...");
			PvpLocalization.L("KayceePvP.Final.ReturningToPreparation", "RETURNING TO DECK SELECTION...", "VOLTANDO À SELEÇÃO DE BARALHO...");
			PvpLocalization.L("KayceePvP.Final.RematchUnavailable", "REMATCH UNAVAILABLE - CONNECTION TO THE OPPONENT LOST", "REVANCHE INDISPONÍVEL - CONEXÃO COM O OPONENTE PERDIDA");
			PvpLocalization.L("KayceePvP.Final.RematchAccepted", "REMATCH ACCEPTED - PREPARING THE NEXT SERIES...", "REVANCHE ACEITA - PREPARANDO A PRÓXIMA SÉRIE...");
			PvpLocalization.L("KayceePvP.Final.RematchRequestedByYou", "YOU REQUESTED A REMATCH - WAITING FOR THE OPPONENT...", "VOCÊ PEDIU REVANCHE - AGUARDANDO O OPONENTE...");
			PvpLocalization.L("KayceePvP.Final.RematchRequestedByPeer", "THE OPPONENT REQUESTED A REMATCH - PRESS SPACE TO ACCEPT", "O OPONENTE PEDIU REVANCHE - PRESSIONE ESPAÇO PRA ACEITAR");
		}

		private void Awake()
		{
			Instance = this;
			BuildUI();
			_canvasRoot.SetActive(false);
		}

		private void OnDestroy()
		{
			if ((Object)(object)Instance == (Object)(object)this)
			{
				Instance = null;
			}
		}

		private void Update()
		{
			if ((Object)(object)_canvasRoot == (Object)null || !_canvasRoot.activeSelf || _resetRequested)
			{
				return;
			}
			UpdateRematchStatusText();
			if (!(Time.realtimeSinceStartup < _inputArmedAt))
			{
				if (Input.GetKeyDown((KeyCode)27) || Input.GetKeyDown((KeyCode)13) || Input.GetKeyDown((KeyCode)271))
				{
					_resetRequested = true;
					_instructionText.text = PvpLocalization.Get("KayceePvP.Final.ClosingGame");
					Plugin.Log.LogInfo((object)"Duel (match-result): QUIT_REQUESTED");
					LobbySession.Instance?.QuitGameAfterMatch();
				}
				else if (Input.GetKeyDown((KeyCode)32))
				{
					LobbySession.Instance?.RequestRematch();
				}
				else if (Input.GetKeyDown((KeyCode)110))
				{
					_resetRequested = true;
					_instructionText.text = PvpLocalization.Get("KayceePvP.Final.ReturningToPreparation");
					Plugin.Log.LogInfo((object)"Duel (match-result): NEW_PREPARATION_REQUESTED");
					LobbySession.Instance?.ReturnToAscensionMenuAfterMatch();
				}
			}
		}

		private void UpdateRematchStatusText()
		{
			LobbySession instance = LobbySession.Instance;
			if (!((Object)(object)instance == (Object)null))
			{
				if (!instance.RematchAvailable)
				{
					_rematchStatusText.text = PvpLocalization.Get("KayceePvP.Final.RematchUnavailable");
				}
				else if (instance.RematchAccepted)
				{
					_rematchStatusText.text = PvpLocalization.Get("KayceePvP.Final.RematchAccepted");
				}
				else if (instance.LocalRematchRequested && !instance.PeerRematchRequested)
				{
					_rematchStatusText.text = PvpLocalization.Get("KayceePvP.Final.RematchRequestedByYou");
				}
				else if (!instance.LocalRematchRequested && instance.PeerRematchRequested)
				{
					_rematchStatusText.text = PvpLocalization.Get("KayceePvP.Final.RematchRequestedByPeer");
				}
				else
				{
					_rematchStatusText.text = "";
				}
			}
		}

		public static void Show(string winnerAbsoluteSide, int hostWins, int peerWins)
		{
			Instance?.ShowInternal(winnerAbsoluteSide, hostWins, peerWins);
		}

		public static void Hide()
		{
			Instance?.HideInternal();
		}

		private void ShowInternal(string winnerAbsoluteSide, int hostWins, int peerWins)
		{
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			bool num = string.Equals(winnerAbsoluteSide, "HOST", StringComparison.OrdinalIgnoreCase);
			LobbySession instance = LobbySession.Instance;
			string text = (((Object)(object)instance != (Object)null) ? instance.HostDisplayName : PvpLocalization.Get("KayceePvP.Lobby.DefaultPlayer1"));
			string text2 = (((Object)(object)instance != (Object)null) ? instance.PeerDisplayName : PvpLocalization.Get("KayceePvP.Lobby.DefaultPlayer2"));
			string text3 = (num ? text : text2);
			string text4 = (num ? text2 : text);
			_winnerText.text = PvpLocalization.Format("KayceePvP.Final.WinnerLine", text3);
			_loserText.text = PvpLocalization.Format("KayceePvP.Final.LoserLine", text4);
			_scoreText.text = PvpLocalization.Format("KayceePvP.Final.ScoreLine", hostWins, peerWins);
			_instructionText.text = PvpLocalization.Get("KayceePvP.Final.Instructions");
			_rematchStatusText.text = "";
			_resetRequested = false;
			_inputArmedAt = Time.realtimeSinceStartup + 0.75f;
			_previousCursorVisible = Cursor.visible;
			_previousCursorLockState = Cursor.lockState;
			Cursor.lockState = (CursorLockMode)0;
			Cursor.visible = true;
			InteractionCursor instance2 = Singleton<InteractionCursor>.Instance;
			_previousInteractionDisabled = (Object)(object)instance2 != (Object)null && instance2.InteractionDisabled;
			_previousInteractionCursorEnabled = (Object)(object)instance2 == (Object)null || ((Behaviour)instance2).enabled;
			if ((Object)(object)instance2 != (Object)null)
			{
				instance2.InteractionDisabled = true;
				instance2.SetEnabled(false);
			}
			_canvasRoot.SetActive(true);
			Plugin.Log.LogInfo((object)$"Duel (match-result): FINAL_SCREEN_SHOWN | winner={winnerAbsoluteSide} hostWins={hostWins} peerWins={peerWins}");
		}

		private void HideInternal()
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_canvasRoot == (Object)null) && _canvasRoot.activeSelf)
			{
				Cursor.visible = _previousCursorVisible;
				Cursor.lockState = _previousCursorLockState;
				InteractionCursor instance = Singleton<InteractionCursor>.Instance;
				if ((Object)(object)instance != (Object)null)
				{
					instance.SetEnabled(_previousInteractionCursorEnabled);
					instance.InteractionDisabled = _previousInteractionDisabled;
				}
				_canvasRoot.SetActive(false);
				_resetRequested = false;
			}
		}

		private void BuildUI()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: 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_0150: 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_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fc: 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_0237: Unknown result type (might be due to invalid IL or missing references)
			//IL_0246: Unknown result type (might be due to invalid IL or missing references)
			//IL_0272: 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)
			_canvasRoot = new GameObject("KayceePvP_FinalMatchCanvas");
			_canvasRoot.transform.SetParent(((Component)this).transform, false);
			Canvas obj = _canvasRoot.AddComponent<Canvas>();
			obj.renderMode = (RenderMode)0;
			obj.sortingOrder = 32760;
			CanvasScaler obj2 = _canvasRoot.AddComponent<CanvasScaler>();
			obj2.uiScaleMode = (ScaleMode)1;
			obj2.referenceResolution = new Vector2(1920f, 1080f);
			obj2.screenMatchMode = (ScreenMatchMode)0;
			obj2.matchWidthOrHeight = 0.5f;
			_canvasRoot.AddComponent<GraphicRaycaster>();
			Stretch(((Graphic)CreateImage("BlackBackdrop", _canvasRoot.transform, Color.black)).rectTransform);
			Image obj3 = CreateImage("Artwork", _canvasRoot.transform, Color.white);
			Stretch(((Graphic)obj3).rectTransform);
			obj3.preserveAspect = true;
			obj3.sprite = LoadEmbeddedSprite();
			((Graphic)obj3).raycastTarget = true;
			Image val = CreateImage("TopTextPanel", _canvasRoot.transform, new Color(0f, 0f, 0f, 0.76f));
			AnchorBand(((Graphic)val).rectTransform, 0.72f, 1f);
			Image val2 = CreateImage("BottomTextPanel", _canvasRoot.transform, new Color(0f, 0f, 0f, 0.78f));
			AnchorBand(((Graphic)val2).rectTransform, 0f, 0.18f);
			_winnerText = CreateText("Winner", ((Component)val).transform, new Vector2(0f, 55f), new Vector2(1700f, 64f), "", 42);
			_loserText = CreateText("Loser", ((Component)val).transform, new Vector2(0f, -15f), new Vector2(1700f, 54f), "", 30);
			_scoreText = CreateText("Score", ((Component)val).transform, new Vector2(0f, -75f), new Vector2(1200f, 46f), "", 26);
			_instructionText = CreateText("Instruction", ((Component)val2).transform, new Vector2(0f, 24f), new Vector2(1700f, 70f), "", 22);
			_rematchStatusText = CreateText("RematchStatus", ((Component)val2).transform, new Vector2(0f, -34f), new Vector2(1700f, 40f), "", 20);
		}

		private static Sprite LoadEmbeddedSprite()
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Expected O, but got Unknown
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("KayceePvP.Assets.tela_final_kayceepvp.png");
			if (stream == null)
			{
				Plugin.Log.LogError((object)"Duel (match-result): embedded background not found: KayceePvP.Assets.tela_final_kayceepvp.png");
				return null;
			}
			byte[] array = new byte[stream.Length];
			int num;
			for (int i = 0; i < array.Length; i += num)
			{
				num = stream.Read(array, i, array.Length - i);
				if (num <= 0)
				{
					break;
				}
			}
			Texture2D val = new Texture2D(2, 2, (TextureFormat)3, false);
			if (!ImageConversion.LoadImage(val, array, true))
			{
				Plugin.Log.LogError((object)"Duel (match-result): failed to decode embedded final-screen PNG.");
				Object.Destroy((Object)(object)val);
				return null;
			}
			((Object)val).name = "KayceePvP_FinalMatchBackground";
			((Texture)val).wrapMode = (TextureWrapMode)1;
			return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f);
		}

		private static Image CreateImage(string name, Transform parent, Color color)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) });
			val.transform.SetParent(parent, false);
			Image obj = val.AddComponent<Image>();
			((Graphic)obj).color = color;
			return obj;
		}

		private static Text CreateText(string name, Transform parent, Vector2 anchoredPosition, Vector2 size, string content, int fontSize)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: 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_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_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) });
			val.transform.SetParent(parent, false);
			RectTransform component = val.GetComponent<RectTransform>();
			component.anchorMin = new Vector2(0.5f, 0.5f);
			component.anchorMax = new Vector2(0.5f, 0.5f);
			component.pivot = new Vector2(0.5f, 0.5f);
			component.anchoredPosition = anchoredPosition;
			component.sizeDelta = size;
			Text obj = val.AddComponent<Text>();
			obj.text = content;
			obj.font = LobbyUI.ResolveGameFont();
			obj.fontSize = fontSize;
			obj.alignment = (TextAnchor)4;
			((Graphic)obj).color = Color.white;
			obj.horizontalOverflow = (HorizontalWrapMode)0;
			obj.verticalOverflow = (VerticalWrapMode)1;
			((Graphic)obj).raycastTarget = false;
			return obj;
		}

		private static void Stretch(RectTransform rect)
		{
			//IL_0001: 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_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			rect.anchorMin = Vector2.zero;
			rect.anchorMax = Vector2.one;
			rect.offsetMin = Vector2.zero;
			rect.offsetMax = Vector2.zero;
		}

		private static void AnchorBand(RectTransform rect, float minY, float maxY)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			rect.anchorMin = new Vector2(0f, minY);
			rect.anchorMax = new Vector2(1f, maxY);
			rect.offsetMin = Vector2.zero;
			rect.offsetMax = Vector2.zero;
		}
	}
	internal static class FixedMap
	{
		public static PredefinedNodes BuildFirstRegionMap()
		{
			PredefinedNodes obj = ScriptableObject.CreateInstance<PredefinedNodes>();
			obj.nodeRows = BuildRows();
			return obj;
		}

		public static List<List<NodeData>> BuildRows()
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Expected O, but got Unknown
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected O, but got Unknown
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Expected O, but got Unknown
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Expected O, but got Unknown
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Expected O, but got Unknown
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Expected O, but got Unknown
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Expected O, but got Unknown
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Expected O, but got Unknown
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Expected O, but got Unknown
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Expected O, but got Unknown
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_018d: Expected O, but got Unknown
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Expected O, but got Unknown
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Expected O, but got Unknown
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: Expected O, but got Unknown
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Expected O, but got Unknown
			//IL_01da: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e0: Expected O, but got Unknown
			//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e8: Expected O, but got Unknown
			List<List<NodeData>> list = new List<List<NodeData>>();
			list.Add(Row(new NodeData()));
			list.Add(Row((NodeData)new TradePeltsNodeData()));
			list.Add(Row((NodeData)Choices((CardChoicesType)1)));
			list.Add(Row((NodeData)new CardStatBoostNodeData(), (NodeData)new BuildTotemNodeData(), (NodeData)Choices((CardChoicesType)1)));
			list.Add(Row((NodeData)Choices((CardChoicesType)2), (NodeData)Choices((CardChoicesType)2), (NodeData)Choices((CardChoicesType)1)));
			list.Add(Row((NodeData)Choices((CardChoicesType)1), (NodeData)Choices((CardChoicesType)2), (NodeData)Choices((CardChoicesType)2)));
			list.Add(Row((NodeData)new CardRemoveNodeData(), (NodeData)Choices((CardChoicesType)2), (NodeData)new DeckTrialNodeData()));
			list.Add(Row((NodeData)Battle(1), (NodeData)Battle(1), (NodeData)Battle(1)));
			list.Add(Row((NodeData)Choices((CardChoicesType)2), (NodeData)new BuildTotemNodeData(), (NodeData)new BuyPeltsNodeData()));
			list.Add(Row((NodeData)new CopyCardNodeData(), (NodeData)Choices((CardChoicesType)2), (NodeData)new TradePeltsNodeData()));
			list.Add(Row((NodeData)new DuplicateMergeNodeData(), (NodeData)new CardMergeNodeData(), (NodeData)Choices((CardChoicesType)2)));
			list.Add(Row((NodeData)new CardMergeNodeData(), (NodeData)new CardStatBoostNodeData(), (NodeData)new CardMergeNodeData()));
			list.Add(Row((NodeData)new CardRemoveNodeData(), (NodeData)new CardRemoveNodeData(), (NodeData)Choices((CardChoicesType)1)));
			list.Add(Row((NodeData)new RareRewardNodeData()));
			list.Add(Row(new DeathcardNodeData()));
			return list;
		}

		private static List<NodeData> Row(params NodeData[] nodes)
		{
			return new List<NodeData>(nodes);
		}

		private static CardChoicesNodeData Choices(CardChoicesType type)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			return new CardChoicesNodeData
			{
				choicesType = type
			};
		}

		private static CardBattleNodeData Battle(int difficulty)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			return new CardBattleNodeData
			{
				difficulty = difficulty
			};
		}
	}
	internal static class LobbyMatchState
	{
		public const int WinsNeeded = 2;

		private static List<CardInfo> _frozenLocalDeck;

		public static int MatchId { get; private set; }

		public static int BattleNumber { get; private set; } = 1;

		public static int HostWins { get; private set; }

		public static int PeerWins { get; private set; }

		public static bool BattleInProgress { get; private set; }

		public static bool HostGoesFirstThisBattle => (uint)(MatchId + BattleNumber - 1) % 2u == 0;

		public static bool InterBattleSceneReloadActive { get; private set; }

		public static void BeginMatch(int matchId)
		{
			MatchId = matchId;
			BattleNumber = 1;
			HostWins = 0;
			PeerWins = 0;
			BattleInProgress = false;
			_frozenLocalDeck = CloneDeck(((CardCollectionInfo)RunState.Run.playerDeck).Cards);
			Plugin.Log.LogInfo((object)$"Duel (lobby-match): BeginMatch | match={matchId} frozenLocalDeckCount={_frozenLocalDeck.Count}");
		}

		public static void EndMatch()
		{
			BattleInProgress = false;
			Plugin.Log.LogInfo((object)$"Duel (lobby-match): EndMatch | match={MatchId} finalHostWins={HostWins} finalPeerWins={PeerWins}");
		}

		public static void BeginBattle()
		{
			BattleInProgress = true;
		}

		public static void RestoreLocalDeckForNextBattle()
		{
			if (_frozenLocalDeck == null)
			{
				Plugin.Log.LogWarning((object)"Duel (lobby-match): RestoreLocalDeckForNextBattle called with no frozen deck - BeginMatch was never called this match.");
				return;
			}
			DeckInfo playerDeck = RunState.Run.playerDeck;
			((CardCollectionInfo)playerDeck).Cards.Clear();
			foreach (CardInfo item in CloneDeck(_frozenLocalDeck))
			{
				((CardCollectionInfo)playerDeck).Cards.Add(item);
			}
		}

		public static bool ApplyBattleResult(bool loserIsHost)
		{
			if (loserIsHost)
			{
				PeerWins++;
			}
			else
			{
				HostWins++;
			}
			BattleInProgress = false;
			bool flag = HostWins >= 2 || PeerWins >= 2;
			Plugin.Log.LogInfo((object)$"Duel (lobby-match): ApplyBattleResult | match={MatchId} battle={BattleNumber} loserIsHost={loserIsHost} hostWins={HostWins} peerWins={PeerWins} isMatchFinal={flag}");
			return flag;
		}

		public static void ApplyAuthoritativeWins(int hostWins, int peerWins)
		{
			HostWins = hostWins;
			PeerWins = peerWins;
			BattleInProgress = false;
		}

		public static void AdvanceToNextBattle()
		{
			BattleNumber++;
		}

		public static void BeginInterBattleSceneReload()
		{
			InterBattleSceneReloadActive = true;
			Plugin.Log.LogInfo((object)$"Duel (lobby-match): INTERBATTLE_RELOAD_LATCH_ON | match={MatchId} battle={BattleNumber}");
		}

		public static void EndInterBattleSceneReload()
		{
			InterBattleSceneReloadActive = false;
			Plugin.Log.LogInfo((object)$"Duel (lobby-match): INTERBATTLE_RELOAD_LATCH_OFF | match={MatchId} battle={BattleNumber}");
		}

		private static List<CardInfo> CloneDeck(List<CardInfo> source)
		{
			List<CardInfo> list = new List<CardInfo>(source.Count);
			foreach (CardInfo item in source)
			{
				object obj = item.Clone();
				list.Add((CardInfo)((obj is CardInfo) ? obj : null));
			}
			return list;
		}
	}
	internal enum MapCompletionPolicy
	{
		Boss,
		RouteExit
	}
	internal static class MapDebug
	{
		private class MapNodeDump
		{
			public int id;

			public int gridX;

			public int gridY;

			public string nodeType;

			public int[] connectedNodeIds;

			public string extra;
		}

		public static void DumpNewMap()
		{
			if (RunState.Run == null)
			{
				Plugin.Log.LogWarning((object)"MapDebug: no active run - start a run first (e.g. via 'Testar sozinho').");
				return;
			}
			RunState.Run.GenerateMapDataForCurrentRegion((PredefinedNodes)null);
			MapNodeDump[] array = RunState.Run.map.nodeData.Select((NodeData n) => new MapNodeDump
			{
				id = ((MapElementData)n).id,
				gridX = n.gridX,
				gridY = n.gridY,
				nodeType = ((object)n).GetType().Name,
				connectedNodeIds = n.connectedNodes.Select((NodeData c) => ((MapElementData)c).id).ToArray(),
				extra = DescribeExtra(n)
			}).ToArray();
			string contents = BuildJson(array);
			string path = $"map_dump_{DateTime.Now:yyyyMMdd_HHmmss}.json";
			string text = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), path);
			File.WriteAllText(text, contents);
			Plugin.Log.LogInfo((object)$"MapDebug: dumped {array.Length} nodes to {text}");
		}

		private static string BuildJson(MapNodeDump[] nodes)
		{
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append("{\n  \"nodes\": [\n");
			for (int i = 0; i < nodes.Length; i++)
			{
				MapNodeDump mapNodeDump = nodes[i];
				stringBuilder.Append("    {");
				stringBuilder.Append($"\"id\":{mapNodeDump.id},");
				stringBuilder.Append($"\"gridX\":{mapNodeDump.gridX},");
				stringBuilder.Append($"\"gridY\":{mapNodeDump.gridY},");
				stringBuilder.Append("\"nodeType\":\"" + Escape(mapNodeDump.nodeType) + "\",");
				stringBuilder.Append("\"connectedNodeIds\":[" + string.Join(",", mapNodeDump.connectedNodeIds) + "],");
				stringBuilder.Append("\"extra\":\"" + Escape(mapNodeDump.extra) + "\"");
				stringBuilder.Append((i < nodes.Length - 1) ? "},\n" : "}\n");
			}
			stringBuilder.Append("  ]\n}");
			return stringBuilder.ToString();
		}

		private static string Escape(string s)
		{
			if (!string.IsNullOrEmpty(s))
			{
				return s.Replace("\\", "\\\\").Replace("\"", "\\\"");
			}
			return "";
		}

		private static string DescribeExtra(NodeData node)
		{
			//IL_0026: 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)
			BossBattleNodeData val = (BossBattleNodeData)(object)((node is BossBattleNodeData) ? node : null);
			if (val == null)
			{
				CardBattleNodeData val2 = (CardBattleNodeData)(object)((node is CardBattleNodeData) ? node : null);
				if (val2 == null)
				{
					CardChoicesNodeData val3 = (CardChoicesNodeData)(object)((node is CardChoicesNodeData) ? node : null);
					if (val3 != null)
					{
						return $"choicesType={val3.choicesType}";
					}
					return "";
				}
				return $"difficulty={val2.difficulty}";
			}
			return $"bossType={val.bossType}";
		}
	}
	internal enum MapMode
	{
		Battles,
		NoBattles,
		SymmetricForge,
		PeltDraft,
		BalancedPath,
		OpenDraftPath,
		BalancedRoute
	}
	internal static class MapModeCatalog
	{
		internal const int UnifiedDuelThreshold = 15;

		public static readonly IReadOnlyDictionary<MapMode, MapModeDescriptor> All = new Dictionary<MapMode, MapModeDescriptor>
		{
			[MapMode.Battles] = new MapModeDescriptor(MapMode.Battles, RegisterLabel("KayceePvP.MapMode.Battles", "WITH BATTLES", "COM BATALHAS"), FixedMap.BuildRows, 15, 15, MapCompletionPolicy.Boss, 3, new Dictionary<int, string>
			{
				[0] = "Refinamento",
				[1] = "Totem",
				[2] = "Expansao"
			}),
			[MapMode.NoBattles] = new MapModeDescriptor(MapMode.NoBattles, RegisterLabel("KayceePvP.MapMode.NoBattles", "WITHOUT BATTLES", "SEM BATALHAS"), NoBattleMap.BuildRows, 19, 15, MapCompletionPolicy.RouteExit, 6, new Dictionary<int, string>
			{
				[0] = "Refinamento",
				[1] = "Totem",
				[2] = "Replicacao"
			}),
			[MapMode.SymmetricForge] = new MapModeDescriptor(MapMode.SymmetricForge, RegisterLabel("KayceePvP.MapMode.SymmetricForge", "SYMMETRIC FORGE", "FORJA SIMÉTRICA"), SymmetricForgeMap.BuildRows, 20, 15, MapCompletionPolicy.Boss, null, null),
			[MapMode.PeltDraft] = new MapModeDescriptor(MapMode.PeltDraft, RegisterLabel("KayceePvP.MapMode.PeltDraft", "PELT DRAFT", "DRAFT DE PELES"), PeltDraftMap.BuildRows, 5, 15, MapCompletionPolicy.RouteExit, null, null),
			[MapMode.BalancedPath] = new MapModeDescriptor(MapMode.BalancedPath, RegisterLabel("KayceePvP.MapMode.BalancedPath", "TRIBE FIGHT", "TRIBE FIGHT"), BalancedPathMap.BuildRows, 19, 15, MapCompletionPolicy.RouteExit, null, null),
			[MapMode.OpenDraftPath] = new MapModeDescriptor(MapMode.OpenDraftPath, RegisterLabel("KayceePvP.MapMode.OpenDraftPath", "OPEN DRAFT", "DRAFT ABERTO"), OpenDraftPathMap.BuildRows, 3, 15, MapCompletionPolicy.RouteExit, null, null),
			[MapMode.BalancedRoute] = new MapModeDescriptor(MapMode.BalancedRoute, RegisterLabel("KayceePvP.MapMode.BalancedRoute", "BALANCED ROUTE", "CAMINHO BALANCEADO"), BalancedRouteMap.BuildRows, 20, 15, MapCompletionPolicy.RouteExit, null, null)
		};

		private static string RegisterLabel(string id, string english, string portuguese)
		{
			PvpLocalization.L(id, english, portuguese);
			return id;
		}

		public static bool TryGet(MapMode mode, out MapModeDescriptor descriptor)
		{
			return All.TryGetValue(mode, out descriptor);
		}

		public static bool IsSupported(int rawMapMode)
		{
			return All.ContainsKey((MapMode)rawMapMode);
		}

		public static MapModeDescriptor Get(MapMode mode)
		{
			return All[mode];
		}
	}
	internal sealed class MapModeDescriptor
	{
		private readonly string _uiLabelKey;

		public MapMode Mode { get; }

		public string UiLabel => PvpLocalization.Get(_uiLabelKey);

		public Func<List<List<NodeData>>> BuildRows { get; }

		public int RowCount { get; }

		public int DuelThreshold { get; }

		public MapCompletionPolicy CompletionPolicy { get; }

		public int? ForkGridY { get; }

		public IReadOnlyDictionary<int, string> RouteNamesByGridX { get; }

		public MapModeDescriptor(MapMode mode, string uiLabelKey, Func<List<List<NodeData>>> buildRows, int rowCount, int duelThreshold, MapCompletionPolicy completionPolicy, int? forkGridY, IReadOnlyDictionary<int, string> routeNamesByGridX)
		{
			Mode = mode;
			_uiLabelKey = uiLabelKey;
			BuildRows = buildRows;
			RowCount = rowCount;
			DuelThreshold = duelThreshold;
			CompletionPolicy = completionPolicy;
			ForkGridY = forkGridY;
			RouteNamesByGridX = routeNamesByGridX;
		}
	}
	internal class NoBattleExitNodeData : NodeData
	{
		public override string PrefabPath => "Prefabs/Map/MapNodesPart1/MapNode_CardBattle";
	}
	internal static class NoBattleMap
	{
		public const int RowCount = 19;

		public static PredefinedNodes BuildFirstRegionMap()
		{
			PredefinedNodes obj = ScriptableObject.CreateInstance<PredefinedNodes>();
			obj.nodeRows = BuildRows();
			return obj;
		}

		public static List<List<NodeData>> BuildRows()
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Expected O, but got Unknown
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected O, but got Unknown
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Expected O, but got Unknown
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Expected O, but got Unknown
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Expected O, but got Unknown
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Expected O, but got Unknown
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Expected O, but got Unknown
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Expected O, but got Unknown
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Expected O, but got Unknown
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Expected O, but got Unknown
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Expected O, but got Unknown
			//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Expected O, but got Unknown
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0205: Expected O, but got Unknown
			//IL_0207: Unknown result type (might be due to invalid IL or missing references)
			//IL_020d: Expected O, but got Unknown
			//IL_027d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0283: Expected O, but got Unknown
			List<List<NodeData>> list = new List<List<NodeData>>();
			list.Add(Row(new NodeData()));
			list.Add(Row((NodeData)new TradePeltsNodeData()));
			list.Add(Row((NodeData)Choices((CardChoicesType)2)));
			list.Add(Row((NodeData)Choices((CardChoicesType)0)));
			list.Add(Row((NodeData)Choices((CardChoicesType)2)));
			list.Add(Row((NodeData)Choices((CardChoicesType)0)));
			list.Add(Row((NodeData)new CardRemoveNodeData(), (NodeData)Choices((CardChoicesType)2), (NodeData)Choices((CardChoicesType)1)));
			list.Add(Row((NodeData)Choices((CardChoicesType)1), (NodeData)new BuildTotemNodeData(), (NodeData)new CardRemoveNodeData()));
			list.Add(Row((NodeData)Choices((CardChoicesType)0), (NodeData)Choices((CardChoicesType)2), (NodeData)Choices((CardChoicesType)0)));
			list.Add(Row((NodeData)new CardStatBoostNodeData(), (NodeData)new CardRemoveNodeData(), (NodeData)new CopyCardNodeData()));
			list.Add(Row((NodeData)Choices((CardChoicesType)0), (NodeData)new DeckTrialNodeData(), (NodeData)Choices((CardChoicesType)2)));
			list.Add(Row((NodeData)new CardStatBoostNodeData(), (NodeData)Choices((CardChoicesType)2), (NodeData)new DuplicateMergeNodeData()));
			list.Add(Row((NodeData)new CardStatBoostNodeData(), (NodeData)Choices((CardChoicesType)2), (NodeData)Choices((CardChoicesType)0)));
			list.Add(Row((NodeData)Choices((CardChoicesType)2), (NodeData)Choices((CardChoicesType)2), (NodeData)Choices((CardChoicesType)2)));
			list.Add(Row((NodeData)new DeckTrialNodeData(), (NodeData)new BuildTotemNodeData(), (NodeData)Choices((CardChoicesType)1)));
			list.Add(Row((NodeData)Choices((CardChoicesType)1), new NoBattleExitNodeData(), new NoBattleExitNodeData()));
			list.Add(Row((NodeData)Choices((CardChoicesType)1), new NoBattleExitNodeData(), new NoBattleExitNodeData()));
			list.Add(Row((NodeData)new CardMergeNodeData(), new NoBattleExitNodeData(), new NoBattleExitNodeData()));
			list.Add(Row(new NoBattleExitNodeData(), new NoBattleExitNodeData(), new NoBattleExitNodeData()));
			return list;
		}

		private static List<NodeData> Row(params NodeData[] nodes)
		{
			return new List<NodeData>(nodes);
		}

		private static CardChoicesNodeData Choices(CardChoicesType type)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			return new CardChoicesNodeData
			{
				choicesType = type
			};
		}
	}
	internal static class NoBattleRouteCompletionFlow
	{
		internal static void RegisterLocalizedText()
		{
			PvpLocalization.L("KayceePvP.Duel.WaitingForOpponentRouteTitle", "WAITING FOR THE OPPONENT TO FINISH THE ROUTE", "AGUARDANDO O OPONENTE TERMINAR O CAMINHO");
		}

		public static void OnLocalRouteCompleted()
		{
			if (!PvpRunState.LocalRouteCompletedNoBattles)
			{
				PvpRunState.LocalRouteCompletedNoBattles = true;
				RunState run = RunState.Run;
				int? obj;
				if (run == null)
				{
					obj = null;
				}
				else
				{
					DeckInfo playerDeck = run.playerDeck;
					obj = ((playerDeck != null) ? new int?(((CardCollectionInfo)playerDeck).Cards.Count) : ((int?)null));
				}
				int num = obj ?? (-1);
				Plugin.Log.LogInfo((object)$"PvP (sem batalhas): rota local concluída ({num} cartas) - iniciando o handoff compartilhado.");
				Telemetry.Log("route_completed_no_battles", $"route={PvpRunState.Route} deckSize={num}");
				((MonoBehaviour)LobbySession.Instance).StartCoroutine(PvpCardCreationFlow.WaitForPeerDeckThenDuel(PvpLocalization.Get("KayceePvP.Duel.WaitingForOpponentRouteTitle")));
			}
		}
	}
	internal class NoBattleWaitingScreen : MonoBehaviour
	{
		private GameObject _canvasRoot;

		private Text _titleText;

		private Text _subtitleText;

		private Text _deckListText;

		private Text _cancelHintText;

		private bool _errorMode;

		private bool _prevCursorVisible;

		private CursorLockMode _prevCursorLockState;

		private bool _prevInteractionDisabled;

		private bool _prevInteractionCursorEnabled;

		public static NoBattleWaitingScreen Instance { get; private set; }

		internal static void RegisterLocalizedText()
		{
			PvpLocalization.L("KayceePvP.Waiting.YourDeckSubtitle", "Your current deck:", "Seu baralho atual:");
			PvpLocalization.L("KayceePvP.Waiting.EmptyDeck", "(empty deck)", "(baralho vazio)");
			PvpLocalization.L("KayceePvP.Waiting.CancelHint", "PRESS ESC TO CANCEL", "PRESSIONE ESC PARA CANCELAR");
		}

		private void Awake()
		{
			Instance = this;
			BuildUI();
			_canvasRoot.SetActive(false);
		}

		private void Update()
		{
			if (_errorMode && (Input.GetKeyDown((KeyCode)13) || Input.GetKeyDown((KeyCode)271) || Input.GetKeyDown((KeyCode)32)))
			{
				Plugin.Log.LogInfo((object)"PvP handoff: peer-wait error screen - player requested quit.");
				LobbySession.Instance?.QuitGameAfterMatch();
			}
		}

		public static void Show(List<CardInfo> deck, string title = null)
		{
			Instance?.ShowInternal(deck, title ?? PvpLocalization.Get("KayceePvP.Duel.WaitingForOpponentTitle"));
		}

		public static void ShowError(string message)
		{
			Instance?.ShowErrorInternal(message);
		}

		public static void Hide()
		{
			Instance?.HideInternal();
		}

		private void ShowInternal(List<CardInfo> deck, string title)
		{
			_errorMode = false;
			_titleText.text = title;
			((Component)_subtitleText).gameObject.SetActive(true);
			_subtitleText.text = PvpLocalization.Get("KayceePvP.Waiting.YourDeckSubtitle");
			((Component)_deckListText).gameObject.SetActive(true);
			_deckListText.text = BuildDeckListText(deck);
			_cancelHintText.text = PvpLocalization.Get("KayceePvP.Waiting.CancelHint");
			((Component)_cancelHintText).gameObject.SetActive(true);
			ApplyOverlayState();
		}

		private void ShowErrorInternal(string message)
		{
			_errorMode = true;
			_titleText.text = message;
			((Component)_subtitleText).gameObject.SetActive(false);
			((Component)_deckListText).gameObject.SetActive(false);
			((Component)_cancelHintText).gameObject.SetActive(false);
			ApplyOverlayState();
		}

		private void ApplyOverlayState()
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			if (!_canvasRoot.activeSelf)
			{
				_prevCursorVisible = Cursor.visible;
				_prevCursorLockState = Cursor.lockState;
				InteractionCursor instance = Singleton<InteractionCursor>.Instance;
				_prevInteractionDisabled = (Object)(object)instance != (Object)null && instance.InteractionDisabled;
				_prevInteractionCursorEnabled = (Object)(object)instance == (Object)null || ((Behaviour)instance).enabled;
			}
			Cursor.lockState = (CursorLockMode)0;
			Cursor.visible = true;
			InteractionCursor instance2 = Singleton<InteractionCursor>.Instance;
			if ((Object)(object)instance2 != (Object)null)
			{
				instance2.InteractionDisabled = true;
				instance2.SetEnabled(false);
			}
			_canvasRoot.SetActive(true);
		}

		private void HideInternal()
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			_errorMode = false;
			if (_canvasRoot.activeSelf)
			{
				Cursor.visible = _prevCursorVisible;
				Cursor.lockState = _prevCursorLockState;
				InteractionCursor instance = Singleton<InteractionCursor>.Instance;
				if ((Object)(object)instance != (Object)null)
				{
					instance.SetEnabled(_prevInteractionCursorEnabled);
					instance.InteractionDisabled = _prevInteractionDisabled;
				}
				_canvasRoot.SetActive(false);
			}
		}

		private static string BuildDeckListText(List<CardInfo> deck)
		{
			if (deck == null || deck.Count == 0)
			{
				return PvpLocalization.Get("KayceePvP.Waiting.EmptyDeck");
			}
			return string.Join("\n", from c in deck
				group c by c.DisplayedNameLocalized into g
				orderby g.Key
				select (g.Count() <= 1) ? g.Key : $"{g.Key} x{g.Count()}");
		}

		private void BuildUI()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: 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_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: 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_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_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0229: Unknown result type (might be due to invalid IL or missing references)
			_canvasRoot = new GameObject("KayceePvP_NoBattleWaitingCanvas");
			_canvasRoot.transform.SetParent(((Component)this).transform, false);
			Canvas obj = _canvasRoot.AddComponent<Canvas>();
			obj.renderMode = (RenderMode)0;
			obj.sortingOrder = 31000;
			CanvasScaler obj2 = _canvasRoot.AddComponent<CanvasScaler>();
			obj2.uiScaleMode = (ScaleMode)1;
			obj2.referenceResolution = new Vector2(1920f, 1080f);
			_canvasRoot.AddComponent<GraphicRaycaster>();
			RectTransform component = CreateImage("Backdrop", _canvasRoot.transform, new Color(0f, 0f, 0f, 0.85f)).GetComponent<RectTransform>();
			component.anchorMin = Vector2.zero;
			component.anchorMax = Vector2.one;
			component.offsetMin = Vector2.zero;
			component.offsetMax = Vector2.zero;
			_titleText = CreateText("Title", _canvasRoot.transform, new Vector2(0f, 320f), new Vector2(700f, 80f), PvpLocalization.Get("KayceePvP.Duel.WaitingForOpponentTitle"), 24, (TextAnchor)4);
			((Graphic)_titleText).color = Color.white;
			_subtitleText = CreateText("Subtitle", _canvasRoot.transform, new Vector2(0f, 270f), new Vector2(700f, 30f), "Seu baralho atual:", 16, (TextAnchor)4);
			_deckListText = CreateText("DeckList", _canvasRoot.transform, new Vector2(0f, 0f), new Vector2(700f, 500f), "", 15, (TextAnchor)1);
			((Graphic)_deckListText).color = new Color(0.9f, 0.9f, 0.9f);
			_cancelHintText = CreateText("CancelHint", _canvasRoot.transform, new Vector2(0f, -380f), new Vector2(700f, 30f), PvpLocalization.Get("KayceePvP.Waiting.CancelHint"), 14, (TextAnchor)4);
			((Graphic)_cancelHintText).color = new Color(0.7f, 0.7f, 0.7f);
			((Component)_cancelHintText).gameObject.SetActive(false);
		}

		private static GameObject CreateImage(string name, Transform parent, Color color)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Expected O, but got Unknown
			GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) });
			val.transform.SetParent(parent, false);
			Image obj = val.AddComponent<Image>();
			((Graphic)obj).color = color;
			((Graphic)obj).raycastTarget = true;
			return val;
		}

		private Text CreateText(string name, Transform parent, Vector2 anchoredPos, Vector2 size, string content, int fontSize, TextAnchor alignment)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: 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_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_009a: 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)
			GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) });
			val.transform.SetParent(parent, false);
			RectTransform component = val.GetComponent<RectTransform>();
			component.anchorMin = new Vector2(0.5f, 0.5f);
			component.anchorMax = new Vector2(0.5f, 0.5f);
			component.pivot = new Vector2(0.5f, 0.5f);
			component.sizeDelta = size;
			component.anchoredPosition = anchoredPos;
			Text obj = val.AddComponent<Text>();
			obj.text = content;
			obj.font = LobbyUI.ResolveGameFont();
			obj.fontSize = fontSize;
			obj.alignment = alignment;
			((Graphic)obj).color = Color.white;
			obj.horizontalOverflow = (HorizontalWrapMode)0;
			return obj;
		}
	}
	public enum OpenDraftTier
	{
		Rabbit,
		Wolf,
		Golden
	}
	public static class OpenDraftBudget
	{
		public const int RabbitLimit = 8;

		public const int WolfLimit = 4;

		public const int GoldenLimit = 2;

		public static OpenDraftTier TierForPower(int powerLevel)
		{
			if (powerLevel < 4)
			{
				if (powerLevel < 3)
				{
					return OpenDraftTier.Rabbit;
				}
				return OpenDraftTier.Wolf;
			}
			return OpenDraftTier.Golden;
		}

		public static int Limit(OpenDraftTier tier)
		{
			return tier switch
			{
				OpenDraftTier.Wolf => 4, 
				OpenDraftTier.Rabbit => 8, 
				_ => 2, 
			};
		}

		public static bool CanAdd(IReadOnlyCollection<OpenDraftTier> selected, OpenDraftTier tier)
		{
			int num = 0;
			foreach (OpenDraftTier item in selected)
			{
				if (item == tier)
				{
					num++;
				}
			}
			return num < Limit(tier);
		}

		public static bool IsComplete(IReadOnlyCollection<OpenDraftTier> selected)
		{
			if (selected.Count != 14)
			{
				return false;
			}
			int num = 0;
			int num2 = 0;
			int num3 = 0;
			using (IEnumerator<OpenDraftTier> enumerator = selected.GetEnumerator())
			{
				while (enumerator.MoveNext())
				{
					switch (enumerator.Current)
					{
					case OpenDraftTier.Rabbit:
						num++;
						break;
					case OpenDraftTier.Wolf:
						num2++;
						break;
					default:
						num3++;
						break;
					}
				}
			}
			if (num == 8 && num2 == 4)
			{
				return num3 == 2;
			}
			return false;
		}
	}
	public static class OpenDraftCardPool
	{
		public const int PageSize = 8;

		private const int SeedDomain = 500000;

		public static bool IsAllowedName(string cardName)
		{
			if (cardName != "Lice" && cardName != "Hrokkall")
			{
				return PvpCardPoolRules.IsAllowedByName(cardName, null);
			}
			return false;
		}

		public static int ComputeSeed(int sharedMapSeed, int currentNodeId)
		{
			return sharedMapSeed + 500000 + currentNodeId;
		}

		public static List<string> DeriveOrder(IReadOnlyList<string> cardNames, int sharedMapSeed, int currentNodeId = 0)
		{
			List<string> list = new List<string>(cardNames);
			Random random = new Random(ComputeSeed(sharedMapSeed, currentNodeId));
			for (int num = list.Count - 1; num > 0; num--)
			{
				int num2 = random.Next(num + 1);
				List<string> list2 = list;
				int index = num;
				List<string> list3 = list;
				int index2 = num2;
				string value = list[num2];
				string value2 = list[num];
				list2[index] = value;
				list3[index2] = value2;
			}
			return list;
		}

		public static int PageCount(int totalCount)
		{
			if (totalCount > 0)
			{
				return (totalCount + 8 - 1) / 8;
			}
			return 0;
		}

		public static int ClampPage(int requestedPage, int totalCount)
		{
			int num = PageCount(totalCount);
			if (num == 0)
			{
				return 0;
			}
			return Math.Max(0, Math.Min(requestedPage, num - 1));
		}

		public static List<string> GetPage(IReadOnlyList<string> orderedNames, int pageIndex)
		{
			int num = pageIndex * 8;
			if (pageIndex < 0 || num >= orderedNames.Count)
			{
				return new List<string>();
			}
			return orderedNames.Skip(num).Take(8).ToList();
		}
	}
	internal sealed class OpenDraftNodeData : SpecialNodeData
	{
		public override string PrefabPath => ((MapElementData)new CardChoicesNodeData
		{
			choicesType = (CardChoicesType)2
		}).PrefabPath;
	}
	internal static class OpenDraftPathMap
	{
		public const int RowCount = 3;

		public static List<List<NodeData>> BuildRows()
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Expected O, but got Unknown
			List<List<NodeData>> list = new List<List<NodeData>>();
			list.Add(Row(new NodeData()));
			list.Add(Row((NodeData)new OpenDraftNodeData()));
			list.Add(Row(new NoBattleExitNodeData()));
			return list;
		}

		private static List<NodeData> Row(params NodeData[] nodes)
		{
			return new List<NodeData>(nodes);
		}
	}
	public static class OpenDraftSelectionState
	{
		public const int TargetCount = 14;

		public static bool CanFinalize(IReadOnlyCollection<string> selected)
		{
			return selected.Count == 14;
		}

		public static List<string> ApplyPick(IReadOnlyList<string> selected, string cardName)
		{
			List<string> list = new List<string>(selected);
			int num = list.IndexOf(cardName);
			if (num >= 0)
			{
				list.RemoveAt(num);
				return list;
			}
			if (list.Count >= 14)
			{
				return list;
			}
			list.Add(cardName);
			return list;
		}

		public static List<string> UndoLast(IReadOnlyList<string> selected)
		{
			if (selected.Count == 0)
			{
				return new List<string>(selected);
			}
			List<string> list = new List<string>(selected);
			list.RemoveAt(list.Count - 1);
			return list;
		}

		public static bool IsSelected(IReadOnlyCollection<string> selected, string cardName)
		{
			return selected.Contains(cardName);
		}
	}
	public static class PeltDraftAcquiredCards
	{
		public const string MarkerId = "pelt_draft_trader_acquired";

		public static void Mark(CardInfo card)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			if (!((Object)(object)card == (Object)null) && !IsMarked(card))
			{
				card.Mods.Add(new CardModificationInfo
				{
					singletonId = "pelt_draft_trader_acquired"
				});
			}
		}

		public static bool IsMarked(CardInfo card)
		{
			if ((Object)(object)card != (Object)null && card.Mods != null)
			{
				return card.Mods.Exists((CardModificationInfo m) => m.singletonId == "pelt_draft_trader_acquired");
			}
			return false;
		}

		public static List<CardInfo> OnlyMarked(List<CardInfo> cards)
		{
			cards.RemoveAll((CardInfo c) => !IsMarked(c));
			return cards;
		}
	}
	internal static class PeltDraftMap
	{
		public const int RowCount = 5;

		public static List<List<NodeData>> BuildRows()
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Expected O, but got Unknown
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected O, but got Unknown
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Expected O, but got Unknown
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Expected O, but got Unknown
			List<List<NodeData>> list = new List<List<NodeData>>();
			list.Add(Row(new NodeData()));
			list.Add(Row((NodeData)new TradePeltsNodeData()));
			list.Add(Row((NodeData)new TradePeltsNodeData()));
			list.Add(Row((NodeData)new TradePeltsNodeData()));
			list.Add(Row(new NoBattleExitNodeData()));
			return list;
		}

		private static List<NodeData> Row(params NodeData[] nodes)
		{
			return new List<NodeData>(nodes);
		}
	}
	public static class PeltDraftPlan
	{
		public const int StartingRabbit = 3;

		public const int StartingWolf = 2;

		public const int StartingGolden = 1;

		public const int SecondRabbit = 3;

		public const int SecondWolf = 2;

		public const int SecondGolden = 1;

		public const int FinalRabbit = 2;

		public const int FirstVisitCards = 6;

		public const int SecondVisitCards = 6;

		public const int ThirdVisitCards = 2;

		public const int FinalDeckSize = 14;

		public static bool IsForbiddenOfferName(string cardName)
		{
			if (!(cardName == "Lice"))
			{
				return cardName == "Hrokkall";
			}
			return true;
		}
	}
	public static class PeltDraftTraderSeed
	{
		public static int Compute(int sharedMapSeed, int regionTier, int currentNodeId)
		{
			return sharedMapSeed + regionTier * 100 + currentNodeId;
		}
	}
	[BepInPlugin("jgs.inscryption.kayceepvp", "KayceePvP", "0.1.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		public const string PluginGuid = "jgs.inscryption.kayceepvp";

		public const string PluginName = "KayceePvP";

		public const string PluginVersion = "0.1.0";

		internal static ManualLogSource Log;

		internal static ConfigEntry<bool> MultiplayerEnabled;

		internal static ConfigEntry<bool> CreatorCreditEnabled;

		internal static ConfigEntry<KeyboardShortcut> FeedbackShortcut;

		internal static ConfigEntry<bool> PvpItemsEnabled;

		internal static ConfigEntry<string> RelayHost;

		internal static ConfigEntry<int> RelayPort;

		private Harmony _harmony;

		private void Awake()
		{
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			MultiplayerEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "EnableMultiplayer", true, "Liga/desliga o lobby e o duelo em rede do KayceePvP. Desligado, o jogo roda normal (vanilla + as trocas de carta permanentes).");
			CreatorCreditEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShowCreatorCredit", true, "Mostra periodicamente a assinatura discreta 'KayceePvP · Designed by YNASTRA' em um canto da tela.");
			PvpItemsEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "EnablePvpItems", false, "Libera o uso de um subconjunto auditado de itens consumíveis (bateria, cofrinho, lupa, garrafa de carta, garrafa de goo) durante o duelo PvP. Itens que afetam o tabuleiro do oponente continuam bloqueados independente disso.");
			FeedbackShortcut = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("General", "FeedbackShortcut", FeedbackConfig.DefaultShortcut, "Tecla que abre a página de feedback/sugestões do KayceePvP no navegador (padrão F10 - F12 conflita com o print padrão da Steam). Não coleta nem envia nenhum log/dado automaticamente.");
			RelayHost = ((BaseUnityPlugin)this).Config.Bind<string>("Online", "RelayHost", "kayceepvp.duckdns.org", "Hostname público do relay KayceePvP. Deve corresponder ao certificado TLS; deixe vazio para desativar o online.");
			RelayPort = ((BaseUnityPlugin)this).Config.Bind<int>("Online", "RelayPort", 443, "Porta TLS do relay KayceePvP (normalmente 443).");
			LobbySession.RegisterLocalizedText();
			DuelHud.RegisterLocalizedText();
			PvpCardCreationFlow.RegisterLocalizedText();
			NoBattleRouteCompletionFlow.RegisterLocalizedText();
			NoBattleWaitingScreen.RegisterLocalizedText();
			FinalMatchScreen.RegisterLocalizedText();
			ProtocolDesyncOverlay.RegisterLocalizedText();
			OpenDraftFlow.RegisterLocalizedText();
			LobbyUI.RegisterLocalizedText();
			CreatorCreditOverlay.RegisterLocalizedText();
			Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
			((Component)this).gameObject.AddComponent<LobbySession>();
			((Component)this).gameObject.AddComponent<DuelSession>();
			((Component)this).gameObject.AddComponent<LobbyUI>();
			((Component)this).gameObject.AddComponent<DuelHud>();
			((Component)this).gameObject.AddComponent<NoBattleWaitingScreen>();
			((Component)this).gameObject.AddComponent<FinalMatchScreen>();
			((Component)this).gameObject.AddComponent<ProtocolDesyncOverlay>();
			((Component)this).gameObject.AddComponent<CreatorCreditOverlay>();
			_harmony = new Harmony("jgs.inscryption.kayceepvp");
			_harmony.PatchAll();
			PvpDialogueOverrides.Initialize();
			CardEdits.Apply();
			_ = PvpCardMutations.PackRatMarker;
			TvfsStarterDeckAllowlist.Apply();
			CobaiasStarterDeck.Apply();
			SelfCheck.RunOwnershipMatrix();
			SelfCheck.RunStarterDeckGateMatrix();
			SelfCheck.RunStarterDeckAllowlistMatrix();
			SelfCheck.RunConvergenceCheck();
			SelfCheck.RunRematchProtocolMatrix();
			SelfCheck.RunPvpItemAllowlistMatrix();
			Log.LogInfo((object)"KayceePvP 0.1.0 loaded.");
		}

		private void OnDestroy()
		{
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}
	}
	internal class ProtocolDesyncOverlay : MonoBehaviour
	{
		private GameObject _root;

		private Text _text;

		private bool _shown;

		internal static void RegisterLocalizedText()
		{
			PvpLocalization.L("KayceePvP.Protocol.DesyncMessage", "SYNCHRONIZATION LOST\nCLOSE AND RESTART THE MATCH\n\nPRESS ENTER OR SPACE TO CLOSE THE GAME", "SINCRONIZAÇÃO PERDIDA\nFECHE E REINICIE A PARTIDA\n\nPRESSIONE ENTER OU ESPAÇO PARA FECHAR O JOGO");
			PvpLocalization.L("KayceePvP.Protocol.ConnectionLostMessage", "CONNECTION TO THE OPPONENT LOST\nCLOSE AND RESTART THE MATCH\n\nPRESS ENTER OR SPACE TO CLOSE THE GAME", "CONEXÃO COM O OPONENTE PERDIDA\nFECHE E REINICIE A PARTIDA\n\nPRESSIONE ENTER OU ESPAÇO PARA FECHAR O JOGO");
		}

		private void Awake()
		{
			BuildUI();
			_root.SetActive(false);
		}

		private void Update()
		{
			DuelSession instance = DuelSession.Instance;
			bool flag = (Object)(object)instance != (Object)null && instance.ProtocolDesync;
			bool flag2 = (Object)(object)instance != (Object)null && instance.ConnectionLost;
			bool flag3 = flag || flag2;
			if (flag3 != _shown)
			{
				_root.SetActive(flag3);
				_shown = flag3;
				if (flag3)
				{
					if (flag)
					{
						_text.text = PvpLocalization.Get("KayceePvP.Protocol.DesyncMessage");
						Plugin.Log.LogError((object)("Duel: PROTOCOL_DESYNC_OVERLAY_SHOWN | reason=" + instance.ProtocolDesyncReason));
					}
					else
					{
						_text.text = PvpLocalization.Get("KayceePvP.Protocol.ConnectionLostMessage");
						Plugin.Log.LogError((object)("Duel: CONNECTION_LOST_OVERLAY_SHOWN | reason=" + instance.ConnectionLostReason));
					}
				}
			}
			if (flag3 && (Input.GetKeyDown((KeyCode)13) || Input.GetKeyDown((KeyCode)271) || Input.GetKeyDown((KeyCode)32)))
			{
				Plugin.Log.LogInfo((object)(flag ? "Duel: PROTOCOL_DESYNC_QUIT_REQUESTED" : "Duel: CONNECTION_LOST_QUIT_REQUESTED"));
				LobbySession.Instance?.QuitGameAfterMatch();
			}
		}

		private void BuildUI()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			//IL_006b: 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_0093: Expected O, but got Unknown
			//IL_00c5: 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_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Expected O, but got Unknown
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			_root = new GameObject("KayceePvP_ProtocolDesyncOverlay");
			_root.transform.SetParent(((Component)this).transform, false);
			Canvas obj = _root.AddComponent<Canvas>();
			obj.renderMode = (RenderMode)0;
			obj.sortingOrder = 33000;
			_root.AddComponent<GraphicRaycaster>();
			CanvasScaler obj2 = _root.AddComponent<CanvasScaler>();
			obj2.uiScaleMode = (ScaleMode)1;
			obj2.referenceResolution = new Vector2(1920f, 1080f);
			GameObject val = new GameObject("Backdrop", new Type[1] { typeof(RectTransform) });
			val.transform.SetParent(_root.transform, false);
			Image obj3 = val.AddComponent<Image>();
			((Graphic)obj3).color = new Color(0f, 0f, 0f, 0.92f);
			((Graphic)obj3).raycastTarget = true;
			RectTransform component = val.GetComponent<RectTransform>();
			component.anchorMin = Vector2.zero;
			component.anchorMax = Vector2.one;
			component.offsetMin = Vector2.zero;
			component.offsetMax = Vector2.zero;
			GameObject val2 = new GameObject("Text", new Type[1] { typeof(RectTransform) });
			val2.transform.SetParent(val.transform, false);
			RectTransform component2 = val2.GetComponent<RectTransform>();
			component2.anchorMin = new Vector2(0.1f, 0.35f);
			component2.anchorMax = new Vector2(0.9f, 0.65f);
			component2.offsetMin = Vector2.zero;
			component2.offsetMax = Vector2.zero;
			_text = val2.AddComponent<Text>();
			_text.font = LobbyUI.ResolveGameFont();
			_text.fontSize = 28;
			_text.alignment = (TextAnchor)4;
			((Graphic)_text).color = Color.white;
			((Graphic)_text).raycastTarget = false;
			_text.horizontalOverflow = (HorizontalWrapMode)1;
			_text.verticalOverflow = (VerticalWrapMode)1;
			_text.text = PvpLocalization.Get("KayceePvP.Protocol.DesyncMessage");
		}
	}
	internal static class PvpCardCreationFlow
	{
		internal readonly struct F6DeckLineEntry
		{
			internal readonly string RequestedName;

			internal readonly int Count;

			internal F6DeckLineEntry(string requestedName, int count)
			{
				RequestedName = requestedName;
				Count = count;
			}
		}

		internal enum PeerWaitOutcome
		{
			Waiting,
			Success,
			Cancelled,
			Disconnected,
			TimedOut
		}

		internal const int F6DeckMinCards = 4;

		internal const int F6DeckMaxCards = 40;

		internal const string F6DeckConfigFileName = "KayceePvP.F6Deck.txt";

		internal static readonly string[] DefaultF6DeckLines = new string[4] { "# COBAIAS default (arquivo de config ausente/recriado automaticamente)", "PackRat x4", "MealWorm x3", "Skink x3" };

		private static readonly Regex F6DeckQuantityPattern = new Regex("^(?<name>.+)[xX*](?<qty>-?\\d+)$", RegexOptions.Compiled);

		private static readonly float PeerDeckWaitTimeoutSeconds = ResolvePeerDeckWaitTimeoutSeconds();

		private const float DefaultPeerDeckWaitTimeoutSeconds = 21600f;

		private static bool WaitOrShowRecoverableErrorFailed;

		internal static void RegisterLocalizedText()
		{
			PvpLocalization.L("KayceePvP.Duel.F6InvalidDeckOnScreen", "F6 DEBUG: INVALID DECK - SEE LogOutput.log", "F6 DEBUG: DECK INVALIDO - VER LogOutput.log");
			PvpLocalization.L("KayceePvP.Duel.ErrorConnectionLostDuringWait", "CONNECTION TO THE OPPONENT LOST.\n{0}", "CONEXÃO COM O OPONENTE PERDIDA.\n{0}");
			PvpLocalization.L("KayceePvP.Duel.ErrorWaitCancelled", "WAIT CANCELLED.", "ESPERA CANCELADA.");
			PvpLocalization.L("KayceePvP.Duel.WaitingForOpponentTitle", "WAITING FOR OPPONENT", "AGUARDANDO OPONENTE");
			PvpLocalization.L("KayceePvP.Duel.ErrorTimeoutWaitingDeck", "TIMED OUT WAITING FOR THE OPPONENT TO FINISH PREPARING.", "TEMPO ESGOTADO ESPERANDO O OPONENTE TERMINAR A PREPARAÇÃO.");
			PvpLocalization.L("KayceePvP.Duel.ErrorTimeoutWaitingReady", "TIMED OUT WAITING FOR THE OPPONENT.", "TEMPO ESGOTADO ESPERANDO O OPONENTE.");
			PvpLocalization.L("KayceePvP.Duel.ReadyPrompt", "PRESS SPACE WHEN YOU'RE READY", "PRESSIONE ESPAÇO QUANDO ESTIVER PRONTO");
			PvpLocalization.L("KayceePvP.Duel.WaitingOpponentReadyPrompt", "WAITING FOR OPPONENT... (ESC TO CANCEL)", "AGUARDANDO OPONENTE... (ESC PARA CANCELAR)");
			PvpLocalization.L("KayceePvP.Duel.GetReadyLine", "GET READY. NOW YOUR DECK WILL HAVE TO JUSTIFY ALL THAT EFFORT.", "PREPAREM-SE. AGORA O BARALHO TERÁ DE JUSTIFICAR TODO ESSE ESFORÇO.");
			PvpLocalization.L("KayceePvP.Duel.PressEnterOrSpaceToClose", "PRESS ENTER OR SPACE TO CLOSE THE GAME", "PRESSIONE ENTER OU ESPAÇO PARA FECHAR O JOGO");
		}

		public static void BeginAfterFirstBoss()
		{
			SaveManager.SaveToFile(true);
			SceneLoader.Load("Part1_Sanctum");
		}

		public static void StartFixedDeckDuelDebug()
		{
			if (!PvpRunState.IsPvpRun || RunState.Run == null)
			{
				Plugin.Log.LogWarning((object)"Duel debug (fixed deck): no active PvP run - connect through the lobby and start a run first.");
				return;
			}
			if (PvpRunState.IsDuelActive || PvpRunState.BossDefeated)
			{
				Plugin.Log.LogWarning((object)"Duel debug (fixed deck): already past this point in the flow this run.");
				return;
			}
			ITransport transport = LobbySession.Instance.Transport;
			if (transport == null || !transport.IsConnected)
			{
				string text = ((transport == null) ? "Transport==null" : ("IsConnected=false LastError='" + transport.LastError + "'"));
				Plugin.Log.LogWarning((object)("Duel debug (fixed deck): no live lobby connection (" + text + ") - this tool is for exercising the real LanTransport, not solo mode."));
				return;
			}
			string text2 = ResolveF6DeckConfigPath();
			string parseError;
			List<F6DeckLineEntry> list = ParseF6DeckFileLines(ReadOrCreateF6DeckFileLines(text2), out parseError);
			if (list == null)
			{
				FailF6DeckDebug("Duel debug (F6 deck): erro de formato em '" + text2 + "': " + parseError + " NENHUMA carta foi trocada (fail-closed).");
				return;
			}
			if (list.Count == 0)
			{
				FailF6DeckDebug("Duel debug (F6 deck): '" + text2 + "' nao tem nenhuma linha de carta valida (so comentarios/linhas vazias?). NENHUMA carta foi trocada (fail-closed).");
				return;
			}
			if (!TryResolveF6Deck(list, out var deck, out var resolutionError, out var requestedSummary, out var resolvedSummary))
			{
				FailF6DeckDebug("Duel debug (F6 deck): " + resolutionError + " Deck solicitado: [" + requestedSummary + "]. NENHUMA carta foi trocada (fail-closed).");
				return;
			}
			PvpRunState.BossDefeated = true;
			((CardCollectionInfo)RunState.Run.playerDeck).Cards.Clear();
			foreach (CardInfo item in deck)
			{
				((CardCollectionInfo)RunState.Run.playerDeck).AddCard(item);
			}
			Plugin.Log.LogInfo((object)$"Duel debug (F6 deck): arquivo='{text2}' solicitado=[{requestedSummary}] resolvido=[{resolvedSummary}] total={deck.Count} cartas - handing off to the shared peer-deck wait (sending is now done inside it), then the real ready screen + DuelStart.Begin() (map/boss/Death Card skipped).");
			((MonoBehaviour)LobbySession.Instance).StartCoroutine(WaitForPeerDeckThenDuel());
		}

		internal static string ResolveF6DeckConfigPath()
		{
			return Path.Combine(Paths.ConfigPath, "KayceePvP.F6Deck.txt");
		}

		internal static List<string> ReadOrCreateF6DeckFileLines(string path)
		{
			if (File.Exists(path))
			{
				return new List<string>(File.ReadAllLines(path));
			}
			Plugin.Log.LogWarning((object)("Duel debug (F6 deck): '" + path + "' nao existe - criando com o default COBAIAS (PackRat x4, MealWorm x3, Skink x3)."));
			try
			{
				string directoryName = Path.GetDirectoryName(path);
				if (!string.IsNullOrEmpty(directoryName))
				{
					Directory.CreateDirectory(directoryName);
				}
				File.WriteAllLines(path, DefaultF6DeckLines);
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("Duel debug (F6 deck): falha ao criar '" + path + "' (" + ex.Message + ") - usando o default apenas em memoria nesta tentativa."));
			}
			return new List<string>(DefaultF6DeckLines);
		}

		internal static List<F6DeckLineEntry> ParseF6DeckFileLines(IEnumerable<string> rawLines, out string parseError)
		{
			parseError = null;
			List<F6DeckLineEntry> list = new List<F6DeckLineEntry>();
			Dictionary<string, int> dictionary = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase);
			int num = 0;
			foreach (string rawLine in rawLines)
			{
				num++;
				string text = rawLine ?? string.Empty;
				int num2 = text.IndexOf('#');
				if (num2 >= 0)
				{
					text = text.Substring(0, num2);
				}
				text = text.Trim();
				if (text.Length == 0)
				{
					continue;
				}
				Match match = F6DeckQuantityPattern.Match(text);
				string text2;
				int result;
				if (match.Success)
				{
					text2 = match.Groups["name"].Value.Trim();
					string value = match.Groups["qty"].Value;
					if (!int.TryParse(value, out result))
					{
						parseError = $"linha {num} ('{rawLine.Trim()}'): quantidade '{value}' nao e um numero valido.";
						return null;
					}
				}
				else
				{
					text2 = text;
					result = 1;
				}
				if (text2.Length == 0)
				{
					parseError = $"linha {num} ('{rawLine.Trim()}'): nome de carta vazio.";
					return null;
				}
				if (result <= 0)
				{
					parseError = $"linha {num} ('{rawLine.Trim()}'): quantidade deve ser positiva, lida={result} para '{text2}'.";
					return null;
				}
				if (dictionary.TryGetValue(text2, out var value2))
				{
					F6DeckLineEntry f6DeckLineEntry = list[value2];
					list[value2] = new F6DeckLineEntry(f6DeckLineEntry.RequestedName, f6DeckLineEntry.Count + result);
				}
				else
				{
					dictionary[text2] = list.Count;
					list.Add(new F6DeckLineEntry(text2, result));
				}
			}
			return list;
		}

		internal static bool ValidateF6DeckSize(int totalRequested, out string sizeError)
		{
			sizeError = null;
			if (totalRequested < 4)
			{
				sizeError = $"deck com {totalRequested} carta(s) no total - minimo exigido e {4}.";
				return false;
			}
			if (totalRequested > 40)
			{
				sizeError = $"deck com {totalRequested} carta(s) no total - maximo permitido e {40} (limite defensivo contra erro de digitacao).";
				return false;
			}
			return true;
		}

		internal static bool TryResolveF6Deck(List<F6DeckLineEntry> entries, out List<CardInfo> deck, out string resolutionError, out string requestedSummary, out string resolvedSummary)
		{
			deck = null;
			resolvedSummary = null;
			requestedSummary = string.Join(", ", entries.Select((F6DeckLineEntry e) => $"{e.RequestedName} x{e.Count}"));
			if (!ValidateF6DeckSize(entries.Sum((F6DeckLineEntry e) => e.Count), out resolutionError))
			{
				return false;
			}
			List<CardInfo> source = CardManager.AllCardsCopy.Where((CardInfo c) => (Object)(object)c != (Object)null && !string.IsNullOrEmpty(((Object)c).name)).ToList();
			List<CardInfo> list = new List<CardInfo>();
			List<string> list2 = new List<string>();
			foreach (F6DeckLineEntry entry in entries)
			{
				CardInfo val = ((IEnumerable<CardInfo>)source).FirstOrDefault((Func<CardInfo, bool>)((CardInfo c) => string.Equals(((Object)c).name, entry.RequestedName, StringComparison.OrdinalIgnoreCase)));
				if ((Object)(object)val == (Object)null)
				{
					resolutionError = "nome de carta invalido: '" + entry.RequestedName + "' (nao encontrado via CardLoader.GetCardByName/pool de cartas - confira a grafia contra CardInfo.name).";
					return false;
				}
				for (int num = 0; num < entry.Count; num++)
				{
					list.Add(CardLoader.GetCardByName(((Object)val).name));
				}
				list2.Add($"{((Object)val).name} x{entry.Count}");
			}
			resolvedSummary = string.Join(", ", list2);
			deck = list;
			return true;
		}

		private static void FailF6DeckDebug(string message)
		{
			Plugin.Log.LogError((object)message);
			if ((Object)(object)Singleton<TextDisplayer>.Instance != (Object)null)
			{
				Singleton<TextDisplayer>.Instance.ShowMessage(PvpLocalization.English("KayceePvP.Duel.F6InvalidDeckOnScreen"), (Emotion)0, (LetterAnimation)0, (Speaker)0, (string[])null);
			}
		}

		private static float ResolvePeerDeckWaitTimeoutSeconds()
		{
			string environmentVariable = Environment.GetEnvironmentVariable("KAYCEEPVP_PEER_WAIT_TIMEOUT_SECONDS");
			if (!string.IsNullOrEmpty(environmentVariable) && float.TryParse(environmentVariable, out var result) && result > 0f)
			{
				return result;
			}
			return 21600f;
		}

		internal static PeerWaitOutcome EvaluatePeerWaitState(bool conditionMet, bool cancelRequested, bool hasRealTransport, bool transportConnected, float elapsedSeconds, float timeoutSeconds)
		{
			if (conditionMet)
			{
				return PeerWaitOutcome.Success;
			}
			if (cancelRequested)
			{
				return PeerWaitOutcome.Cancelled;
			}
			if (hasRealTransport && !transportConnected)
			{
				return PeerWaitOutcome.Disconnected;
			}
			if (elapsedSeconds > timeoutSeconds)
			{
				return PeerWaitOutcome.TimedOut;
			}
			return PeerWaitOutcome.Waiting;
		}

		private static string DescribeWaitFailureReason(PeerWaitOutcome outcome, LobbySession session, string timeoutMessage)
		{
			return outcome switch
			{
				PeerWaitOutcome.Disconnected => PvpLocalization.Format("KayceePvP.Duel.ErrorConnectionLostDuringWait", session.Transport?.LastError), 
				PeerWaitOutcome.Cancelled => PvpLocalization.Get("KayceePvP.Duel.ErrorWaitCancelled"), 
				_ => timeoutMessage, 
			};
		}

		internal static IEnumerator WaitForPeerDeckThenDuel(string waitingTitle = null)
		{
			LobbySession session = LobbySession.Instance;
			session.SendLocalDeck(((CardCollectionInfo)RunState.Run.playerDeck).Cards);
			NoBattleWaitingScreen.Show(((CardCollectionInfo)RunState.Run.playerDeck).Cards, waitingTitle ?? PvpLocalization.Get("KayceePvP.Duel.WaitingForOpponentTitle"));
			bool hasRealTransport = session.Transport != null;
			float startTime = Time.realtimeSinc