Decompiled source of KayceePvP v0.1.0
plugins\KayceePvP\KayceePvP.dll
Decompiled 3 hours ago
The result has been truncated due to the large size, download it to view full contents!
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