Decompiled source of TCG AP Client v0.4.2
plugins/ApClient.dll
Decompiled 2 weeks 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.Generic; using System.Collections.Specialized; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text.RegularExpressions; using ApClient; using ApClient.data; using ApClient.mapping; using ApClient.patches; using ApClientl; using Archipelago.MultiClient.Net; using Archipelago.MultiClient.Net.BounceFeatures.DeathLink; using Archipelago.MultiClient.Net.Converters; using Archipelago.MultiClient.Net.Enums; using Archipelago.MultiClient.Net.Helpers; using Archipelago.MultiClient.Net.MessageLog.Messages; using Archipelago.MultiClient.Net.Models; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using I2.Loc; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using TMPro; using UnityEngine; using UnityEngine.SceneManagement; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: AssemblyCompany("ApClient")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("0.4.0.0")] [assembly: AssemblyInformationalVersion("0.4.0+05ff11feb22ac1180d6a7d8281a465f4a8a3c676")] [assembly: AssemblyProduct("Ap Client For TCG Sim")] [assembly: AssemblyTitle("ApClient")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.4.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.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; } } } public class APConsole : MonoBehaviour { [Serializable] public class LogEntry { public double Timestamp; public float Lifetime = 50f; public float TotalLifetime = 50f; public float RiseSpeed = 5f; public TextMeshProUGUI RenderedText; public string Message; public LogEntry(string message, double timestamp) { Message = message; Timestamp = timestamp; } } private static readonly Dictionary<string, string> keywordColors = new Dictionary<string, string> { { "license", "#FF5151" }, { "card", "#3089FF" }, { "money", "#FFBF62" } }; private static readonly Regex keywordRegex = new Regex(string.Join("|", keywordColors.Keys.Select(Regex.Escape)), RegexOptions.IgnoreCase); private bool showConsole = true; private Transform messageParent; private readonly List<LogEntry> visibleEntries = new List<LogEntry>(); private readonly Queue<LogEntry> cachedEntries = new Queue<LogEntry>(); private Queue<TextMeshProUGUI> messagePool = new Queue<TextMeshProUGUI>(); private float lastUpdate; private const float MessageDelay = 0.05f; private const float MessageTime = 6f; private static float animationDuration = 6f; private static float MessageHeight = 10f; private static float ConsoleHeight = 280f; private static int MaxMessages = (int)((double)ConsoleHeight / ((double)MessageHeight * 1.5)); public static APConsole Instance { get; private set; } public static void Create() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown if (!((Object)(object)Instance != (Object)null)) { GameObject val = new GameObject("ArchipelagoConsoleUI"); Object.DontDestroyOnLoad((Object)(object)val); APConsole aPConsole = val.AddComponent<APConsole>(); aPConsole.CreateConsoleCanvas(); Instance = aPConsole; } } private void Update() { //IL_0052: Unknown result type (might be due to invalid IL or missing references) if (Time.time - lastUpdate >= 6f / (ConsoleHeight / (MessageHeight * 2f))) { UpdateVisibleMessages(); lastUpdate = Time.time; } UpdateUI(); if (Input.GetKeyDown(Settings.Instance.ConsoleHotkey.Value)) { if (showConsole) { Log("Disabling AP Console"); showConsole = false; } else { showConsole = true; Log("AP Console Enabled"); } } } private void UpdateUI() { foreach (LogEntry visibleEntry in visibleEntries) { if (Object.op_Implicit((Object)(object)visibleEntry.RenderedText)) { Animate(visibleEntry.RenderedText, visibleEntry.Timestamp); } ((TMP_Text)visibleEntry.RenderedText).text = Colorize(visibleEntry.Message); } } private void Animate(TextMeshProUGUI text, double timestamp) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) float num = (float)(UnixTimeConverter.ToUnixTimeStamp(DateTime.Now) - timestamp); float num2 = Mathf.Clamp01(num / animationDuration); float y = num2 * ConsoleHeight; Vector2 anchoredPosition = ((TMP_Text)text).rectTransform.anchoredPosition; anchoredPosition.y = y; ((TMP_Text)text).rectTransform.anchoredPosition = anchoredPosition; ((TMP_Text)text).alpha = Mathf.Lerp(1f, 0f, Mathf.Clamp01(num - animationDuration + 2f)); } private string Colorize(string input) { return keywordRegex.Replace(input, delegate(Match match) { string key = match.Value.ToLower(); string value; return keywordColors.TryGetValue(key, out value) ? ("<color=" + value + ">" + match.Value + "</color>") : match.Value; }); } private void UpdateVisibleMessages() { //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Expected O, but got Unknown //IL_00e3: 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) double now = UnixTimeConverter.ToUnixTimeStamp(DateTime.Now); visibleEntries.RemoveAll(delegate(LogEntry e) { if (now - e.Timestamp > 6.0) { RecycleMessage(e); return true; } return false; }); if (visibleEntries.Count < MaxMessages && cachedEntries.Count != 0) { LogEntry logEntry = cachedEntries.Dequeue(); logEntry.Timestamp = now; GameObject val = new GameObject("ConsoleMessage"); val.transform.SetParent(messageParent, false); TextMeshProUGUI pooledMessage = GetPooledMessage(); ((TMP_Text)pooledMessage).enableWordWrapping = false; ((TMP_Text)pooledMessage).text = logEntry.Message; ((TMP_Text)pooledMessage).fontSize = 20f; ((TMP_Text)pooledMessage).alignment = (TextAlignmentOptions)513; ((Graphic)pooledMessage).color = new Color(1f, 1f, 1f, 1f); ((TMP_Text)pooledMessage).rectTransform.anchoredPosition = new Vector2(MessageHeight, 0f); logEntry.RenderedText = pooledMessage; visibleEntries.Add(logEntry); } } public void Log(string text) { if (showConsole) { LogEntry item = new LogEntry(text, UnixTimeConverter.ToUnixTimeStamp(DateTime.Now)); cachedEntries.Enqueue(item); } } private void CreateConsoleCanvas() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Expected O, but got Unknown //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("ArchipelagoConsoleCanvas"); val.transform.SetParent(((Component)this).transform); Canvas val2 = val.AddComponent<Canvas>(); val2.renderMode = (RenderMode)0; val2.sortingOrder = 1000; CanvasScaler val3 = val.AddComponent<CanvasScaler>(); val3.uiScaleMode = (ScaleMode)1; val3.referenceResolution = new Vector2(1920f, 1080f); val.AddComponent<GraphicRaycaster>(); GameObject val4 = new GameObject("Messages"); RectTransform val5 = val4.AddComponent<RectTransform>(); ((Transform)val5).SetParent(val.transform, false); val5.anchorMin = new Vector2(0f, 0f); val5.anchorMax = new Vector2(0f, 0f); val5.pivot = new Vector2(0f, 0f); val5.anchoredPosition = new Vector2(60f, 35f); messageParent = val4.transform; } private TextMeshProUGUI GetPooledMessage() { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Expected O, but got Unknown if (messagePool.Count > 0) { TextMeshProUGUI val = messagePool.Dequeue(); ((Component)val).gameObject.SetActive(true); return val; } GameObject val2 = new GameObject("ConsoleMessage"); val2.transform.SetParent(messageParent, false); TextMeshProUGUI val3 = val2.AddComponent<TextMeshProUGUI>(); ((TMP_Text)val3).enableWordWrapping = false; return val3; } private void RecycleMessage(LogEntry msg) { ((Component)msg.RenderedText).gameObject.SetActive(false); messagePool.Enqueue(msg.RenderedText); } } namespace ApClientl { public class APGui : MonoBehaviour { public static bool showGUI = true; public static string ipporttext = Settings.Instance.LastUsedIP.Value; public static string password = Settings.Instance.LastUsedPassword.Value; public static string slot = Settings.Instance.LastUsedSlot.Value; public static string state = "Not Connected"; private void OnGUI() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Expected O, but got Unknown //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) if (showGUI) { GUI.Box(new Rect(10f, 10f, 200f, 300f), "AP Client"); GUIStyle val = new GUIStyle(); val.fontSize = 12; val.normal.textColor = Color.white; GUI.Label(new Rect(20f, 40f, 300f, 30f), "Address:port", val); ipporttext = GUI.TextField(new Rect(20f, 60f, 180f, 25f), ipporttext, 25); GUI.Label(new Rect(20f, 90f, 300f, 30f), "Password", val); password = GUI.TextField(new Rect(20f, 110f, 180f, 25f), password, 25); GUI.Label(new Rect(20f, 140f, 300f, 30f), "Slot", val); slot = GUI.TextField(new Rect(20f, 160f, 180f, 25f), slot, 25); if (GUI.Button(new Rect(20f, 210f, 180f, 30f), "Connect")) { Debug.Log((object)"Button Pressed!"); Plugin.m_SessionHandler.connect(ipporttext, password, slot); } GUI.Label(new Rect(20f, 240f, 300f, 30f), state, val); } } private void Update() { //IL_000b: Unknown result type (might be due to invalid IL or missing references) if (Input.GetKeyDown(Settings.Instance.MyHotkey.Value)) { showGUI = !showGUI; } } } } namespace ApClient { public class APClientSaveManager { [Serializable] public class SaveDataWrapper { public CGameData gameData; public int ProcessedIndex; public List<int> newCards = new List<int>(); public float MoneyMultiplier; public int Luck; public int TetramonCommonChecksFound; public int DestinyCommonChecksFound; public int TetramonRareChecksFound; public int DestinyRareChecksFound; public int TetramonEpicChecksFound; public int DestinyEpicChecksFound; public int TetramonLegendaryChecksFound; public int DestinyLegendaryChecksFound; public int TetramonCommonChecksSold; public int DestinyCommonChecksSold; public int TetramonRareChecksSold; public int DestinyRareChecksSold; public int TetramonEpicChecksSold; public int DestinyEpicChecksSold; public int TetramonLegendaryChecksSold; public int DestinyLegendaryChecksSold; public int GhostCardsSold; public int EventGamesPlayed; public int LicensesReceived; public int StoredXP; } private APSaveData aPSaveData; private int cachedTetramonCheckCount = -1; private int cachedDestinyCheckCount = -1; public int cachedCommonChecks = -1; public int cachedRareChecks = -1; public int cachedEpicChecks = -1; public int cachedLegendaryChecks = -1; public int customersPlayedGames = 0; public APClientSaveManager() { Clear(); } public void Clear() { aPSaveData = new APSaveData(); aPSaveData.ProcessedIndex = 0; aPSaveData.MoneyMultiplier = 1f; aPSaveData.StoredXP = 0; cachedTetramonCheckCount = -1; cachedDestinyCheckCount = -1; cachedCommonChecks = -1; cachedRareChecks = -1; cachedEpicChecks = -1; cachedLegendaryChecks = -1; customersPlayedGames = 0; } public void setConnectionData(string seed, string slot) { aPSaveData.seed = seed; aPSaveData.slotname = slot; } public void setProcessedIndex(int index) { aPSaveData.ProcessedIndex = index; } public void IncreaseProcessedIndex() { aPSaveData.ProcessedIndex++; } public int GetProcessedIndex() { return aPSaveData.ProcessedIndex; } public void IncreaselicensesReceived() { aPSaveData.LicensesReceived++; } public int GetlicensesReceived() { return aPSaveData.LicensesReceived; } public void IncreaseMoneyMult() { aPSaveData.MoneyMultiplier = (aPSaveData.MoneyMultiplier += 0.1f); } public float GetMoneyMult() { if (aPSaveData.MoneyMultiplier < 1f) { aPSaveData.MoneyMultiplier = 1f; } return aPSaveData.MoneyMultiplier; } public int GetLuck() { return aPSaveData.Luck; } public void IncreaseLuck() { aPSaveData.Luck++; } public int GetEventGamesPlayed() { return aPSaveData.EventGamesPlayed; } public void IncreaseCustomersPlayed() { customersPlayedGames++; if (customersPlayedGames % 2 == 0) { aPSaveData.EventGamesPlayed++; } } public void DecreaseLuck() { if (aPSaveData.Luck > 0) { aPSaveData.Luck--; } } public void IncreaseCardChecks(ECollectionPackType packType) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0004: 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_002b: Expected I4, but got Unknown switch ((int)packType) { case 0: aPSaveData.TetramonCommonChecksFound++; break; case 1: aPSaveData.TetramonRareChecksFound++; break; case 2: aPSaveData.TetramonEpicChecksFound++; break; case 3: aPSaveData.TetramonLegendaryChecksFound++; break; case 4: aPSaveData.DestinyCommonChecksFound++; break; case 5: aPSaveData.DestinyRareChecksFound++; break; case 6: aPSaveData.DestinyEpicChecksFound++; break; case 7: aPSaveData.DestinyLegendaryChecksFound++; break; } } public void IncreaseCardSold(ECardExpansionType expansionType, ERarity rarity) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Invalid comparison between Unknown and I4 //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0095: 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_00ae: Expected I4, but got Unknown //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected I4, but got Unknown if ((int)expansionType == 0) { switch ((int)rarity) { case 0: aPSaveData.TetramonCommonChecksSold++; break; case 1: aPSaveData.TetramonRareChecksSold++; break; case 2: aPSaveData.TetramonEpicChecksSold++; break; case 3: aPSaveData.TetramonLegendaryChecksSold++; break; } } else { switch ((int)rarity) { case 0: aPSaveData.DestinyCommonChecksSold++; break; case 1: aPSaveData.DestinyRareChecksSold++; break; case 2: aPSaveData.DestinyEpicChecksSold++; break; case 3: aPSaveData.DestinyLegendaryChecksSold++; break; } } } public int GetCardsSold(ECardExpansionType expansionType, ERarity rarity) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Invalid comparison between Unknown and I4 //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Expected I4, but got Unknown //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected I4, but got Unknown if ((int)expansionType == 0) { switch ((int)rarity) { case 0: return aPSaveData.TetramonCommonChecksSold; case 1: return aPSaveData.TetramonRareChecksSold; case 2: return aPSaveData.TetramonEpicChecksSold; case 3: return aPSaveData.TetramonLegendaryChecksSold; } } else { switch ((int)rarity) { case 0: return aPSaveData.DestinyCommonChecksSold; case 1: return aPSaveData.DestinyRareChecksSold; case 2: return aPSaveData.DestinyEpicChecksSold; case 3: return aPSaveData.DestinyLegendaryChecksSold; } } return -1; } public void IncreaseGhostChecks() { aPSaveData.GhostCardsSold++; } public int getTotalExpansionChecks(ECardExpansionType cardExpansionType) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Invalid comparison between Unknown and I4 //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Invalid comparison between Unknown and I4 //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Invalid comparison between Unknown and I4 //IL_02a2: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Invalid comparison between Unknown and I4 //IL_02b8: Unknown result type (might be due to invalid IL or missing references) //IL_02ba: Invalid comparison between Unknown and I4 //IL_02cb: Unknown result type (might be due to invalid IL or missing references) //IL_02cd: Invalid comparison between Unknown and I4 //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Invalid comparison between Unknown and I4 //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Invalid comparison between I4 and Unknown //IL_01d4: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Invalid comparison between I4 and Unknown //IL_0237: Unknown result type (might be due to invalid IL or missing references) //IL_0239: Invalid comparison between I4 and Unknown if ((int)cardExpansionType == 2) { if (Plugin.m_SessionHandler.GetSlotData().Goal == 2) { return Plugin.m_SessionHandler.GetSlotData().GhostGoalAmount; } return 0; } if ((int)cardExpansionType != 0 && (int)cardExpansionType != 1) { return 0; } if ((int)cardExpansionType == 0 && cachedTetramonCheckCount != -1) { Plugin.Log("-1"); return cachedTetramonCheckCount; } if ((int)cardExpansionType == 1 && cachedDestinyCheckCount != -1) { Plugin.Log("-1"); return cachedDestinyCheckCount; } cachedCommonChecks = 0; cachedRareChecks = 0; cachedEpicChecks = 0; cachedLegendaryChecks = 0; int num = 0; for (int i = 0; i < InventoryBase.GetShownMonsterList(cardExpansionType).Count; i++) { ERarity rarity = InventoryBase.GetMonsterData(InventoryBase.GetShownMonsterList(cardExpansionType)[i]).Rarity; int num2 = (((int)cardExpansionType == 1) ? 4 : 0); if ((int)rarity == 0) { Plugin.Log("common"); cachedCommonChecks += 12; if (Plugin.m_SessionHandler.GetSlotData().CardSanity > num2) { num += (Plugin.m_SessionHandler.GetSlotData().BorderInSanity + 1) * ((!Plugin.m_SessionHandler.GetSlotData().FoilInSanity) ? 1 : 2); } } if (1 == (int)rarity) { cachedRareChecks += 12; if (Plugin.m_SessionHandler.GetSlotData().CardSanity > num2 + 1) { num += (Plugin.m_SessionHandler.GetSlotData().BorderInSanity + 1) * ((!Plugin.m_SessionHandler.GetSlotData().FoilInSanity) ? 1 : 2); } } if (2 == (int)rarity) { cachedEpicChecks += 12; if (Plugin.m_SessionHandler.GetSlotData().CardSanity > num2 + 2) { num += (Plugin.m_SessionHandler.GetSlotData().BorderInSanity + 1) * ((!Plugin.m_SessionHandler.GetSlotData().FoilInSanity) ? 1 : 2); } } if (3 == (int)rarity) { cachedLegendaryChecks += 12; if (Plugin.m_SessionHandler.GetSlotData().CardSanity > num2 + 3) { num += (Plugin.m_SessionHandler.GetSlotData().BorderInSanity + 1) * ((!Plugin.m_SessionHandler.GetSlotData().FoilInSanity) ? 1 : 2); } } } if ((int)cardExpansionType == 0) { cachedTetramonCheckCount = num; } if ((int)cardExpansionType == 1) { cachedDestinyCheckCount = num; } return num; } public int GetTotalCountedCards(ECollectionPackType packType) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected I4, but got Unknown getTotalExpansionChecks((ECardExpansionType)0); return (int)packType switch { 0 => cachedCommonChecks, 1 => cachedRareChecks, 2 => cachedEpicChecks, 3 => cachedLegendaryChecks, 4 => cachedCommonChecks, 5 => cachedRareChecks, 6 => cachedEpicChecks, 7 => cachedLegendaryChecks, _ => -1, }; } public int GetExpansionChecks(ECardExpansionType type) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0004: 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_0017: Expected I4, but got Unknown return (int)type switch { 0 => GetTetramonChecks(), 1 => GetDestinyChecks(), 2 => GetGhostChecks(), _ => 0, }; } public int GetTetramonChecks() { return aPSaveData.TetramonCommonChecksFound + aPSaveData.TetramonRareChecksFound + aPSaveData.TetramonEpicChecksFound + aPSaveData.TetramonLegendaryChecksFound; } public int GetDestinyChecks() { return aPSaveData.DestinyCommonChecksFound + aPSaveData.DestinyRareChecksFound + aPSaveData.DestinyEpicChecksFound + aPSaveData.DestinyLegendaryChecksFound; } public int GetCardChecks(ECollectionPackType packType) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0004: 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_002b: Expected I4, but got Unknown return (int)packType switch { 0 => aPSaveData.TetramonCommonChecksFound, 1 => aPSaveData.TetramonRareChecksFound, 2 => aPSaveData.TetramonEpicChecksFound, 3 => aPSaveData.TetramonLegendaryChecksFound, 4 => aPSaveData.DestinyCommonChecksFound, 5 => aPSaveData.DestinyRareChecksFound, 6 => aPSaveData.DestinyEpicChecksFound, 7 => aPSaveData.DestinyLegendaryChecksFound, _ => -1, }; } public int GetSentChecks(ECollectionPackType packType) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Expected I4, but got Unknown int totalCountedCards = Plugin.m_SaveManager.GetTotalCountedCards(packType); float num = (float)totalCountedCards * ((float)Plugin.m_SessionHandler.GetSlotData().CardCollectPercentage / 100f); float num2 = num / (float)Plugin.m_SessionHandler.GetSlotData().ChecksPerPack; return (int)packType switch { 0 => (int)((float)aPSaveData.TetramonCommonChecksFound / num2), 1 => (int)((float)aPSaveData.TetramonRareChecksFound / num2), 2 => (int)((float)aPSaveData.TetramonEpicChecksFound / num2), 3 => (int)((float)aPSaveData.TetramonLegendaryChecksFound / num2), 4 => (int)((float)aPSaveData.DestinyCommonChecksFound / num2), 5 => (int)((float)aPSaveData.DestinyRareChecksFound / num2), 6 => (int)((float)aPSaveData.DestinyEpicChecksFound / num2), 7 => (int)((float)aPSaveData.DestinyLegendaryChecksFound / num2), _ => -1, }; } public int GetGhostChecks() { return aPSaveData.GhostCardsSold; } public int GetStoredXP(int maxToGrab) { if (aPSaveData.StoredXP > maxToGrab) { aPSaveData.StoredXP -= maxToGrab; return maxToGrab; } return aPSaveData.StoredXP; } public int TotalStoredXP() { return aPSaveData.StoredXP; } public void IncreaseStoredXP(int xp) { Plugin.Log($"xp: {xp}"); aPSaveData.StoredXP += xp; } private string GetBaseDirectory() { return Path.GetDirectoryName(GetType().Assembly.Location); } private string getGdSavePath() { return GetBaseDirectory() + "/Saves/ApClient_" + aPSaveData.slotname + "_" + aPSaveData.seed + ".gd"; } private string getJsonSavePath() { return GetBaseDirectory() + "/Saves/ApClient_" + aPSaveData.slotname + "_" + aPSaveData.seed + ".json"; } public bool doesSaveExist() { return File.Exists(getJsonSavePath()) || File.Exists(getGdSavePath()); } public void Save(int saveSlotIndex) { Directory.CreateDirectory(GetBaseDirectory() + "/Saves/"); CSaveLoad.m_SavedGame = CGameData.instance; SaveDataWrapper saveDataWrapper = new SaveDataWrapper { gameData = CGameData.instance, ProcessedIndex = aPSaveData.ProcessedIndex, MoneyMultiplier = aPSaveData.MoneyMultiplier, Luck = aPSaveData.Luck, TetramonCommonChecksFound = aPSaveData.TetramonCommonChecksFound, DestinyCommonChecksFound = aPSaveData.DestinyCommonChecksFound, TetramonRareChecksFound = aPSaveData.TetramonRareChecksFound, DestinyRareChecksFound = aPSaveData.DestinyRareChecksFound, TetramonEpicChecksFound = aPSaveData.TetramonEpicChecksFound, DestinyEpicChecksFound = aPSaveData.DestinyEpicChecksFound, TetramonLegendaryChecksFound = aPSaveData.TetramonLegendaryChecksFound, DestinyLegendaryChecksFound = aPSaveData.DestinyLegendaryChecksFound, TetramonCommonChecksSold = aPSaveData.TetramonCommonChecksSold, DestinyCommonChecksSold = aPSaveData.DestinyCommonChecksSold, TetramonRareChecksSold = aPSaveData.TetramonRareChecksSold, DestinyRareChecksSold = aPSaveData.DestinyRareChecksSold, TetramonEpicChecksSold = aPSaveData.TetramonEpicChecksSold, DestinyEpicChecksSold = aPSaveData.DestinyEpicChecksSold, TetramonLegendaryChecksSold = aPSaveData.TetramonLegendaryChecksSold, DestinyLegendaryChecksSold = aPSaveData.DestinyLegendaryChecksSold, GhostCardsSold = aPSaveData.GhostCardsSold, EventGamesPlayed = aPSaveData.EventGamesPlayed, LicensesReceived = aPSaveData.LicensesReceived, StoredXP = aPSaveData.LicensesReceived }; try { string contents = JsonUtility.ToJson((object)saveDataWrapper, true); File.WriteAllText(getJsonSavePath(), contents); } catch (Exception ex) { Plugin.Log("Error saving JSON: " + ex); } } public bool Load() { string jsonSavePath = getJsonSavePath(); if (!File.Exists(jsonSavePath)) { return false; } try { string text = File.ReadAllText(jsonSavePath); SaveDataWrapper saveDataWrapper = JsonConvert.DeserializeObject<SaveDataWrapper>(text); if (saveDataWrapper == null) { return false; } CSaveLoad.m_SavedGame = saveDataWrapper.gameData; aPSaveData.ProcessedIndex = saveDataWrapper.ProcessedIndex; aPSaveData.MoneyMultiplier = saveDataWrapper.MoneyMultiplier; aPSaveData.Luck = saveDataWrapper.Luck; aPSaveData.TetramonCommonChecksFound = saveDataWrapper.TetramonCommonChecksFound; aPSaveData.DestinyCommonChecksFound = saveDataWrapper.DestinyCommonChecksFound; aPSaveData.TetramonRareChecksFound = saveDataWrapper.TetramonRareChecksFound; aPSaveData.DestinyRareChecksFound = saveDataWrapper.DestinyRareChecksFound; aPSaveData.TetramonEpicChecksFound = saveDataWrapper.TetramonEpicChecksFound; aPSaveData.DestinyEpicChecksFound = saveDataWrapper.DestinyEpicChecksFound; aPSaveData.TetramonLegendaryChecksFound = saveDataWrapper.TetramonLegendaryChecksFound; aPSaveData.DestinyLegendaryChecksFound = saveDataWrapper.DestinyLegendaryChecksFound; aPSaveData.TetramonCommonChecksSold = saveDataWrapper.TetramonCommonChecksSold; aPSaveData.DestinyCommonChecksSold = saveDataWrapper.DestinyCommonChecksSold; aPSaveData.TetramonRareChecksSold = saveDataWrapper.TetramonRareChecksSold; aPSaveData.DestinyRareChecksSold = saveDataWrapper.DestinyRareChecksSold; aPSaveData.TetramonEpicChecksSold = saveDataWrapper.TetramonEpicChecksSold; aPSaveData.DestinyEpicChecksSold = saveDataWrapper.DestinyEpicChecksSold; aPSaveData.TetramonLegendaryChecksSold = saveDataWrapper.TetramonLegendaryChecksSold; aPSaveData.DestinyLegendaryChecksSold = saveDataWrapper.DestinyLegendaryChecksSold; aPSaveData.GhostCardsSold = saveDataWrapper.GhostCardsSold; aPSaveData.EventGamesPlayed = saveDataWrapper.EventGamesPlayed; aPSaveData.LicensesReceived = saveDataWrapper.LicensesReceived; aPSaveData.StoredXP = saveDataWrapper.StoredXP; return true; } catch { Plugin.Log("Failed to retrieve save data"); } return false; } } public class CardHelper { private ERarity[] CardRarities = (ERarity[])(object)new ERarity[122]; private bool initialized = false; public CardHelper() { initialized = false; } public void Initialize() { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected I4, but got Unknown //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) CardRarities[0] = (ERarity)(-1); for (int i = 1; i < CardRarities.Length; i++) { try { CardRarities[i] = (ERarity)(int)InventoryBase.GetMonsterData((EMonsterType)i).Rarity; } catch (Exception) { Plugin.Log("Failed to get monster data"); } } initialized = true; ERarity[] cardRarities = CardRarities; foreach (ERarity val in cardRarities) { Console.WriteLine(val); } Plugin.Log("initialized card helper"); } public CardData RandomNewCard(ECardExpansionType expansion, HashSet<ERarity> allowedRarities, int borderlimit, bool foils) { //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Invalid comparison between Unknown and I4 //IL_01be: 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_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_01cb: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_01d2: Unknown result type (might be due to invalid IL or missing references) //IL_01d7: Unknown result type (might be due to invalid IL or missing references) //IL_01de: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Expected O, but got Unknown //IL_01f6: Unknown result type (might be due to invalid IL or missing references) //IL_0205: Unknown result type (might be due to invalid IL or missing references) //IL_0214: Unknown result type (might be due to invalid IL or missing references) Plugin.Log($"RandomNewCard {((object)(ECardExpansionType)(ref expansion)).ToString()} {allowedRarities.Count} {borderlimit} {foils}"); foreach (ERarity allowedRarity in allowedRarities) { Console.WriteLine($"allowed: {allowedRarity}"); } try { if (!initialized) { Initialize(); } List<bool> isCardCollectedList = CPlayerData.GetIsCardCollectedList(expansion, false); int num = (foils ? 12 : 6); int num2 = 121; List<int> list = new List<int>(); for (int i = 1; i < num2; i++) { if (!allowedRarities.Contains(CardRarities[i])) { continue; } int num3 = i * 12; for (int j = 0; j < num; j++) { if (j % 6 <= borderlimit) { int num4 = num3 + j; if (!isCardCollectedList[num4]) { list.Add(num4); } } } } if (list.Count == 0) { Plugin.Log("No new cards"); return CardRoller((ECollectionPackType)Random.Range(0, 4)); } int num5 = list[Random.Range(0, list.Count)]; int num6 = num5 % 12; int num7 = (num5 - num6) / 12; CardData val = new CardData { isFoil = (num6 > 5), isDestiny = ((int)expansion == 1), borderType = (ECardBorderType)(num6 % 6), monsterType = (EMonsterType)num7, expansionType = expansion, isChampionCard = false, isNew = true }; Plugin.Log($"{val.monsterType} {val.borderType} {val.expansionType} {val.isFoil}"); return val; } catch (Exception ex) { Plugin.Log(ex.Message); throw; } } public CardData CardRoller(ECollectionPackType collectionPackType) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Invalid comparison between Unknown and I4 //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0067: 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_006d: Unknown result type (might be due to invalid IL or missing references) //IL_006e: 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_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Expected O, but got Unknown ECardExpansionType val = (ECardExpansionType)(!((double)Random.Range(0f, 1f) > 0.5)); return new CardData { isFoil = ((double)Random.Range(0f, 1f) > 0.5), isDestiny = ((int)val == 1), borderType = (ECardBorderType)Random.Range(0, 6), monsterType = (EMonsterType)Random.Range(0, 122), expansionType = val, isChampionCard = false, isNew = true }; } } public class CoroutineRunner : MonoBehaviour { private static readonly Queue<Action> _mainThreadQueue = new Queue<Action>(); private static CoroutineRunner _instance; public static CoroutineRunner Instance { get { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown if ((Object)(object)_instance == (Object)null) { GameObject val = new GameObject("CoroutineRunner"); Object.DontDestroyOnLoad((Object)(object)val); _instance = val.AddComponent<CoroutineRunner>(); } return _instance; } } public static void RunOnMainThread(Action action) { CoroutineRunner instance = Instance; lock (_mainThreadQueue) { _mainThreadQueue.Enqueue(action); } } private void Update() { lock (_mainThreadQueue) { while (_mainThreadQueue.Count > 0) { _mainThreadQueue.Dequeue()(); } } } } public class ItemHandler { private Coroutine cashOnlyCoroutine; private float remainingTime = 0f; private bool timerRunning = false; public bool cashOnly = false; public void processNewItem(ItemInfo itemReceived) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Expected O, but got Unknown //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Expected O, but got Unknown //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Expected O, but got Unknown //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Expected O, but got Unknown //IL_0280: Unknown result type (might be due to invalid IL or missing references) //IL_0286: Invalid comparison between Unknown and I4 //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Expected O, but got Unknown //IL_022c: Unknown result type (might be due to invalid IL or missing references) //IL_0231: Unknown result type (might be due to invalid IL or missing references) //IL_0238: Unknown result type (might be due to invalid IL or missing references) //IL_02fc: Unknown result type (might be due to invalid IL or missing references) //IL_0306: Expected O, but got Unknown //IL_0362: Unknown result type (might be due to invalid IL or missing references) //IL_0507: Unknown result type (might be due to invalid IL or missing references) if ((int)itemReceived.ItemId == TrashMapping.smallMoney) { CEventManager.QueueEvent((CEvent)new CEventPlayer_AddCoin((float)(10 * Math.Min(CPlayerData.m_ShopLevel + 1, 25)), false)); } else if ((int)itemReceived.ItemId == TrashMapping.mediumMoney) { CEventManager.QueueEvent((CEvent)new CEventPlayer_AddCoin((float)(20 * Math.Min(CPlayerData.m_ShopLevel + 1, 25)), false)); } else if ((int)itemReceived.ItemId == TrashMapping.largeMoney) { CEventManager.QueueEvent((CEvent)new CEventPlayer_AddCoin((float)(40 * Math.Min(CPlayerData.m_ShopLevel + 1, 25)), false)); } else if ((int)itemReceived.ItemId == TrashMapping.smallXp) { CEventManager.QueueEvent((CEvent)new CEventPlayer_AddShopExp(Math.Min((int)((double)CPlayerData.GetExpRequiredToLevelUp() * 0.1), (CPlayerData.m_ShopLevel + 1 > 20) ? ((int)((double)(300 * (CPlayerData.m_ShopLevel + 1)) * 0.2)) : 400), false)); } else if ((int)itemReceived.ItemId == TrashMapping.mediumXp) { CEventManager.QueueEvent((CEvent)new CEventPlayer_AddShopExp(Math.Min((int)((double)CPlayerData.GetExpRequiredToLevelUp() * 0.17), (CPlayerData.m_ShopLevel + 1 > 20) ? ((int)((double)(600 * (CPlayerData.m_ShopLevel + 1)) * 0.2)) : 800), false)); } else if ((int)itemReceived.ItemId == TrashMapping.largeXp) { CEventManager.QueueEvent((CEvent)new CEventPlayer_AddShopExp(Math.Min((int)((double)CPlayerData.GetExpRequiredToLevelUp() * 0.25), (CPlayerData.m_ShopLevel + 1 > 20) ? ((int)((double)(1000 * (CPlayerData.m_ShopLevel + 1)) * 0.2)) : 1500), false)); } else if ((int)itemReceived.ItemId == TrashMapping.randomcard) { Array values = Enum.GetValues(typeof(ECollectionPackType)); ECollectionPackType collectionPackType = (ECollectionPackType)values.GetValue(Random.Range(0, (Plugin.m_SessionHandler.GetSlotData().CardSanity == 0) ? 8 : Plugin.m_SessionHandler.GetSlotData().CardSanity)); CardData val = Plugin.m_CardHelper.CardRoller(collectionPackType); CPlayerData.AddCard(val, 1); } else if ((int)itemReceived.ItemId == TrashMapping.randomNewCard) { CardData newCard = Plugin.getNewCard(); CPlayerData.AddCard(newCard, 1); } else { if ((int)PlayTableMapping.GetFormatFromInt((int)itemReceived.ItemId) != -1) { return; } if ((int)itemReceived.ItemId == TrashMapping.ProgressiveCustomerMoney) { Plugin.m_SaveManager.IncreaseMoneyMult(); } else if ((int)itemReceived.ItemId == TrashMapping.IncreaseCardLuck) { if (Plugin.m_SaveManager.GetLuck() >= 100) { CEventManager.QueueEvent((CEvent)new CEventPlayer_AddCoin((float)(40 * Math.Min(CPlayerData.m_ShopLevel + 1, 25)), false)); } else { Plugin.m_SaveManager.IncreaseLuck(); } } else if ((int)itemReceived.ItemId == TrashMapping.DecreaseCardLuck) { Plugin.m_SaveManager.DecreaseLuck(); } else if ((int)itemReceived.ItemId == TrashMapping.CurrencyTrap) { CSingleton<CGameManager>.Instance.m_CurrencyType = (EMoneyCurrencyType)Random.RandomRangeInt(0, 8); } else { if ((int)itemReceived.ItemId == TrashMapping.stinkTrap) { FieldInfo field = typeof(CustomerManager).GetField("m_CustomerList", BindingFlags.Instance | BindingFlags.NonPublic); if (field == null) { return; } List<Customer> list = (List<Customer>)field.GetValue(CSingleton<CustomerManager>.Instance); { foreach (Customer item in list) { item.SetSmelly(); } return; } } if ((int)itemReceived.ItemId == TrashMapping.lightTrap) { ((MonoBehaviour)CoroutineRunner.Instance).StartCoroutine(ToggleLightMultipleTimes()); } else if ((int)itemReceived.ItemId == TrashMapping.CreditCardFailure) { remainingTime += 60f; if (!timerRunning) { cashOnlyCoroutine = ((MonoBehaviour)CoroutineRunner.Instance).StartCoroutine(CashOnlyTimerCoroutine()); } } else if ((int)itemReceived.ItemId == TrashMapping.MarketChangeTrap) { CSingleton<PriceChangeManager>.Instance.EvaluatePriceChange(); CSingleton<PriceChangeManager>.Instance.EvaluatePriceCrash(); CPlayerData.UpdateItemPricePercentChange(); CPlayerData.UpdatePastCardPricePercentChange(); } else if (itemReceived.ItemId == LicenseMapping.BASIC_CARD_PACK_ID || (itemReceived.ItemId < 125 && LicenseMapping.mapping.ContainsKey((EItemType)itemReceived.ItemId))) { EItemType val2 = (EItemType)((itemReceived.ItemId != LicenseMapping.BASIC_CARD_PACK_ID) ? itemReceived.ItemId : 0); Plugin.m_SaveManager.IncreaselicensesReceived(); CoroutineRunner.RunOnMainThread(delegate { CSingleton<GameUIScreen>.Instance.EvaluateShopLevelAndExp(); }); } else if ((int)itemReceived.ItemId == ExpansionMapping.progressiveA) { if (Plugin.m_SessionHandler.GetSlotData().AutoRenovate) { CoroutineRunner.RunOnMainThread(delegate { CSingleton<UnlockRoomManager>.Instance.StartUnlockNextRoom(); }); } } else if ((int)itemReceived.ItemId == ExpansionMapping.progressiveB) { if (Plugin.m_SessionHandler.itemCount(itemReceived.ItemId) == 1) { CoroutineRunner.RunOnMainThread(delegate { CSingleton<UnlockRoomManager>.Instance.SetUnlockWarehouseRoom(true); }); SoundManager.PlayAudio("SFX_CustomerBuy", 0.6f, 1f); } else if (Plugin.m_SessionHandler.GetSlotData().AutoRenovate) { CoroutineRunner.RunOnMainThread(delegate { CSingleton<UnlockRoomManager>.Instance.StartUnlockNextWarehouseRoom(); }); } } else if (EmployeeMapping.getindexFromId((int)itemReceived.ItemId) != -1) { int num = EmployeeMapping.getindexFromId((int)itemReceived.ItemId); HireWorkerScreen val3 = Object.FindObjectOfType<HireWorkerScreen>(); HireWorkerPanelUI[] array = Object.FindObjectsOfType<HireWorkerPanelUI>(); HireWorkerPanelUI val4 = null; HireWorkerPanelUI[] array2 = array; foreach (HireWorkerPanelUI val5 in array2) { FieldInfo field2 = typeof(HireWorkerPanelUI).GetField("m_Index", BindingFlags.Instance | BindingFlags.NonPublic); if (field2 == null) { return; } int num2 = (int)field2.GetValue(val5); if (num2 == num) { val4 = val5; break; } } if (!((Object)(object)val4 == (Object)null)) { Plugin.Log("detected Hire Worker Screen"); Plugin.Log("Found Hire Worker Panel"); val4.m_HiredText.SetActive(false); val4.m_PurchaseBtn.SetActive(true); Plugin.Log($"Recieved Worker While panel was open: {(int)itemReceived.ItemId}"); } } else if (FurnatureMapping.getindexFromId((int)itemReceived.ItemId) != -1) { int num3 = FurnatureMapping.getindexFromId((int)itemReceived.ItemId); FurnitureShopPanelUI val6 = null; FurnitureShopPanelUI[] array3 = Object.FindObjectsOfType<FurnitureShopPanelUI>(); FurnitureShopPanelUI[] array4 = array3; foreach (FurnitureShopPanelUI val7 in array4) { FieldInfo field3 = typeof(FurnitureShopPanelUI).GetField("m_Index", BindingFlags.Instance | BindingFlags.NonPublic); if (field3 == null) { return; } int num4 = (int)field3.GetValue(val7); if (num4 == num3) { val6 = val7; break; } } if (!((Object)(object)val6 == (Object)null)) { FurnaturePatches.EnableFurnature(val6, num3); } } else if ((int)itemReceived.ItemId == CardMapping.oneghostcard) { addRandomGhost(); } else if ((int)itemReceived.ItemId == CardMapping.twoghostcard) { for (int k = 0; k < 2; k++) { addRandomGhost(); } } else if ((int)itemReceived.ItemId == CardMapping.threeghostcard) { for (int l = 0; l < 3; l++) { addRandomGhost(); } } else if ((int)itemReceived.ItemId == CardMapping.fourghostcard) { for (int m = 0; m < 4; m++) { Plugin.Log("Ghost"); addRandomGhost(); } } else if ((int)itemReceived.ItemId == CardMapping.fiveghostcard) { for (int n = 0; n < 5; n++) { addRandomGhost(); } } } } } private void addRandomGhost() { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006e: 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_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Expected O, but got Unknown List<EMonsterType> shownMonsterList = InventoryBase.GetShownMonsterList((ECardExpansionType)2); CPlayerData.AddCard(new CardData { isFoil = ((double)Random.Range(0f, 1f) > 0.5), isDestiny = ((double)Random.Range(0f, 1f) > 0.5), borderType = (ECardBorderType)0, monsterType = InventoryBase.GetMonsterData(shownMonsterList[Random.Range(0, shownMonsterList.Count())]).MonsterType, expansionType = (ECardExpansionType)2, isChampionCard = false, isNew = true }, 1); } private IEnumerator ToggleLightMultipleTimes() { int repeats = Random.Range(1, 6) * 2 - 1; for (int i = 0; i < repeats; i++) { CSingleton<LightManager>.Instance.ToggleShopLight(); SoundManager.PlayAudio("SFX_ButtonLightTap", 0.6f, 0.5f); float delay = Random.Range(0.5f, 2f); yield return (object)new WaitForSeconds(delay); } } private IEnumerator CashOnlyTimerCoroutine() { timerRunning = true; for (cashOnly = true; remainingTime > 0f; remainingTime -= Time.deltaTime) { yield return null; } cashOnly = false; timerRunning = false; } } [BepInPlugin("ApClient", "Ap Client For TCG Sim", "0.4.0")] public class Plugin : BaseUnityPlugin { internal static ManualLogSource Logger; private readonly Harmony m_Harmony = new Harmony("ApClient"); public static APClientSaveManager m_SaveManager = new APClientSaveManager(); public static ItemHandler m_ItemHandler = new ItemHandler(); public static SessionHandler m_SessionHandler = new SessionHandler(); public static CardHelper m_CardHelper = new CardHelper(); private static bool SceneLoaded = false; private Plugin() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown m_Harmony.PatchAll(); } private void Awake() { Logger = ((BaseUnityPlugin)this).Logger; Settings.Instance.Load(this); Logger.LogInfo((object)"Plugin ApClient is loaded!"); SceneManager.sceneLoaded += OnSceneLoad; } private void Start() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown GameObject val = new GameObject("MyGUI"); val.AddComponent<APGui>(); Object.DontDestroyOnLoad((Object)(object)val); APConsole.Create(); } private void OnDestroy() { m_Harmony.UnpatchSelf(); } public static bool isSceneLoaded() { return SceneLoaded; } public static void onSceneLoadLogic() { SceneLoaded = true; m_SessionHandler.ProcessCachedItems(); } public static bool OverrideTrades() { return m_SessionHandler.GetSlotData().TradesAreNew; } public static float getNumLuckItems() { return m_SaveManager.GetLuck(); } public static bool isCashOnly() { return m_ItemHandler.cashOnly; } public static CardData getNewCard() { //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Invalid comparison between Unknown and I4 //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Invalid comparison between Unknown and I4 //IL_00d3: Unknown result type (might be due to invalid IL or missing references) try { int num = 8; int borderlimit = 5; bool foils = true; if (m_SessionHandler.GetSlotData().CardSanity != 0) { borderlimit = m_SessionHandler.GetSlotData().BorderInSanity; foils = m_SessionHandler.GetSlotData().FoilInSanity; num = m_SessionHandler.GetSlotData().CardSanity; } ECardExpansionType val = (ECardExpansionType)(Random.Range(0, num) > 4); HashSet<ERarity> hashSet = new HashSet<ERarity>(); if ((int)val == 1) { for (int i = 0; i < num - 4; i++) { hashSet.Add((ERarity)i); } } if ((int)val == 0) { for (int j = 0; j < num && j < 4; j++) { hashSet.Add((ERarity)j); } } return m_CardHelper.RandomNewCard(val, hashSet, borderlimit, foils); } catch (Exception ex) { Log(ex.ToString()); APConsole.Instance.Log("Error in New Card Randomization"); return m_CardHelper.CardRoller((ECollectionPackType)7); } } private void OnSceneLoad(Scene scene, LoadSceneMode mode) { Log(" Scene Load: " + ((Scene)(ref scene)).name); if (((Scene)(ref scene)).name == "Title") { m_SaveManager = new APClientSaveManager(); setTitleInteractable(interactable: false); SceneLoaded = false; } if (((Scene)(ref scene)).name == "Start") { APGui.showGUI = false; } } public static void RunTitleInteractableSaveLogic() { TitleScreen val = Object.FindFirstObjectByType<TitleScreen>(); GameObject val2 = GameObject.Find("NewGameBtn"); Button val3 = null; if ((Object)(object)val2 != (Object)null) { val3 = val2.GetComponentInChildren<Button>(); } if (m_SaveManager.doesSaveExist()) { ((Selectable)val.m_LoadGameButton).interactable = true; ((Selectable)val3).interactable = false; } else { ((Selectable)val.m_LoadGameButton).interactable = false; ((Selectable)val3).interactable = true; } } public static void setTitleInteractable(bool interactable) { TitleScreen val = Object.FindFirstObjectByType<TitleScreen>(); ((Selectable)val.m_LoadGameButton).interactable = interactable; GameObject val2 = GameObject.Find("NewGameBtn"); if ((Object)(object)val2 != (Object)null) { Button componentInChildren = val2.GetComponentInChildren<Button>(); ((Selectable)componentInChildren).interactable = interactable; } } public static void Log(string s) { Logger.LogInfo((object)s); } private void Update() { if (Input.GetKeyDown((KeyCode)98)) { } if (!Input.GetKeyDown((KeyCode)104)) { } } } public class SessionHandler { private class ItemCache { public ItemInfo info { get; set; } public int index { get; set; } } [CompilerGenerated] private static class <>O { public static Func<string, int> <0>__Parse; public static MessageReceivedHandler <1>__OnMessageReceived; } private ArchipelagoSession session; private SlotData slotData = new SlotData(); private Queue<ItemCache> cachedItems = new Queue<ItemCache>(); private LoginResult result = null; private DeathLinkService deathLinkService = null; private bool isConnected = false; public SlotData GetSlotData() { return slotData; } public int itemCount(long id) { return session.Items.AllItemsReceived.Where((ItemInfo i) => i.ItemId == id).Count(); } public bool ControlTrades() { return slotData.TradesAreNew; } public bool hasItem(long id) { if (id == 0) { id = 190L; } return itemCount(id) > 0; } public bool isEventUnlocked(EGameEventFormat format) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) return hasItem(PlayTableMapping.FormatStartingId + format); } public void SendGoalCompletion() { session.SetGoalAchieved(); } public void CompleteLocationChecks(params long[] ids) { session.Locations.CompleteLocationChecks(ids); } public bool isStartingItem(int id) { return slotData.startingItems.Contains(id); } public int[] startingids() { return slotData.startingItems.ToArray(); } public int GetRemainingLicenses(int currentLevelStart) { //IL_0032: 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_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //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_0142: 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_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_01fa: Unknown result type (might be due to invalid IL or missing references) Dictionary<EItemType, int> dictionary = new Dictionary<EItemType, int>(); foreach (DictionaryEntry item in slotData.pg1IndexMapping) { EItemType key = (EItemType)item.Key; int num = (int)item.Value; if (num < currentLevelStart && !dictionary.ContainsKey(key)) { dictionary[key] = num; } } foreach (DictionaryEntry item2 in slotData.pg2IndexMapping) { EItemType key2 = (EItemType)item2.Key; int num2 = (int)item2.Value; if (num2 < currentLevelStart && !dictionary.ContainsKey(key2)) { dictionary[key2] = num2; } } foreach (DictionaryEntry item3 in slotData.pg3IndexMapping) { EItemType key3 = (EItemType)item3.Key; int num3 = (int)item3.Value; if (num3 < currentLevelStart && !dictionary.ContainsKey(key3)) { dictionary[key3] = num3; } } foreach (DictionaryEntry item4 in slotData.ttIndexMapping) { EItemType key4 = (EItemType)item4.Key; int num4 = (int)item4.Value; if (num4 < currentLevelStart && !dictionary.ContainsKey(key4)) { dictionary[key4] = num4; } } if (dictionary.Count == 0) { return 0; } int requiredLicenses = slotData.RequiredLicenses; int num5 = currentLevelStart; int num6 = 0; int num7 = 0; if (currentLevelStart > 25) { num5 = 25; num6 = currentLevelStart - 25; } if (currentLevelStart > 50) { num6 = 25; num7 = currentLevelStart - 50; } int num8 = num5 / 5 * slotData.RequiredLicenses; num8 += num6 / 5 * 3; num8 += num7 / 5 * 2; int num9 = dictionary.Keys.Count((EItemType itemId) => hasItem((long)itemId)); int num10 = num8 - num9; return (num10 > 0) ? num10 : 0; } private OrderedDictionary PgStrToDict(string str) { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) JObject val = JObject.Parse(str); OrderedDictionary orderedDictionary = new OrderedDictionary(); foreach (JProperty item in val.Properties()) { try { int num = int.Parse(item.Name); EItemType val2 = (EItemType)((num != 190) ? num : 0); int num2 = (int)item.Value; orderedDictionary.Add(val2, num2); } catch { Plugin.Log($" FAILED {item.Name} : {item.Value}"); } } return orderedDictionary; } private List<int> StrToList(string str) { int num; return (from s in str.Trim('[', ']').Split(',') select s.Trim() into s where int.TryParse(s, out num) select s).Select(int.Parse).ToList(); } public void sendDeath() { //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Expected O, but got Unknown if (slotData.Deathlink) { Plugin.Log("Sent Death!"); deathLinkService.SendDeathLink(new DeathLink(Settings.Instance.LastUsedSlot.Value, Settings.Instance.LastUsedSlot.Value + " Died to Not Paying Bills.")); } } public bool GetIsConnected() { return isConnected; } public void connect(string ip, string password, string slot) { //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Expected O, but got Unknown //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Expected O, but got Unknown //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Expected O, but got Unknown //IL_0550: Unknown result type (might be due to invalid IL or missing references) //IL_0557: Expected O, but got Unknown //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Expected O, but got Unknown //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Expected O, but got Unknown //IL_0467: Unknown result type (might be due to invalid IL or missing references) //IL_0471: Expected O, but got Unknown APGui.state = "Connecting"; session = ArchipelagoSessionFactory.CreateSession(ip, 38281); IMessageLogHelper messageLog = session.MessageLog; object obj = <>O.<1>__OnMessageReceived; if (obj == null) { MessageReceivedHandler val = OnMessageReceived; <>O.<1>__OnMessageReceived = val; obj = (object)val; } messageLog.OnMessageReceived += (MessageReceivedHandler)obj; session.Items.ItemReceived += (ItemReceivedHandler)delegate(ReceivedItemsHelper receivedItemsHelper) { if (!Plugin.isSceneLoaded()) { Plugin.Log("Not In Scene"); cachedItems.Enqueue(new ItemCache { info = receivedItemsHelper.DequeueItem(), index = receivedItemsHelper.Index }); Plugin.Log("Enqueue"); } else if (Plugin.m_SaveManager.GetProcessedIndex() <= receivedItemsHelper.Index) { Plugin.m_SaveManager.IncreaseProcessedIndex(); ItemInfo itemReceived = receivedItemsHelper.DequeueItem(); Plugin.m_ItemHandler.processNewItem(itemReceived); CSingleton<CGameManager>.Instance.SaveGameData(3); } }; try { result = session.TryConnectAndLogin("TCG Card Shop Simulator", slot, (ItemsHandlingFlags)7, (Version)null, (string[])null, (string)null, password, true); } catch (Exception ex) { APGui.state = "Connection Failed"; result = (LoginResult)new LoginFailure(ex.GetBaseException().Message); Plugin.Log(ex.GetBaseException().Message); } if (result.Successful) { isConnected = true; Plugin.m_SaveManager.setConnectionData(session.RoomState.Seed, slot); session.Socket.SocketClosed += (SocketClosedHandler)delegate { isConnected = false; APGui.showGUI = true; APGui.state = "AP Disconnected"; APConsole.Instance.Log("Connection Closed"); }; LoginSuccessful val2 = (LoginSuccessful)result; string text = val2.SlotData.GetValueOrDefault("ModVersion").ToString(); if (!text.Equals("0.4.0")) { APGui.state = "AP Expects Mod v" + text; } else { APGui.state = "Connected"; Plugin.RunTitleInteractableSaveLogic(); } slotData.MaxLevel = int.Parse(val2.SlotData.GetValueOrDefault("MaxLevel").ToString()); slotData.RequiredLicenses = int.Parse(val2.SlotData.GetValueOrDefault("RequiredLicenses").ToString()); slotData.Goal = int.Parse(val2.SlotData.GetValueOrDefault("Goal").ToString()); slotData.GhostGoalAmount = int.Parse(val2.SlotData.GetValueOrDefault("GhostGoalAmount").ToString()); slotData.AutoRenovate = val2.SlotData.GetValueOrDefault("AutoRenovate").ToString() == "1"; slotData.TradesAreNew = val2.SlotData.GetValueOrDefault("BetterTrades").ToString() == "1"; slotData.ExtraStartingItemChecks = int.Parse(val2.SlotData.GetValueOrDefault("ExtraStartingItemChecks").ToString()); slotData.SellCheckAmount = int.Parse(val2.SlotData.GetValueOrDefault("SellCheckAmount").ToString()); slotData.ChecksPerPack = int.Parse(val2.SlotData.GetValueOrDefault("ChecksPerPack").ToString()); slotData.CardCollectPercentage = int.Parse(val2.SlotData.GetValueOrDefault("CardCollectPercentage").ToString()); slotData.NumberOfGameChecks = int.Parse(val2.SlotData.GetValueOrDefault("PlayTableChecks").ToString()); slotData.GamesPerCheck = int.Parse(val2.SlotData.GetValueOrDefault("GamesPerCheck").ToString()); slotData.NumberOfSellCardChecks = int.Parse(val2.SlotData.GetValueOrDefault("NumberOfSellCardChecks").ToString()); slotData.SellCardsPerCheck = int.Parse(val2.SlotData.GetValueOrDefault("SellCardsPerCheck").ToString()); slotData.Deathlink = val2.SlotData.GetValueOrDefault("Deathlink").ToString() == "1"; slotData.CardSanity = int.Parse(val2.SlotData.GetValueOrDefault("CardSanity").ToString()); slotData.FoilInSanity = val2.SlotData.GetValueOrDefault("FoilInSanity").ToString() == "1"; slotData.BorderInSanity = int.Parse(val2.SlotData.GetValueOrDefault("BorderInSanity").ToString()); if (slotData.Deathlink) { deathLinkService = DeathLinkProvider.CreateDeathLinkService(session); deathLinkService.EnableDeathLink(); deathLinkService.OnDeathLinkReceived += (DeathLinkReceivedHandler)delegate(DeathLink deathLinkObject) { //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Expected O, but got Unknown if (slotData.Deathlink && Plugin.isSceneLoaded()) { APConsole.Instance.Log(deathLinkObject.Cause ?? ""); CSingleton<LightManager>.Instance.m_HasDayEnded = true; CSingleton<LightManager>.Instance.m_TimeHour = 21; CSingleton<LightManager>.Instance.EvaluateTimeClock(); CEventManager.QueueEvent((CEvent)new CEventPlayer_OnDayEnded()); } }; } slotData.pg1IndexMapping = PgStrToDict(val2.SlotData.GetValueOrDefault("ShopPg1Mapping").ToString()); slotData.pg2IndexMapping = PgStrToDict(val2.SlotData.GetValueOrDefault("ShopPg2Mapping").ToString()); slotData.pg3IndexMapping = PgStrToDict(val2.SlotData.GetValueOrDefault("ShopPg3Mapping").ToString()); slotData.ttIndexMapping = PgStrToDict(val2.SlotData.GetValueOrDefault("ShopTTMapping").ToString()); slotData.startingItems = StrToList(val2.SlotData.GetValueOrDefault("StartingIds").ToString()); Settings.Instance.SaveNewConnectionInfo(ip, password, slot); } else { LoginFailure val3 = (LoginFailure)result; string seed = "Failed to Connect to " + ip + " as " + slot + ":"; seed = val3.Errors.Aggregate(seed, (string current, string error) => current + "\n " + error); seed = val3.ErrorCodes.Aggregate(seed, (string current, ConnectionRefusedError error) => current + $"\n {error}"); APConsole.Instance.Log(seed); } } private static void OnMessageReceived(LogMessage message) { APConsole.Instance.Log(((object)message).ToString() ?? string.Empty); } public void ProcessCachedItems() { while (cachedItems.Any()) { ItemCache itemCache = cachedItems.Dequeue(); if (Plugin.m_SaveManager.GetProcessedIndex() <= itemCache.index) { Plugin.m_SaveManager.IncreaseProcessedIndex(); Plugin.Log("Item on load " + itemCache.info.ItemName); Plugin.m_ItemHandler.processNewItem(itemCache.info); } } cachedItems.Clear(); CSingleton<CGameManager>.Instance.SaveGameData(3); } } public class Settings { private static Settings m_instance; private Plugin plugin; public ConfigEntry<int> StartingMoney; public ConfigEntry<int> XpMultiplier; public ConfigEntry<KeyCode> MyHotkey; public ConfigEntry<KeyCode> ConsoleHotkey; public ConfigEntry<bool> disabledeathlink; public ConfigEntry<string> LastUsedIP; public ConfigEntry<string> LastUsedPassword; public ConfigEntry<string> LastUsedSlot; public static Settings Instance { get { if (m_instance == null) { m_instance = new Settings(); } return m_instance; } } public void Load(Plugin plugin) { this.plugin = plugin; disabledeathlink = ((BaseUnityPlugin)plugin).Config.Bind<bool>("1. GamePlay", "Force Deathlink Off", false, "If this is on, Deathlink is forced off"); MyHotkey = ((BaseUnityPlugin)plugin).Config.Bind<KeyCode>("2. Hotkeys", "Toggle Connection Window", (KeyCode)289, "Press this key to toggle AP Connection GUI"); ConsoleHotkey = ((BaseUnityPlugin)plugin).Config.Bind<KeyCode>("2. Hotkeys", "Toggle AP Console", (KeyCode)290, "Press this key to toggle AP Console Output"); LastUsedIP = ((BaseUnityPlugin)plugin).Config.Bind<string>("Connection", "LastUsedIP", "", "The last server IP entered."); LastUsedPassword = ((BaseUnityPlugin)plugin).Config.Bind<string>("Connection", "LastUsedPassword", "", "The last server password entered."); LastUsedSlot = ((BaseUnityPlugin)plugin).Config.Bind<string>("Connection", "LastUsedSlot", "", "The last player slot name entered."); } public void SaveNewConnectionInfo(string ip, string password, string slot) { LastUsedIP.Value = ip; LastUsedPassword.Value = password; LastUsedSlot.Value = slot; ((BaseUnityPlugin)plugin).Config.Save(); } } public static class MyPluginInfo { public const string PLUGIN_GUID = "ApClient"; public const string PLUGIN_NAME = "Ap Client For TCG Sim"; public const string PLUGIN_VERSION = "0.4.0"; } } namespace ApClient.patches { public class BillPatches { [HarmonyPatch(typeof(RentBillScreen))] public class NewDay { [HarmonyPatch("EvaluateNewDayBill")] [HarmonyPostfix] private static void PostFix(RentBillScreen __instance) { BillData bill = CPlayerData.GetBill((EBillType)1); BillData bill2 = CPlayerData.GetBill((EBillType)2); BillData bill3 = CPlayerData.GetBill((EBillType)3); bool flag = false; if (bill != null && !BillRentDeath && __instance.m_DueDayMax - CPlayerData.GetBill((EBillType)1).billDayPassed <= -1) { flag = true; BillRentDeath = true; } if (bill2 != null && !BillElectricDeath && __instance.m_DueDayMax - CPlayerData.GetBill((EBillType)2).billDayPassed <= -1) { flag = true; BillElectricDeath = true; } if (bill3 != null && !BillEmployeeDeath && __instance.m_DueDayMax - CPlayerData.GetBill((EBillType)3).billDayPassed <= -1) { flag = true; BillEmployeeDeath = true; } if (flag) { Plugin.m_SessionHandler.sendDeath(); } } } [HarmonyPatch(typeof(RentBillScreen))] public class PaidRent { [HarmonyPatch("OnPressPayRentBill")] [HarmonyPostfix] private static void PostFix(RentBillScreen __instance) { BillRentDeath = false; } } [HarmonyPatch(typeof(RentBillScreen))] public class PaidElectric { [HarmonyPatch("OnPressPayElectricBill")] [HarmonyPostfix] private static void PostFix(RentBillScreen __instance) { BillElectricDeath = false; } } [HarmonyPatch(typeof(RentBillScreen))] public class PaidSalery { [HarmonyPatch("OnPressPaySalaryBill")] [HarmonyPostfix] private static void PostFix(RentBillScreen __instance) { BillEmployeeDeath = false; } } [HarmonyPatch(typeof(RentBillScreen))] public class PaidAll { [HarmonyPatch("OnPressPayAllBill")] [HarmonyPostfix] private static void PostFix(RentBillScreen __instance) { BillRentDeath = false; BillElectricDeath = false; BillEmployeeDeath = false; } } private static bool BillRentDeath; private static bool BillElectricDeath; private static bool BillEmployeeDeath; } public class BinderPagePatches { [HarmonyPatch(typeof(CollectionBinderUI))] public class Awake { [HarmonyPatch("Awake")] [HarmonyPostfix] private static void Postfix(CollectionBinderUI __instance) { //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Invalid comparison between Unknown and I4 //IL_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_0202: Unknown result type (might be due to invalid IL or missing references) //IL_0211: Unknown result type (might be due to invalid IL or missing references) //IL_0216: Unknown result type (might be due to invalid IL or missing references) //IL_022c: Unknown result type (might be due to invalid IL or missing references) //IL_023b: Unknown result type (might be due to invalid IL or missing references) //IL_0240: Unknown result type (might be due to invalid IL or missing references) //IL_0256: Unknown result type (might be due to invalid IL or missing references) //IL_0265: Unknown result type (might be due to invalid IL or missing references) //IL_026a: Unknown result type (might be due to invalid IL or missing references) //IL_0280: Unknown result type (might be due to invalid IL or missing references) //IL_028f: Unknown result type (might be due to invalid IL or missing references) //IL_0294: 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) //IL_01c6: 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_0166: Unknown result type (might be due to invalid IL or missing references) commonText = Object.Instantiate<TextMeshProUGUI>(__instance.m_CardCollectedText, ((TMP_Text)__instance.m_CardCollectedText).transform.parent); rareText = Object.Instantiate<TextMeshProUGUI>(__instance.m_CardCollectedText, ((TMP_Text)__instance.m_CardCollectedText).transform.parent); epicText = Object.Instantiate<TextMeshProUGUI>(__instance.m_CardCollectedText, ((TMP_Text)__instance.m_CardCollectedText).transform.parent); legendaryText = Object.Instantiate<TextMeshProUGUI>(__instance.m_CardCollectedText, ((TMP_Text)__instance.m_CardCollectedText).transform.parent); ((TMP_Text)commonText).text = ""; ((TMP_Text)rareText).text = ""; ((TMP_Text)epicText).text = ""; ((TMP_Text)legendaryText).text = ""; sanityText = Object.Instantiate<TextMeshProUGUI>(__instance.m_CardCollectedText, ((TMP_Text)__instance.m_CardCollectedText).transform.parent); RectTransform rectTransform = ((TMP_Text)sanityText).rectTransform; rectTransform.anchoredPosition += new Vector2(0f, -80f); ECardExpansionType expansionType = __instance.m_CollectionAlbum.m_ExpansionType; if ((int)expansionType == 2) { ((TMP_Text)sanityText).text = ""; if (Plugin.m_SessionHandler.GetSlotData().Goal == 2) { ((TMP_Text)sanityText).text = $"Sold {Plugin.m_SaveManager.GetExpansionChecks(expansionType)} / {Plugin.m_SaveManager.getTotalExpansionChecks(expansionType)} {((object)(ECardExpansionType)(ref expansionType)).ToString()} Checks"; } return; } if (Plugin.m_SessionHandler.GetSlotData().CardSanity > 0) { ((TMP_Text)sanityText).text = $"{Plugin.m_SaveManager.GetExpansionChecks(expansionType)} / {Plugin.m_SaveManager.getTotalExpansionChecks(expansionType)} {((object)(ECardExpansionType)(ref expansionType)).ToString()} Checks"; return; } updatepackText(expansionType); RectTransform rectTransform2 = ((TMP_Text)commonText).rectTransform; rectTransform2.anchoredPosition += new Vector2(-100f, -60f); RectTransform rectTransform3 = ((TMP_Text)rareText).rectTransform; rectTransform3.anchoredPosition += new Vector2(100f, -60f); RectTransform rectTransform4 = ((TMP_Text)epicText).rectTransform; rectTransform4.anchoredPosition += new Vector2(-100f, -120f); RectTransform rectTransform5 = ((TMP_Text)legendaryText).rectTransform; rectTransform5.anchoredPosition += new Vector2(100f, -120f); } } [HarmonyPatch(typeof(CollectionBinderUI))] public class SetCardCollected { [HarmonyPatch("SetCardCollected")] [HarmonyPostfix] private static void Postfix(CollectionBinderUI __instance, int current, ECardExpansionType expansionType) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Invalid comparison between Unknown and I4 //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: 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_00ec: 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_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) if ((int)expansionType == 2) { ((TMP_Text)sanityText).text = ""; if (Plugin.m_SessionHandler.GetSlotData().Goal == 2) { ((TMP_Text)sanityText).text = $"Sold {Plugin.m_SaveManager.GetExpansionChecks(expansionType)} / {Plugin.m_SaveManager.getTotalExpansionChecks(expansionType)} {((object)(ECardExpansionType)(ref expansionType)).ToString()} Checks"; } ((TMP_Text)commonText).text = ""; ((TMP_Text)rareText).text = ""; ((TMP_Text)epicText).text = ""; ((TMP_Text)legendaryText).text = ""; } else if (Plugin.m_SessionHandler.GetSlotData().CardSanity > 0) { ECardExpansionType expansionType2 = __instance.m_CollectionAlbum.m_ExpansionType; ((TMP_Text)sanityText).text = $"{Plugin.m_SaveManager.GetExpansionChecks(expansionType2)} / {Plugin.m_SaveManager.getTotalExpansionChecks(expansionType2)} {((object)(ECardExpansionType)(ref expansionType2)).ToString()} Checks"; } else { ECardExpansionType expansionType3 = __instance.m_CollectionAlbum.m_ExpansionType; updatepackText(expansionType3); } } } [HarmonyPatch(typeof(CollectionBinderUI))] public class CardText { [HarmonyPatch("OnPressSwitchExpansion")] [HarmonyPostfix] private static void Postfix(CollectionBinderUI __instance, int expansionIndex) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Invalid comparison between Unknown and I4 //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) ECardExpansionType val = (ECardExpansionType)expansionIndex; if (Plugin.m_SessionHandler.GetSlotData().Goal == 2 && (int)val == 2) { ((TMP_Text)sanityText).text = ""; if (Plugin.m_SessionHandler.GetSlotData().Goal == 2) { ((TMP_Text)sanityText).text = $"Sold {Plugin.m_SaveManager.GetExpansionChecks(val)} / {Plugin.m_SaveManager.getTotalExpansionChecks(val)} {((object)(ECardExpansionType)(ref val)).ToString()} Checks"; } ((TMP_Text)commonText).text = ""; ((TMP_Text)rareText).text = ""; ((TMP_Text)epicText).text = ""; ((TMP_Text)legendaryText).text = ""; } else if (Plugin.m_SessionHandler.GetSlotData().CardSanity > 0) { ECardExpansionType expansionType = __instance.m_CollectionAlbum.m_ExpansionType; ((TMP_Text)sanityText).text = $"{Plugin.m_SaveManager.GetExpansionChecks(expansionType)} / {Plugin.m_SaveManager.getTotalExpansionChecks(expansionType)} {((object)(ECardExpansionType)(ref expansionType)).ToString()} Checks"; } else { ECardExpansionType expansionType2 = __instance.m_CollectionAlbum.m_ExpansionType; updatepackText(expansionType2); } } } [HarmonyPatch(typeof(BinderPageGrp))] public class single { [HarmonyPatch("SetSingleCard")] [HarmonyPostfix] private static void SetSingleCard(BinderPageGrp __instance, int cardIndex, CardData cardData, int cardCount, ECollectionSortingType sortingType) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Invalid comparison between Unknown and I4 //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Invalid comparison between Unknown and I4 int cardSaveIndex = CPlayerData.GetCardSaveIndex(cardData); if (CPlayerData.GetIsCardCollectedList(cardData.expansionType, (int)cardData.expansionType == 2)[cardSaveIndex] && cardCount <= 0 && cardData != null) { if ((int)cardData.expansionType != 2) { SetCardUIAlpha(__instance.m_CardList[cardIndex], 0.35f); __instance.m_CardList[cardIndex].m_CardUI.SetCardUI(cardData); __instance.m_CardList[cardIndex].SetVisibility(true); ((TMP_Text)__instance.m_CardList[cardIndex].m_CardCountText).text = "Check Collected"; __instance.m_CardList[cardIndex].SetCardCountTextVisibility(true); } } else { SetCardUIAlpha(__instance.m_CardList[cardIndex], 1f); } } } [HarmonyPatch(typeof(CollectionBinderFlipAnimCtrl))] public class onclick { [HarmonyPatch("OnMouseButtonUp")] [HarmonyPrefix] private static bool Prefix(CollectionBinderFlipAnimCtrl __instance) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance.m_CurrentRaycastedInteractableCard3d == (Object)null) { return true; } CardData cardData = __instance.m_CurrentRaycastedInteractableCard3d.m_Card3dUI.m_CardUI.GetCardData(); int cardSaveIndex = CPlayerData.GetCardSaveIndex(cardData); int cardAmountByIndex = CPlayerData.GetCardAmountByIndex(cardSaveIndex, cardData.expansionType, cardData.isDestiny); if (cardAmountByIndex <= 0) { return false; } return true; } } [HarmonyPatch(typeof(CollectionBinderFlipAnimCtrl))] public class onrightclick { [HarmonyPatch("OnRightMouseButtonUp")] [HarmonyPrefix] private static bool Prefix(CollectionBinderFlipAnimCtrl __instance) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance.m_CurrentRaycastedInteractableCard3d == (Object)null) { return true; } CardData cardData = __instance.m_CurrentRaycastedInteractableCard3d.m_Card3dUI.m_CardUI.GetCardData(); int cardSaveIndex = CPlayerData.GetCardSaveIndex(cardData); int cardAmountByIndex = CPlayerData.GetCardAmountByIndex(cardSaveIndex, cardData.expansionType, cardData.isDestiny); if (cardAmountByIndex <= 0) { return false; } return true; } } [HarmonyPatch(typeof(CollectionBinderFlipAnimCtrl))] public class Anim { [HarmonyPatch("UpdateBinderAllCardUI")] [HarmonyPostfix] private static void UpdateBinderAllCardUI(CollectionBinderFlipAnimCtrl __instance, int binderIndex, int pageIndex) { //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Invalid comparison between Unknown and I4 //IL_0062: 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_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Expected O, but got Unknown //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: 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_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) if (pageIndex <= 0 || pageIndex > __instance.m_MaxIndex) { return; } for (int i = 0; i < __instance.m_BinderPageGrpList[binderIndex].m_CardList.Count; i++) { int num = (pageIndex - 1) * 12 + i; if (num >= __instance.m_SortedIndexList.Count) { int num2 = __instance.m_SortedIndexList[num]; bool isDestiny = false; if ((int)__instance.m_ExpansionType == 2 && num2 >= InventoryBase.GetShownMonsterList(__instance.m_ExpansionType).Count * CPlayerData.GetCardAmountPerMonsterType(__instance.m_ExpansionType, true)) { isDestiny = true; num2 -= InventoryBase.GetShownMonsterList(__instance.m_ExpansionType).Count * CPlayerData.GetCardAmountPerMonsterType(__instance.m_ExpansionType, true); } CardData val = new CardData(); val.monsterType = CPlayerData.GetMonsterTypeFromCardSaveIndex(num2, __instance.m_ExpansionType); val.isFoil = num2 % CPlayerData.GetCardAmountPerMonsterType(__instance.m_ExpansionType, true) >= CPlayerData.GetCardAmountPerMonsterType(__instance.m_ExpansionType, false); val.borderType = (ECardBorderType)(num2 % CPlayerData.GetCardAmountPerMonsterType(__instance.m_ExpansionType, false)); val.isDestiny = isDestiny; val.expansionType = __instance.m_ExpansionType; __instance.m_BinderPageGrpList[binderIndex].SetSingleCard(i, val, 0, __instance.m_SortingType); } } } } [HarmonyPatch(typeof(BinderPageGrp))] public class set { [HarmonyPatch("SetCard")] [HarmonyPostfix] private static void PostFix(BinderPageGrp __instance, int index, ECardExpansionType cardExpansionType, bool isDimensionCard) { //IL_000c: 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_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Invalid comparison between Unknown and I4 //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Expected O, but got Unknown //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_006e: 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_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Invalid comparison between Unknown and I4 for (int i = 0; i < __instance.m_CardList.Count; i++) { int num = (index - 1) * CPlayerData.GetCardAmountPerMonsterType(cardExpansionType, true) + i; int cardAmountByIndex = CPlayerData.GetCardAmountByIndex(num, cardExpansionType, isDimensionCard); if (CPlayerData.GetIsCardCollectedList(cardExpansionType, isDimensionCard)[num] && cardAmountByIndex <= 0) { bool isDestiny = false; if ((int)cardExpansionType != 2) { CardData val = new CardData(); ECardBorderType borderType = (ECardBorderType)(i % CPlayerData.GetCardAmountPerMonsterType(cardExpansionType, false)); val.monsterType = CPlayerData.GetMonsterTypeFromCardSaveIndex(num, cardExpansionType); val.borderType = borderType; val.expansionType = cardExpansionType; val.isDestiny = isDestiny; val.isNew = false; val.isFoil = i >= CPlayerData.GetCardAmountPerMonsterType(cardExpansionType, false); __instance.m_CardList[i].m_CardUI.SetCardUI(val); __instance.m_CardList[i].SetVisibility(true); ((TMP_Text)__instance.m_CardList[i].m_CardCountText).text = (((int)cardExpansionType == 2) ? "Ghost Found" : "Check Collected"); __instance.m_CardList[i].SetCardCountTextVisibility(true); SetCardUIAlpha(__instance.m_CardList[i], 0.35f); } } } } } private static TextMeshProUGUI sanityText; private static TextMeshProUGUI commonText; private static TextMeshProUGUI rareText; private static TextMeshProUGUI epicText; private static TextMeshProUGUI legendaryText; private static void updatepackText(ECardExpansionType eCardExpansionType) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Invalid comparison between Unknown and I4 if ((int)eCardExpansionType == 0) { ((TMP_Text)commonText).text = $"{Plugin.m_SaveManager.GetSentChecks((ECollectionPackType)0)} / {Plugin.m_SessionHandler.GetSlotData().ChecksPerPack} Basic Pack Checks"; ((TMP_Text)rareText).text = $"{Plugin.m_SaveManager.GetSentChecks((ECollectionPackType)1)} / {Plugin.m_SessionHandler.GetSlotData().ChecksPerPack} Rare Pack Checks"; ((TMP_Text)epicText).text = $"{Plugin.m_SaveManager.GetSentChecks((ECollectionPackType)2)} / {Plugin.m_SessionHandler.GetSlotData().ChecksPerPack} Epic Pack Checks"; ((TMP_Text)legendaryText).text = $"{Plugin.m_SaveManager.GetSentChecks((ECollectionPackType)3)} / {Plugin.m_SessionHandler.GetSlotData().ChecksPerPack} Legendary Pack Checks"; } else { ((TMP_Text)commonText).text = $"{Plugin.m_SaveManager.GetSentChecks((ECollectionPackType)4)} / {Plugin.m_SessionHandler.GetSlotData().ChecksPerPack} Destiny Basic Pack Checks"; ((TMP_Text)rareText).text = $"{Plugin.m_SaveManager.GetSentChecks((ECollectionPackType)5)} / {Plugin.m_SessionHandler.GetSlotData().ChecksPerPack} Destiny Rare Pack Checks"; ((TMP_Text)epicText).text = $"{Plugin.m_SaveManager.GetSentChecks((ECollectionPackType)6)} / {Plugin.m_SessionHandler.GetSlotData().ChecksPerPack} Destiny Epic Pack Checks"; ((TMP_Text)legendaryText).text = $"{Plugin.m_SaveManager.GetSentChecks((ECollectionPackType)7)} / {Plugin.m_SessionHandler.GetSlotData().ChecksPerPack} Destiny Legendary Pack Checks"; } ((TMP_Text)sanityText).text = ""; } private static void SetCardUIAlpha(Card3dUIGroup cardUI, float alpha) { //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Expected O, but got Unknown //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Expected O, but got Unknown //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)cardUI == (Object)null) { return; } Image[] array = (Image[])(object)new Image[5] { cardUI.m_CardUI.m_CardBGImage, cardUI.m_CardUI.m_CardBorderImage, cardUI.m_CardUI.m_MonsterImage, cardUI.m_CardUI.m_MonsterMaskImage, cardUI.m_CardUI.m_RarityImage }; Material val = new Material(((Graphic)cardUI.m_CardUI.m_CardBackImage).material); val.SetColor("_Color", new Color(1f, 1f, 1f, 0f)); ((Graphic)cardUI.m_CardUI.m_CardBackImage).material = val; Image[] array2 = array; foreach (Image val2 in array2) { if (!((Object)(object)val2 == (Object)null)) { Material val3 = new Material(((Graphic)val2).material); val3.SetColor("_Color", new Color(1f, 1f, 1f, alpha)); ((Graphic)val2).material = val3; } } TextMeshProUGUI[] componentsInChildren = ((Component)cardUI.m_CardUI).GetComponentsInChildren<TextMeshProUGUI>(true); foreach (TextMeshProUGUI val4 in componentsInChildren) { Color color = ((Graphic)val4).color; color.a = 0.5f; color.r /= 2f; color.b /= 2f; color.g /= 2f; ((Graphic)val4).color = color; } ((Graphic)cardUI.m_CardCountText).color = Color.white; } private static void DisableInteractability(CardUI cardUI) { Image[] componentsInChildren = ((Component)cardUI).GetComponentsInChildren<Image>(true); foreach (Image val in componentsInChildren) { ((Graphic)val).raycastTarget = false; } TextMeshProUGUI[] componentsInChildren2 = ((Component)cardUI).GetComponentsInChildren<TextMeshProUGUI>(true); foreach (TextMeshProUGUI val2 in componentsInChildren2) { ((Graphic)val2).raycastTarget = false; } } } public class CardOpeningPatches { [HarmonyPatch(typeof(CardOpeningSequence), "GetPackContent")] private class Patch_TargetMethod { private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) { //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Expected O, but got Unknown //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Expected O, but got Unknown //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Expected O, but got Unknown //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Expected O, but got Unknown //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Expected O, but got Unknown //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Expected O, but got Unknown List<CodeInstruction> list = new List<CodeInstruction>(instructions); Dictionary<float, float> dictionary = new Dictionary<float, float> { { 5f, 0.45f }, { 20f, 0f }, { 8f, 0.12f }, { 4f, 0.26f }, { 1f, 0.29f }, { 0.25f, 0.5f } }; HashSet<float> hashSet = new HashSet<float>(); MethodInfo methodInfo = AccessTools.Method(typeof(Plugin), "getNumLuckItems", (Type[])null, (Type[])null); for (int i = 0; i < list.Count - 1; i++) { CodeInstruction val = list[i]; if (val.opcode == OpCodes.Ldc_R4 && dictionary.TryGetValue((float)val.operand, out var value)) { float item = (float)val.operand; if (!hashSet.Contains(item) && list[i + 1].opcode.Name.StartsWith("stloc")) { object operand = list[i + 1].operand; list.InsertRange(i + 2, (IEnumerable<CodeInstruction>)(object)new CodeInstruction[6] { new CodeInstruction(OpCodes.Ldloc, operand), new CodeInstruction(OpCodes.Call, (object)methodInfo), new CodeInstruction(OpCodes.Ldc_R4, (object)value), new CodeInstruction(OpCodes.Mul, (object)null), new CodeInstruction(OpCodes.Add, (object)null), new CodeInstruction(OpCodes.Stloc, operand) }); hashSet.Add(item); i += 6; } } } return list; } } } public class CustomerPatches { [HarmonyPatch(typeof(Customer), "EvaluateFinishScanItem")] public static class FinishScan { [HarmonyPostfix] public static void Postf
plugins/Archipelago.MultiClient.Net.dll
Decompiled 2 weeks 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.Globalization; using System.IO; using System.Linq; using System.Net.WebSockets; using System.Numerics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Serialization; using System.Runtime.Versioning; using System.Text; using System.Threading; using System.Threading.Tasks; using Archipelago.MultiClient.Net.Colors; using Archipelago.MultiClient.Net.ConcurrentCollection; using Archipelago.MultiClient.Net.Converters; using Archipelago.MultiClient.Net.DataPackage; using Archipelago.MultiClient.Net.Enums; using Archipelago.MultiClient.Net.Exceptions; using Archipelago.MultiClient.Net.Extensions; using Archipelago.MultiClient.Net.Helpers; using Archipelago.MultiClient.Net.MessageLog.Messages; using Archipelago.MultiClient.Net.MessageLog.Parts; using Archipelago.MultiClient.Net.Models; using Archipelago.MultiClient.Net.Packets; using Newtonsoft.Json; using Newtonsoft.Json.Converters; using Newtonsoft.Json.Linq; using Newtonsoft.Json.Serialization; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: ComVisible(false)] [assembly: Guid("35a803ad-85ed-42e9-b1e3-c6b72096f0c1")] [assembly: InternalsVisibleTo("Archipelago.MultiClient.Net.Tests")] [assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] [assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")] [assembly: AssemblyCompany("Jarno Westhof, Hussein Farran, Zach Parks")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyCopyright("Copyright © 2025")] [assembly: AssemblyDescription("A client library for use with .NET based prog-langs for interfacing with Archipelago hosts.")] [assembly: AssemblyFileVersion("6.6.0.0")] [assembly: AssemblyInformationalVersion("6.6.0+75d4c5e6a52bb0c8bb1d4bc368652613509c7acb")] [assembly: AssemblyProduct("Archipelago.MultiClient.Net")] [assembly: AssemblyTitle("Archipelago.MultiClient.Net")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/ArchipelagoMW/Archipelago.MultiClient.Net")] [assembly: AssemblyVersion("6.6.0.0")] internal interface IConcurrentHashSet<T> { bool TryAdd(T item); bool Contains(T item); void UnionWith(T[] otherSet); T[] ToArray(); ReadOnlyCollection<T> AsToReadOnlyCollection(); ReadOnlyCollection<T> AsToReadOnlyCollectionExcept(IConcurrentHashSet<T> otherSet); } namespace Archipelago.MultiClient.Net { [Serializable] public abstract class ArchipelagoPacketBase { [JsonIgnore] internal JObject jobject; [JsonProperty("cmd")] [JsonConverter(typeof(StringEnumConverter))] public abstract ArchipelagoPacketType PacketType { get; } public JObject ToJObject() { return jobject; } } public interface IArchipelagoSession : IArchipelagoSessionActions { IArchipelagoSocketHelper Socket { get; } IReceivedItemsHelper Items { get; } ILocationCheckHelper Locations { get; } IPlayerHelper Players { get; } IDataStorageHelper DataStorage { get; } IConnectionInfoProvider ConnectionInfo { get; } IRoomStateHelper RoomState { get; } IMessageLogHelper MessageLog { get; } Task<RoomInfoPacket> ConnectAsync(); Task<LoginResult> LoginAsync(string game, string name, ItemsHandlingFlags itemsHandlingFlags, Version version = null, string[] tags = null, string uuid = null, string password = null, bool requestSlotData = true); LoginResult TryConnectAndLogin(string game, string name, ItemsHandlingFlags itemsHandlingFlags, Version version = null, string[] tags = null, string uuid = null, string password = null, bool requestSlotData = true); } public class ArchipelagoSession : IArchipelagoSession, IArchipelagoSessionActions { private const int ArchipelagoConnectionTimeoutInSeconds = 4; private ConnectionInfoHelper connectionInfo; private TaskCompletionSource<LoginResult> loginResultTask = new TaskCompletionSource<LoginResult>(); private TaskCompletionSource<RoomInfoPacket> roomInfoPacketTask = new TaskCompletionSource<RoomInfoPacket>(); public IArchipelagoSocketHelper Socket { get; } public IReceivedItemsHelper Items { get; } public ILocationCheckHelper Locations { get; } public IPlayerHelper Players { get; } public IDataStorageHelper DataStorage { get; } public IConnectionInfoProvider ConnectionInfo => connectionInfo; public IRoomStateHelper RoomState { get; } public IMessageLogHelper MessageLog { get; } internal ArchipelagoSession(IArchipelagoSocketHelper socket, IReceivedItemsHelper items, ILocationCheckHelper locations, IPlayerHelper players, IRoomStateHelper roomState, ConnectionInfoHelper connectionInfoHelper, IDataStorageHelper dataStorage, IMessageLogHelper messageLog) { Socket = socket; Items = items; Locations = locations; Players = players; RoomState = roomState; connectionInfo = connectionInfoHelper; DataStorage = dataStorage; MessageLog = messageLog; socket.PacketReceived += Socket_PacketReceived; } private void Socket_PacketReceived(ArchipelagoPacketBase packet) { if (!(packet is ConnectedPacket) && !(packet is ConnectionRefusedPacket)) { if (packet is RoomInfoPacket result) { roomInfoPacketTask.TrySetResult(result); } return; } if (packet is ConnectedPacket && RoomState.Version != null && RoomState.Version >= new Version(0, 3, 8)) { LogUsedVersion(); } loginResultTask.TrySetResult(LoginResult.FromPacket(packet)); } private void LogUsedVersion() { try { string fileVersion = FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).FileVersion; Socket.SendPacketAsync(new SetPacket { Key = ".NetUsedVersions", DefaultValue = (JToken)(object)JObject.FromObject((object)new Dictionary<string, bool>()), Operations = new OperationSpecification[1] { Operation.Update(new Dictionary<string, bool> { { ConnectionInfo.Game + ":" + fileVersion + ":NETSTANDARD2_0", true } }) } }); } catch { } } public Task<RoomInfoPacket> ConnectAsync() { roomInfoPacketTask = new TaskCompletionSource<RoomInfoPacket>(); Task.Factory.StartNew(delegate { try { Task task = Socket.ConnectAsync(); task.Wait(TimeSpan.FromSeconds(4.0)); if (!task.IsCompleted) { roomInfoPacketTask.TrySetCanceled(); } } catch (AggregateException) { roomInfoPacketTask.TrySetCanceled(); } }); return roomInfoPacketTask.Task; } public Task<LoginResult> LoginAsync(string game, string name, ItemsHandlingFlags itemsHandlingFlags, Version version = null, string[] tags = null, string uuid = null, string password = null, bool requestSlotData = true) { loginResultTask = new TaskCompletionSource<LoginResult>(); if (!roomInfoPacketTask.Task.IsCompleted) { loginResultTask.TrySetResult(new LoginFailure("You are not connected, run ConnectAsync() first")); return loginResultTask.Task; } connectionInfo.SetConnectionParameters(game, tags, itemsHandlingFlags, uuid); try { Socket.SendPacket(BuildConnectPacket(name, password, version, requestSlotData)); } catch (ArchipelagoSocketClosedException) { loginResultTask.TrySetResult(new LoginFailure("You are not connected, run ConnectAsync() first")); return loginResultTask.Task; } SetResultAfterTimeout(loginResultTask, 4, new LoginFailure("Connection timed out.")); return loginResultTask.Task; } private static void SetResultAfterTimeout<T>(TaskCompletionSource<T> task, int timeoutInSeconds, T result) { new CancellationTokenSource(TimeSpan.FromSeconds(timeoutInSeconds)).Token.Register(delegate { task.TrySetResult(result); }); } public LoginResult TryConnectAndLogin(string game, string name, ItemsHandlingFlags itemsHandlingFlags, Version version = null, string[] tags = null, string uuid = null, string password = null, bool requestSlotData = true) { Task<RoomInfoPacket> task = ConnectAsync(); try { task.Wait(TimeSpan.FromSeconds(4.0)); } catch (AggregateException ex) { if (ex.GetBaseException() is OperationCanceledException) { return new LoginFailure("Connection timed out."); } return new LoginFailure(ex.GetBaseException().Message); } if (!task.IsCompleted) { return new LoginFailure("Connection timed out."); } return LoginAsync(game, name, itemsHandlingFlags, version, tags, uuid, password, requestSlotData).Result; } private ConnectPacket BuildConnectPacket(string name, string password, Version version, bool requestSlotData) { return new ConnectPacket { Game = ConnectionInfo.Game, Name = name, Password = password, Tags = ConnectionInfo.Tags, Uuid = ConnectionInfo.Uuid, Version = ((version != null) ? new NetworkVersion(version) : new NetworkVersion(0, 6, 0)), ItemsHandling = ConnectionInfo.ItemsHandlingFlags, RequestSlotData = requestSlotData }; } public void Say(string message) { Socket.SendPacket(new SayPacket { Text = message }); } public void SetClientState(ArchipelagoClientState state) { Socket.SendPacket(new StatusUpdatePacket { Status = state }); } public void SetGoalAchieved() { SetClientState(ArchipelagoClientState.ClientGoal); } } public interface IArchipelagoSessionActions { void Say(string message); void SetClientState(ArchipelagoClientState state); void SetGoalAchieved(); } public static class ArchipelagoSessionFactory { public static ArchipelagoSession CreateSession(Uri uri) { ArchipelagoSocketHelper socket = new ArchipelagoSocketHelper(uri); DataPackageCache cache = new DataPackageCache(socket); ConnectionInfoHelper connectionInfoHelper = new ConnectionInfoHelper(socket); PlayerHelper playerHelper = new PlayerHelper(socket, connectionInfoHelper); ItemInfoResolver itemInfoResolver = new ItemInfoResolver(cache, connectionInfoHelper); LocationCheckHelper locationCheckHelper = new LocationCheckHelper(socket, itemInfoResolver, connectionInfoHelper, playerHelper); ReceivedItemsHelper items = new ReceivedItemsHelper(socket, locationCheckHelper, itemInfoResolver, connectionInfoHelper, playerHelper); RoomStateHelper roomState = new RoomStateHelper(socket, locationCheckHelper); DataStorageHelper dataStorage = new DataStorageHelper(socket, connectionInfoHelper); MessageLogHelper messageLog = new MessageLogHelper(socket, itemInfoResolver, playerHelper, connectionInfoHelper); return new ArchipelagoSession(socket, items, locationCheckHelper, playerHelper, roomState, connectionInfoHelper, dataStorage, messageLog); } public static ArchipelagoSession CreateSession(string hostname, int port = 38281) { return CreateSession(ParseUri(hostname, port)); } internal static Uri ParseUri(string hostname, int port) { string text = hostname; if (!text.StartsWith("ws://") && !text.StartsWith("wss://")) { text = "unspecified://" + text; } if (!text.Substring(text.IndexOf("://", StringComparison.Ordinal) + 3).Contains(":")) { text += $":{port}"; } if (text.EndsWith(":")) { text += port; } return new Uri(text); } } public abstract class LoginResult { public abstract bool Successful { get; } public static LoginResult FromPacket(ArchipelagoPacketBase packet) { if (!(packet is ConnectedPacket connectedPacket)) { if (packet is ConnectionRefusedPacket connectionRefusedPacket) { return new LoginFailure(connectionRefusedPacket); } throw new ArgumentOutOfRangeException("packet", "packet is not a connection result packet"); } return new LoginSuccessful(connectedPacket); } } public class LoginSuccessful : LoginResult { public override bool Successful => true; public int Team { get; } public int Slot { get; } public Dictionary<string, object> SlotData { get; } public LoginSuccessful(ConnectedPacket connectedPacket) { Team = connectedPacket.Team; Slot = connectedPacket.Slot; SlotData = connectedPacket.SlotData; } } public class LoginFailure : LoginResult { public override bool Successful => false; public ConnectionRefusedError[] ErrorCodes { get; } public string[] Errors { get; } public LoginFailure(ConnectionRefusedPacket connectionRefusedPacket) { if (connectionRefusedPacket.Errors != null) { ErrorCodes = connectionRefusedPacket.Errors.ToArray(); Errors = ErrorCodes.Select(GetErrorMessage).ToArray(); } else { ErrorCodes = new ConnectionRefusedError[0]; Errors = new string[0]; } } public LoginFailure(string message) { ErrorCodes = new ConnectionRefusedError[0]; Errors = new string[1] { message }; } private static string GetErrorMessage(ConnectionRefusedError errorCode) { return errorCode switch { ConnectionRefusedError.InvalidSlot => "The slot name did not match any slot on the server.", ConnectionRefusedError.InvalidGame => "The slot is set to a different game on the server.", ConnectionRefusedError.SlotAlreadyTaken => "The slot already has a connection with a different uuid established.", ConnectionRefusedError.IncompatibleVersion => "The client and server version mismatch.", ConnectionRefusedError.InvalidPassword => "The password is invalid.", ConnectionRefusedError.InvalidItemsHandling => "The item handling flags provided are invalid.", _ => $"Unknown error: {errorCode}.", }; } } internal class TwoWayLookup<TA, TB> : IEnumerable<KeyValuePair<TB, TA>>, IEnumerable { private readonly Dictionary<TA, TB> aToB = new Dictionary<TA, TB>(); private readonly Dictionary<TB, TA> bToA = new Dictionary<TB, TA>(); public TA this[TB b] => bToA[b]; public TB this[TA a] => aToB[a]; public void Add(TA a, TB b) { aToB[a] = b; bToA[b] = a; } public void Add(TB b, TA a) { Add(a, b); } public bool TryGetValue(TA a, out TB b) { return aToB.TryGetValue(a, out b); } public bool TryGetValue(TB b, out TA a) { return bToA.TryGetValue(b, out a); } public IEnumerator<KeyValuePair<TB, TA>> GetEnumerator() { return bToA.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } } } namespace Archipelago.MultiClient.Net.Packets { public class BouncedPacket : BouncePacket { public override ArchipelagoPacketType PacketType => ArchipelagoPacketType.Bounced; } public class BouncePacket : ArchipelagoPacketBase { public override ArchipelagoPacketType PacketType => ArchipelagoPacketType.Bounce; [JsonProperty("games")] public List<string> Games { get; set; } = new List<string>(); [JsonProperty("slots")] public List<int> Slots { get; set; } = new List<int>(); [JsonProperty("tags")] public List<string> Tags { get; set; } = new List<string>(); [JsonProperty("data")] public Dictionary<string, JToken> Data { get; set; } } public class ConnectedPacket : ArchipelagoPacketBase { public override ArchipelagoPacketType PacketType => ArchipelagoPacketType.Connected; [JsonProperty("team")] public int Team { get; set; } [JsonProperty("slot")] public int Slot { get; set; } [JsonProperty("players")] public NetworkPlayer[] Players { get; set; } [JsonProperty("missing_locations")] public long[] MissingChecks { get; set; } [JsonProperty("checked_locations")] public long[] LocationsChecked { get; set; } [JsonProperty("slot_data")] public Dictionary<string, object> SlotData { get; set; } [JsonProperty("slot_info")] public Dictionary<int, NetworkSlot> SlotInfo { get; set; } [JsonProperty("hint_points")] public int? HintPoints { get; set; } } public class ConnectionRefusedPacket : ArchipelagoPacketBase { public override ArchipelagoPacketType PacketType => ArchipelagoPacketType.ConnectionRefused; [JsonProperty("errors", ItemConverterType = typeof(StringEnumConverter))] public ConnectionRefusedError[] Errors { get; set; } } public class ConnectPacket : ArchipelagoPacketBase { public override ArchipelagoPacketType PacketType => ArchipelagoPacketType.Connect; [JsonProperty("password")] public string Password { get; set; } [JsonProperty("game")] public string Game { get; set; } [JsonProperty("name")] public string Name { get; set; } [JsonProperty("uuid")] public string Uuid { get; set; } [JsonProperty("version")] public NetworkVersion Version { get; set; } [JsonProperty("tags")] public string[] Tags { get; set; } [JsonProperty("items_handling")] public ItemsHandlingFlags ItemsHandling { get; set; } [JsonProperty("slot_data")] public bool RequestSlotData { get; set; } } public class ConnectUpdatePacket : ArchipelagoPacketBase { public override ArchipelagoPacketType PacketType => ArchipelagoPacketType.ConnectUpdate; [JsonProperty("tags")] public string[] Tags { get; set; } [JsonProperty("items_handling")] public ItemsHandlingFlags? ItemsHandling { get; set; } } public class DataPackagePacket : ArchipelagoPacketBase { public override ArchipelagoPacketType PacketType => ArchipelagoPacketType.DataPackage; [JsonProperty("data")] public Archipelago.MultiClient.Net.Models.DataPackage DataPackage { get; set; } } public class GetDataPackagePacket : ArchipelagoPacketBase { public override ArchipelagoPacketType PacketType => ArchipelagoPacketType.GetDataPackage; [JsonProperty("games")] public string[] Games { get; set; } } public class GetPacket : ArchipelagoPacketBase { public override ArchipelagoPacketType PacketType => ArchipelagoPacketType.Get; [JsonProperty("keys")] public string[] Keys { get; set; } } public class InvalidPacketPacket : ArchipelagoPacketBase { public override ArchipelagoPacketType PacketType => ArchipelagoPacketType.InvalidPacket; [JsonProperty("type")] public InvalidPacketErrorType ErrorType { get; set; } [JsonProperty("text")] public string ErrorText { get; set; } [JsonProperty("original_cmd")] public ArchipelagoPacketType OriginalCmd { get; set; } } public class LocationChecksPacket : ArchipelagoPacketBase { public override ArchipelagoPacketType PacketType => ArchipelagoPacketType.LocationChecks; [JsonProperty("locations")] public long[] Locations { get; set; } } public class LocationInfoPacket : ArchipelagoPacketBase { public override ArchipelagoPacketType PacketType => ArchipelagoPacketType.LocationInfo; [JsonProperty("locations")] public NetworkItem[] Locations { get; set; } } public class LocationScoutsPacket : ArchipelagoPacketBase { public override ArchipelagoPacketType PacketType => ArchipelagoPacketType.LocationScouts; [JsonProperty("locations")] public long[] Locations { get; set; } [JsonProperty("create_as_hint")] public int CreateAsHint { get; set; } } public class PrintJsonPacket : ArchipelagoPacketBase { public override ArchipelagoPacketType PacketType => ArchipelagoPacketType.PrintJSON; [JsonProperty("data")] public JsonMessagePart[] Data { get; set; } [JsonProperty("type")] [JsonConverter(typeof(StringEnumConverter))] public JsonMessageType? MessageType { get; set; } } public class ItemPrintJsonPacket : PrintJsonPacket { [JsonProperty("receiving")] public int ReceivingPlayer { get; set; } [JsonProperty("item")] public NetworkItem Item { get; set; } } public class ItemCheatPrintJsonPacket : PrintJsonPacket { [JsonProperty("receiving")] public int ReceivingPlayer { get; set; } [JsonProperty("item")] public NetworkItem Item { get; set; } [JsonProperty("team")] public int Team { get; set; } } public class HintPrintJsonPacket : PrintJsonPacket { [JsonProperty("receiving")] public int ReceivingPlayer { get; set; } [JsonProperty("item")] public NetworkItem Item { get; set; } [JsonProperty("found")] public bool? Found { get; set; } } public class JoinPrintJsonPacket : PrintJsonPacket { [JsonProperty("team")] public int Team { get; set; } [JsonProperty("slot")] public int Slot { get; set; } [JsonProperty("tags")] public string[] Tags { get; set; } } public class LeavePrintJsonPacket : PrintJsonPacket { [JsonProperty("team")] public int Team { get; set; } [JsonProperty("slot")] public int Slot { get; set; } } public class ChatPrintJsonPacket : PrintJsonPacket { [JsonProperty("team")] public int Team { get; set; } [JsonProperty("slot")] public int Slot { get; set; } [JsonProperty("message")] public string Message { get; set; } } public class ServerChatPrintJsonPacket : PrintJsonPacket { [JsonProperty("message")] public string Message { get; set; } } public class TutorialPrintJsonPacket : PrintJsonPacket { } public class TagsChangedPrintJsonPacket : PrintJsonPacket { [JsonProperty("team")] public int Team { get; set; } [JsonProperty("slot")] public int Slot { get; set; } [JsonProperty("tags")] public string[] Tags { get; set; } } public class CommandResultPrintJsonPacket : PrintJsonPacket { } public class AdminCommandResultPrintJsonPacket : PrintJsonPacket { } public class GoalPrintJsonPacket : PrintJsonPacket { [JsonProperty("team")] public int Team { get; set; } [JsonProperty("slot")] public int Slot { get; set; } } public class ReleasePrintJsonPacket : PrintJsonPacket { [JsonProperty("team")] public int Team { get; set; } [JsonProperty("slot")] public int Slot { get; set; } } public class CollectPrintJsonPacket : PrintJsonPacket { [JsonProperty("team")] public int Team { get; set; } [JsonProperty("slot")] public int Slot { get; set; } } public class CountdownPrintJsonPacket : PrintJsonPacket { [JsonProperty("countdown")] public int RemainingSeconds { get; set; } } public class ReceivedItemsPacket : ArchipelagoPacketBase { public override ArchipelagoPacketType PacketType => ArchipelagoPacketType.ReceivedItems; [JsonProperty("index")] public int Index { get; set; } [JsonProperty("items")] public NetworkItem[] Items { get; set; } } public class RetrievedPacket : ArchipelagoPacketBase { public override ArchipelagoPacketType PacketType => ArchipelagoPacketType.Retrieved; [JsonProperty("keys")] public Dictionary<string, JToken> Data { get; set; } } public class RoomInfoPacket : ArchipelagoPacketBase { public override ArchipelagoPacketType PacketType => ArchipelagoPacketType.RoomInfo; [JsonProperty("version")] public NetworkVersion Version { get; set; } [JsonProperty("generator_version")] public NetworkVersion GeneratorVersion { get; set; } [JsonProperty("tags")] public string[] Tags { get; set; } [JsonProperty("password")] public bool Password { get; set; } [JsonProperty("permissions")] public Dictionary<string, Permissions> Permissions { get; set; } [JsonProperty("hint_cost")] public int HintCostPercentage { get; set; } [JsonProperty("location_check_points")] public int LocationCheckPoints { get; set; } [JsonProperty("players")] public NetworkPlayer[] Players { get; set; } [JsonProperty("games")] public string[] Games { get; set; } [JsonProperty("datapackage_checksums")] public Dictionary<string, string> DataPackageChecksums { get; set; } [JsonProperty("seed_name")] public string SeedName { get; set; } [JsonProperty("time")] public double Timestamp { get; set; } } public class RoomUpdatePacket : ArchipelagoPacketBase { public override ArchipelagoPacketType PacketType => ArchipelagoPacketType.RoomUpdate; [JsonProperty("tags")] public string[] Tags { get; set; } [JsonProperty("password")] public bool? Password { get; set; } [JsonProperty("permissions")] public Dictionary<string, Permissions> Permissions { get; set; } = new Dictionary<string, Permissions>(); [JsonProperty("hint_cost")] public int? HintCostPercentage { get; set; } [JsonProperty("location_check_points")] public int? LocationCheckPoints { get; set; } [JsonProperty("players")] public NetworkPlayer[] Players { get; set; } [JsonProperty("hint_points")] public int? HintPoints { get; set; } [JsonProperty("checked_locations")] public long[] CheckedLocations { get; set; } } public class SayPacket : ArchipelagoPacketBase { public override ArchipelagoPacketType PacketType => ArchipelagoPacketType.Say; [JsonProperty("text")] public string Text { get; set; } } public class SetNotifyPacket : ArchipelagoPacketBase { public override ArchipelagoPacketType PacketType => ArchipelagoPacketType.SetNotify; [JsonProperty("keys")] public string[] Keys { get; set; } } public class SetPacket : ArchipelagoPacketBase { public override ArchipelagoPacketType PacketType => ArchipelagoPacketType.Set; [JsonProperty("key")] public string Key { get; set; } [JsonProperty("default")] public JToken DefaultValue { get; set; } [JsonProperty("operations")] public OperationSpecification[] Operations { get; set; } [JsonProperty("want_reply")] public bool WantReply { get; set; } [JsonExtensionData] public Dictionary<string, JToken> AdditionalArguments { get; set; } [OnDeserialized] internal void OnDeserializedMethod(StreamingContext context) { AdditionalArguments?.Remove("cmd"); } } public class SetReplyPacket : SetPacket { public override ArchipelagoPacketType PacketType => ArchipelagoPacketType.SetReply; [JsonProperty("value")] public JToken Value { get; set; } [JsonProperty("original_value")] public JToken OriginalValue { get; set; } } public class StatusUpdatePacket : ArchipelagoPacketBase { public override ArchipelagoPacketType PacketType => ArchipelagoPacketType.StatusUpdate; [JsonProperty("status")] public ArchipelagoClientState Status { get; set; } } public class SyncPacket : ArchipelagoPacketBase { public override ArchipelagoPacketType PacketType => ArchipelagoPacketType.Sync; } internal class UnknownPacket : ArchipelagoPacketBase { public override ArchipelagoPacketType PacketType => ArchipelagoPacketType.Unknown; } public class UpdateHintPacket : ArchipelagoPacketBase { public override ArchipelagoPacketType PacketType => ArchipelagoPacketType.UpdateHint; [JsonProperty("player")] public int Player { get; set; } [JsonProperty("location")] public long Location { get; set; } [JsonProperty("status")] public HintStatus Status { get; set; } } } namespace Archipelago.MultiClient.Net.Models { public struct Color : IEquatable<Color> { public static Color Red = new Color(byte.MaxValue, 0, 0); public static Color Green = new Color(0, 128, 0); public static Color Yellow = new Color(byte.MaxValue, byte.MaxValue, 0); public static Color Blue = new Color(0, 0, byte.MaxValue); public static Color Magenta = new Color(byte.MaxValue, 0, byte.MaxValue); public static Color Cyan = new Color(0, byte.MaxValue, byte.MaxValue); public static Color Black = new Color(0, 0, 0); public static Color White = new Color(byte.MaxValue, byte.MaxValue, byte.MaxValue); public static Color SlateBlue = new Color(106, 90, 205); public static Color Salmon = new Color(250, 128, 114); public static Color Plum = new Color(221, 160, 221); public byte R { get; set; } public byte G { get; set; } public byte B { get; set; } public Color(byte r, byte g, byte b) { R = r; G = g; B = b; } public override bool Equals(object obj) { if (obj is Color color && R == color.R && G == color.G) { return B == color.B; } return false; } public bool Equals(Color other) { if (R == other.R && G == other.G) { return B == other.B; } return false; } public override int GetHashCode() { return ((-1520100960 * -1521134295 + R.GetHashCode()) * -1521134295 + G.GetHashCode()) * -1521134295 + B.GetHashCode(); } public static bool operator ==(Color left, Color right) { return left.Equals(right); } public static bool operator !=(Color left, Color right) { return !(left == right); } } public class DataPackage { [JsonProperty("games")] public Dictionary<string, GameData> Games { get; set; } = new Dictionary<string, GameData>(); } public class DataStorageElement { internal DataStorageElementContext Context; internal List<OperationSpecification> Operations = new List<OperationSpecification>(0); internal DataStorageHelper.DataStorageUpdatedHandler Callbacks; internal Dictionary<string, JToken> AdditionalArguments = new Dictionary<string, JToken>(0); private JToken cachedValue; public event DataStorageHelper.DataStorageUpdatedHandler OnValueChanged { add { Context.AddHandler(Context.Key, value); } remove { Context.RemoveHandler(Context.Key, value); } } internal DataStorageElement(DataStorageElementContext context) { Context = context; } internal DataStorageElement(OperationType operationType, JToken value) { Operations = new List<OperationSpecification>(1) { new OperationSpecification { OperationType = operationType, Value = value } }; } internal DataStorageElement(DataStorageElement source, OperationType operationType, JToken value) : this(source.Context) { Operations = source.Operations.ToList(); Callbacks = source.Callbacks; AdditionalArguments = source.AdditionalArguments; Operations.Add(new OperationSpecification { OperationType = operationType, Value = value }); } internal DataStorageElement(DataStorageElement source, Callback callback) : this(source.Context) { Operations = source.Operations.ToList(); Callbacks = source.Callbacks; AdditionalArguments = source.AdditionalArguments; Callbacks = (DataStorageHelper.DataStorageUpdatedHandler)Delegate.Combine(Callbacks, callback.Method); } internal DataStorageElement(DataStorageElement source, AdditionalArgument additionalArgument) : this(source.Context) { Operations = source.Operations.ToList(); Callbacks = source.Callbacks; AdditionalArguments = source.AdditionalArguments; AdditionalArguments[additionalArgument.Key] = additionalArgument.Value; } public static DataStorageElement operator ++(DataStorageElement a) { return new DataStorageElement(a, OperationType.Add, JToken.op_Implicit(1)); } public static DataStorageElement operator --(DataStorageElement a) { return new DataStorageElement(a, OperationType.Add, JToken.op_Implicit(-1)); } public static DataStorageElement operator +(DataStorageElement a, int b) { return new DataStorageElement(a, OperationType.Add, JToken.op_Implicit(b)); } public static DataStorageElement operator +(DataStorageElement a, long b) { return new DataStorageElement(a, OperationType.Add, JToken.op_Implicit(b)); } public static DataStorageElement operator +(DataStorageElement a, float b) { return new DataStorageElement(a, OperationType.Add, JToken.op_Implicit(b)); } public static DataStorageElement operator +(DataStorageElement a, double b) { return new DataStorageElement(a, OperationType.Add, JToken.op_Implicit(b)); } public static DataStorageElement operator +(DataStorageElement a, decimal b) { return new DataStorageElement(a, OperationType.Add, JToken.op_Implicit(b)); } public static DataStorageElement operator +(DataStorageElement a, string b) { return new DataStorageElement(a, OperationType.Add, JToken.op_Implicit(b)); } public static DataStorageElement operator +(DataStorageElement a, JToken b) { return new DataStorageElement(a, OperationType.Add, b); } public static DataStorageElement operator +(DataStorageElement a, IEnumerable b) { return new DataStorageElement(a, OperationType.Add, (JToken)(object)JArray.FromObject((object)b)); } public static DataStorageElement operator +(DataStorageElement a, OperationSpecification s) { return new DataStorageElement(a, s.OperationType, s.Value); } public static DataStorageElement operator +(DataStorageElement a, Callback c) { return new DataStorageElement(a, c); } public static DataStorageElement operator +(DataStorageElement a, AdditionalArgument arg) { return new DataStorageElement(a, arg); } public static DataStorageElement operator *(DataStorageElement a, int b) { return new DataStorageElement(a, OperationType.Mul, JToken.op_Implicit(b)); } public static DataStorageElement operator *(DataStorageElement a, long b) { return new DataStorageElement(a, OperationType.Mul, JToken.op_Implicit(b)); } public static DataStorageElement operator *(DataStorageElement a, float b) { return new DataStorageElement(a, OperationType.Mul, JToken.op_Implicit(b)); } public static DataStorageElement operator *(DataStorageElement a, double b) { return new DataStorageElement(a, OperationType.Mul, JToken.op_Implicit(b)); } public static DataStorageElement operator *(DataStorageElement a, decimal b) { return new DataStorageElement(a, OperationType.Mul, JToken.op_Implicit(b)); } public static DataStorageElement operator %(DataStorageElement a, int b) { return new DataStorageElement(a, OperationType.Mod, JToken.op_Implicit(b)); } public static DataStorageElement operator %(DataStorageElement a, long b) { return new DataStorageElement(a, OperationType.Mod, JToken.op_Implicit(b)); } public static DataStorageElement operator %(DataStorageElement a, float b) { return new DataStorageElement(a, OperationType.Mod, JToken.op_Implicit(b)); } public static DataStorageElement operator %(DataStorageElement a, double b) { return new DataStorageElement(a, OperationType.Mod, JToken.op_Implicit(b)); } public static DataStorageElement operator %(DataStorageElement a, decimal b) { return new DataStorageElement(a, OperationType.Mod, JToken.op_Implicit(b)); } public static DataStorageElement operator ^(DataStorageElement a, int b) { return new DataStorageElement(a, OperationType.Pow, JToken.op_Implicit(b)); } public static DataStorageElement operator ^(DataStorageElement a, long b) { return new DataStorageElement(a, OperationType.Pow, JToken.op_Implicit(b)); } public static DataStorageElement operator ^(DataStorageElement a, float b) { return new DataStorageElement(a, OperationType.Pow, JToken.op_Implicit(b)); } public static DataStorageElement operator ^(DataStorageElement a, double b) { return new DataStorageElement(a, OperationType.Pow, JToken.op_Implicit(b)); } public static DataStorageElement operator ^(DataStorageElement a, decimal b) { return new DataStorageElement(a, OperationType.Pow, JToken.op_Implicit(b)); } public static DataStorageElement operator -(DataStorageElement a, int b) { return new DataStorageElement(a, OperationType.Add, JToken.FromObject((object)(-b))); } public static DataStorageElement operator -(DataStorageElement a, long b) { return new DataStorageElement(a, OperationType.Add, JToken.FromObject((object)(-b))); } public static DataStorageElement operator -(DataStorageElement a, float b) { return new DataStorageElement(a, OperationType.Add, JToken.FromObject((object)(0f - b))); } public static DataStorageElement operator -(DataStorageElement a, double b) { return new DataStorageElement(a, OperationType.Add, JToken.FromObject((object)(0.0 - b))); } public static DataStorageElement operator -(DataStorageElement a, decimal b) { return new DataStorageElement(a, OperationType.Add, JToken.FromObject((object)(-b))); } public static DataStorageElement operator /(DataStorageElement a, int b) { return new DataStorageElement(a, OperationType.Mul, JToken.FromObject((object)(1m / (decimal)b))); } public static DataStorageElement operator /(DataStorageElement a, long b) { return new DataStorageElement(a, OperationType.Mul, JToken.FromObject((object)(1m / (decimal)b))); } public static DataStorageElement operator /(DataStorageElement a, float b) { return new DataStorageElement(a, OperationType.Mul, JToken.FromObject((object)(1.0 / (double)b))); } public static DataStorageElement operator /(DataStorageElement a, double b) { return new DataStorageElement(a, OperationType.Mul, JToken.FromObject((object)(1.0 / b))); } public static DataStorageElement operator /(DataStorageElement a, decimal b) { return new DataStorageElement(a, OperationType.Mul, JToken.FromObject((object)(1m / b))); } public static implicit operator DataStorageElement(bool b) { return new DataStorageElement(OperationType.Replace, JToken.op_Implicit(b)); } public static implicit operator DataStorageElement(int i) { return new DataStorageElement(OperationType.Replace, JToken.op_Implicit(i)); } public static implicit operator DataStorageElement(long l) { return new DataStorageElement(OperationType.Replace, JToken.op_Implicit(l)); } public static implicit operator DataStorageElement(decimal m) { return new DataStorageElement(OperationType.Replace, JToken.op_Implicit(m)); } public static implicit operator DataStorageElement(double d) { return new DataStorageElement(OperationType.Replace, JToken.op_Implicit(d)); } public static implicit operator DataStorageElement(float f) { return new DataStorageElement(OperationType.Replace, JToken.op_Implicit(f)); } public static implicit operator DataStorageElement(string s) { if (s != null) { return new DataStorageElement(OperationType.Replace, JToken.op_Implicit(s)); } return new DataStorageElement(OperationType.Replace, (JToken)(object)JValue.CreateNull()); } public static implicit operator DataStorageElement(JToken o) { return new DataStorageElement(OperationType.Replace, o); } public static implicit operator DataStorageElement(Array a) { return new DataStorageElement(OperationType.Replace, (JToken)(object)JArray.FromObject((object)a)); } public static implicit operator DataStorageElement(List<bool> l) { return new DataStorageElement(OperationType.Replace, (JToken)(object)JArray.FromObject((object)l)); } public static implicit operator DataStorageElement(List<int> l) { return new DataStorageElement(OperationType.Replace, (JToken)(object)JArray.FromObject((object)l)); } public static implicit operator DataStorageElement(List<long> l) { return new DataStorageElement(OperationType.Replace, (JToken)(object)JArray.FromObject((object)l)); } public static implicit operator DataStorageElement(List<decimal> l) { return new DataStorageElement(OperationType.Replace, (JToken)(object)JArray.FromObject((object)l)); } public static implicit operator DataStorageElement(List<double> l) { return new DataStorageElement(OperationType.Replace, (JToken)(object)JArray.FromObject((object)l)); } public static implicit operator DataStorageElement(List<float> l) { return new DataStorageElement(OperationType.Replace, (JToken)(object)JArray.FromObject((object)l)); } public static implicit operator DataStorageElement(List<string> l) { return new DataStorageElement(OperationType.Replace, (JToken)(object)JArray.FromObject((object)l)); } public static implicit operator DataStorageElement(List<object> l) { return new DataStorageElement(OperationType.Replace, (JToken)(object)JArray.FromObject((object)l)); } public static implicit operator bool(DataStorageElement e) { return RetrieveAndReturnBoolValue<bool>(e); } public static implicit operator bool?(DataStorageElement e) { return RetrieveAndReturnBoolValue<bool?>(e); } public static implicit operator int(DataStorageElement e) { return RetrieveAndReturnDecimalValue<int>(e); } public static implicit operator int?(DataStorageElement e) { return RetrieveAndReturnDecimalValue<int?>(e); } public static implicit operator long(DataStorageElement e) { return RetrieveAndReturnDecimalValue<long>(e); } public static implicit operator long?(DataStorageElement e) { return RetrieveAndReturnDecimalValue<long?>(e); } public static implicit operator float(DataStorageElement e) { return RetrieveAndReturnDecimalValue<float>(e); } public static implicit operator float?(DataStorageElement e) { return RetrieveAndReturnDecimalValue<float?>(e); } public static implicit operator double(DataStorageElement e) { return RetrieveAndReturnDecimalValue<double>(e); } public static implicit operator double?(DataStorageElement e) { return RetrieveAndReturnDecimalValue<double?>(e); } public static implicit operator decimal(DataStorageElement e) { return RetrieveAndReturnDecimalValue<decimal>(e); } public static implicit operator decimal?(DataStorageElement e) { return RetrieveAndReturnDecimalValue<decimal?>(e); } public static implicit operator string(DataStorageElement e) { return RetrieveAndReturnStringValue(e); } public static implicit operator bool[](DataStorageElement e) { return RetrieveAndReturnArrayValue<bool[]>(e); } public static implicit operator int[](DataStorageElement e) { return RetrieveAndReturnArrayValue<int[]>(e); } public static implicit operator long[](DataStorageElement e) { return RetrieveAndReturnArrayValue<long[]>(e); } public static implicit operator decimal[](DataStorageElement e) { return RetrieveAndReturnArrayValue<decimal[]>(e); } public static implicit operator double[](DataStorageElement e) { return RetrieveAndReturnArrayValue<double[]>(e); } public static implicit operator float[](DataStorageElement e) { return RetrieveAndReturnArrayValue<float[]>(e); } public static implicit operator string[](DataStorageElement e) { return RetrieveAndReturnArrayValue<string[]>(e); } public static implicit operator object[](DataStorageElement e) { return RetrieveAndReturnArrayValue<object[]>(e); } public static implicit operator List<bool>(DataStorageElement e) { return RetrieveAndReturnArrayValue<List<bool>>(e); } public static implicit operator List<int>(DataStorageElement e) { return RetrieveAndReturnArrayValue<List<int>>(e); } public static implicit operator List<long>(DataStorageElement e) { return RetrieveAndReturnArrayValue<List<long>>(e); } public static implicit operator List<decimal>(DataStorageElement e) { return RetrieveAndReturnArrayValue<List<decimal>>(e); } public static implicit operator List<double>(DataStorageElement e) { return RetrieveAndReturnArrayValue<List<double>>(e); } public static implicit operator List<float>(DataStorageElement e) { return RetrieveAndReturnArrayValue<List<float>>(e); } public static implicit operator List<string>(DataStorageElement e) { return RetrieveAndReturnArrayValue<List<string>>(e); } public static implicit operator List<object>(DataStorageElement e) { return RetrieveAndReturnArrayValue<List<object>>(e); } public static implicit operator Array(DataStorageElement e) { return RetrieveAndReturnArrayValue<Array>(e); } public static implicit operator JArray(DataStorageElement e) { return RetrieveAndReturnArrayValue<JArray>(e); } public static implicit operator JToken(DataStorageElement e) { return e.Context.GetData(e.Context.Key); } public static DataStorageElement operator +(DataStorageElement a, BigInteger b) { return new DataStorageElement(a, OperationType.Add, JToken.Parse(b.ToString())); } public static DataStorageElement operator *(DataStorageElement a, BigInteger b) { return new DataStorageElement(a, OperationType.Mul, JToken.Parse(b.ToString())); } public static DataStorageElement operator %(DataStorageElement a, BigInteger b) { return new DataStorageElement(a, OperationType.Mod, JToken.Parse(b.ToString())); } public static DataStorageElement operator ^(DataStorageElement a, BigInteger b) { return new DataStorageElement(a, OperationType.Pow, JToken.Parse(b.ToString())); } public static DataStorageElement operator -(DataStorageElement a, BigInteger b) { return new DataStorageElement(a, OperationType.Add, JToken.Parse((-b).ToString())); } public static DataStorageElement operator /(DataStorageElement a, BigInteger b) { throw new InvalidOperationException("DataStorage[Key] / BigInterger is not supported, due to loss of precision when using integer division"); } public static implicit operator DataStorageElement(BigInteger bi) { return new DataStorageElement(OperationType.Replace, JToken.Parse(bi.ToString())); } public static implicit operator BigInteger(DataStorageElement e) { return RetrieveAndReturnBigIntegerValue<BigInteger>(e); } public static implicit operator BigInteger?(DataStorageElement e) { return RetrieveAndReturnBigIntegerValue<BigInteger?>(e); } private static T RetrieveAndReturnBigIntegerValue<T>(DataStorageElement e) { if (e.cachedValue != null) { if (!BigInteger.TryParse(((object)e.cachedValue).ToString(), out var result)) { return default(T); } return (T)Convert.ChangeType(result, IsNullable<T>() ? Nullable.GetUnderlyingType(typeof(T)) : typeof(T)); } BigInteger result2; BigInteger? bigInteger = (BigInteger.TryParse(((object)e.Context.GetData(e.Context.Key)).ToString(), out result2) ? new BigInteger?(result2) : null); if (!bigInteger.HasValue && !IsNullable<T>()) { bigInteger = Activator.CreateInstance<BigInteger>(); } foreach (OperationSpecification operation in e.Operations) { if (operation.OperationType == OperationType.Floor || operation.OperationType == OperationType.Ceil) { continue; } if (!BigInteger.TryParse(((object)operation.Value).ToString(), NumberStyles.AllowLeadingSign, null, out var result3)) { throw new InvalidOperationException($"DataStorage[Key] cannot be converted to BigInterger as its value its not an integer number, value: {operation.Value}"); } switch (operation.OperationType) { case OperationType.Replace: bigInteger = result3; break; case OperationType.Add: bigInteger += result3; break; case OperationType.Mul: bigInteger *= result3; break; case OperationType.Mod: bigInteger %= result3; break; case OperationType.Pow: bigInteger = BigInteger.Pow(bigInteger.Value, (int)operation.Value); break; case OperationType.Max: { BigInteger value = result3; BigInteger? bigInteger2 = bigInteger; if (value > bigInteger2) { bigInteger = result3; } break; } case OperationType.Min: { BigInteger value = result3; BigInteger? bigInteger2 = bigInteger; if (value < bigInteger2) { bigInteger = result3; } break; } case OperationType.Xor: bigInteger ^= result3; break; case OperationType.Or: bigInteger |= result3; break; case OperationType.And: bigInteger &= result3; break; case OperationType.LeftShift: bigInteger <<= (int)operation.Value; break; case OperationType.RightShift: bigInteger >>= (int)operation.Value; break; } } e.cachedValue = JToken.Parse(bigInteger.ToString()); if (!bigInteger.HasValue) { return default(T); } return (T)Convert.ChangeType(bigInteger.Value, IsNullable<T>() ? Nullable.GetUnderlyingType(typeof(T)) : typeof(T)); } public void Initialize(JToken value) { Context.Initialize(Context.Key, value); } public void Initialize(IEnumerable value) { Context.Initialize(Context.Key, (JToken)(object)JArray.FromObject((object)value)); } public Task<T> GetAsync<T>() { return GetAsync().ContinueWith((Task<JToken> r) => r.Result.ToObject<T>()); } public Task<JToken> GetAsync() { return Context.GetAsync(Context.Key); } private static T RetrieveAndReturnArrayValue<T>(DataStorageElement e) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Invalid comparison between Unknown and I4 //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Invalid comparison between Unknown and I4 //IL_00d7: Unknown result type (might be due to invalid IL or missing references) if (e.cachedValue != null) { return ((JToken)(JArray)e.cachedValue).ToObject<T>(); } JArray val = (JArray)(((object)e.Context.GetData(e.Context.Key).ToObject<JArray>()) ?? ((object)new JArray())); foreach (OperationSpecification operation in e.Operations) { switch (operation.OperationType) { case OperationType.Add: if ((int)operation.Value.Type != 2) { throw new InvalidOperationException($"Cannot perform operation {OperationType.Add} on Array value, with a non Array value: {operation.Value}"); } ((JContainer)val).Merge((object)operation.Value); break; case OperationType.Replace: if ((int)operation.Value.Type != 2) { throw new InvalidOperationException($"Cannot replace Array value, with a non Array value: {operation.Value}"); } val = (JArray)(((object)operation.Value.ToObject<JArray>()) ?? ((object)new JArray())); break; default: throw new InvalidOperationException($"Cannot perform operation {operation.OperationType} on Array value"); } } e.cachedValue = (JToken)(object)val; return ((JToken)val).ToObject<T>(); } private static string RetrieveAndReturnStringValue(DataStorageElement e) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Invalid comparison between Unknown and I4 //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Invalid comparison between Unknown and I4 if (e.cachedValue != null) { return (string)e.cachedValue; } JToken val = e.Context.GetData(e.Context.Key); string text = (((int)val.Type == 10) ? null : ((object)val).ToString()); foreach (OperationSpecification operation in e.Operations) { switch (operation.OperationType) { case OperationType.Add: text += (string)operation.Value; break; case OperationType.Mul: if ((int)operation.Value.Type != 6) { throw new InvalidOperationException($"Cannot perform operation {OperationType.Mul} on string value, with a non interger value: {operation.Value}"); } text = string.Concat(Enumerable.Repeat(text, (int)operation.Value)); break; case OperationType.Replace: text = (string)operation.Value; break; default: throw new InvalidOperationException($"Cannot perform operation {operation.OperationType} on string value"); } } if (text == null) { e.cachedValue = (JToken)(object)JValue.CreateNull(); } else { e.cachedValue = JToken.op_Implicit(text); } return (string)e.cachedValue; } private static T RetrieveAndReturnBoolValue<T>(DataStorageElement e) { if (e.cachedValue != null) { return e.cachedValue.ToObject<T>(); } bool? flag = e.Context.GetData(e.Context.Key).ToObject<bool?>() ?? ((bool?)Activator.CreateInstance(typeof(T))); foreach (OperationSpecification operation in e.Operations) { if (operation.OperationType == OperationType.Replace) { flag = (bool?)operation.Value; continue; } throw new InvalidOperationException($"Cannot perform operation {operation.OperationType} on boolean value"); } e.cachedValue = JToken.op_Implicit(flag); if (!flag.HasValue) { return default(T); } return (T)Convert.ChangeType(flag.Value, IsNullable<T>() ? Nullable.GetUnderlyingType(typeof(T)) : typeof(T)); } private static T RetrieveAndReturnDecimalValue<T>(DataStorageElement e) { if (e.cachedValue != null) { return e.cachedValue.ToObject<T>(); } decimal? num = e.Context.GetData(e.Context.Key).ToObject<decimal?>(); if (!num.HasValue && !IsNullable<T>()) { num = Activator.CreateInstance<decimal>(); } foreach (OperationSpecification operation in e.Operations) { switch (operation.OperationType) { case OperationType.Replace: num = (decimal)operation.Value; break; case OperationType.Add: num += (decimal?)(decimal)operation.Value; break; case OperationType.Mul: num *= (decimal?)(decimal)operation.Value; break; case OperationType.Mod: num %= (decimal?)(decimal)operation.Value; break; case OperationType.Pow: num = (decimal)Math.Pow((double)num.Value, (double)operation.Value); break; case OperationType.Max: num = Math.Max(num.Value, (decimal)operation.Value); break; case OperationType.Min: num = Math.Min(num.Value, (decimal)operation.Value); break; case OperationType.Xor: num = (long)num.Value ^ (long)operation.Value; break; case OperationType.Or: num = (long)num.Value | (long)operation.Value; break; case OperationType.And: num = (long)num.Value & (long)operation.Value; break; case OperationType.LeftShift: num = (long)num.Value << (int)operation.Value; break; case OperationType.RightShift: num = (long)num.Value >> (int)operation.Value; break; case OperationType.Floor: num = Math.Floor(num.Value); break; case OperationType.Ceil: num = Math.Ceiling(num.Value); break; } } e.cachedValue = JToken.op_Implicit(num); if (!num.HasValue) { return default(T); } return (T)Convert.ChangeType(num.Value, IsNullable<T>() ? Nullable.GetUnderlyingType(typeof(T)) : typeof(T)); } private static bool IsNullable<T>() { if (typeof(T).IsGenericType) { return typeof(T).GetGenericTypeDefinition() == typeof(Nullable<>).GetGenericTypeDefinition(); } return false; } public T To<T>() { if (Operations.Count != 0) { throw new InvalidOperationException("DataStorageElement.To<T>() cannot be used together with other operations on the DataStorageElement"); } return Context.GetData(Context.Key).ToObject<T>(); } public override string ToString() { return (Context?.ToString() ?? "(null)") + ", (" + ListOperations() + ")"; } private string ListOperations() { if (Operations != null) { return string.Join(", ", Operations.Select((OperationSpecification o) => o.ToString()).ToArray()); } return "none"; } } internal class DataStorageElementContext { internal string Key { get; set; } internal Action<string, DataStorageHelper.DataStorageUpdatedHandler> AddHandler { get; set; } internal Action<string, DataStorageHelper.DataStorageUpdatedHandler> RemoveHandler { get; set; } internal Func<string, JToken> GetData { get; set; } internal Action<string, JToken> Initialize { get; set; } internal Func<string, Task<JToken>> GetAsync { get; set; } public override string ToString() { return "Key: " + Key; } } public class GameData { [JsonProperty("location_name_to_id")] public Dictionary<string, long> LocationLookup { get; set; } = new Dictionary<string, long>(); [JsonProperty("item_name_to_id")] public Dictionary<string, long> ItemLookup { get; set; } = new Dictionary<string, long>(); [Obsolete("use Checksum instead")] [JsonProperty("version")] public int Version { get; set; } [JsonProperty("checksum")] public string Checksum { get; set; } } public class Hint { [JsonProperty("receiving_player")] public int ReceivingPlayer { get; set; } [JsonProperty("finding_player")] public int FindingPlayer { get; set; } [JsonProperty("item")] public long ItemId { get; set; } [JsonProperty("location")] public long LocationId { get; set; } [JsonProperty("item_flags")] public ItemFlags ItemFlags { get; set; } [JsonProperty("found")] public bool Found { get; set; } [JsonProperty("entrance")] public string Entrance { get; set; } [JsonProperty("status")] public HintStatus Status { get; set; } } public class ItemInfo { private readonly IItemInfoResolver itemInfoResolver; public long ItemId { get; } public long LocationId { get; } public PlayerInfo Player { get; } public ItemFlags Flags { get; } public string ItemName => itemInfoResolver.GetItemName(ItemId, ItemGame); public string ItemDisplayName => ItemName ?? $"Item: {ItemId}"; public string LocationName => itemInfoResolver.GetLocationName(LocationId, LocationGame); public string LocationDisplayName => LocationName ?? $"Location: {LocationId}"; public string ItemGame { get; } public string LocationGame { get; } public ItemInfo(NetworkItem item, string receiverGame, string senderGame, IItemInfoResolver itemInfoResolver, PlayerInfo player) { this.itemInfoResolver = itemInfoResolver; ItemGame = receiverGame; LocationGame = senderGame; ItemId = item.Item; LocationId = item.Location; Flags = item.Flags; Player = player; } public SerializableItemInfo ToSerializable() { return new SerializableItemInfo { IsScout = (GetType() == typeof(ScoutedItemInfo)), ItemId = ItemId, LocationId = LocationId, PlayerSlot = Player, Player = Player, Flags = Flags, ItemGame = ItemGame, ItemName = ItemName, LocationGame = LocationGame, LocationName = LocationName }; } } public class ScoutedItemInfo : ItemInfo { public new PlayerInfo Player => base.Player; public bool IsReceiverRelatedToActivePlayer { get; } public ScoutedItemInfo(NetworkItem item, string receiverGame, string senderGame, IItemInfoResolver itemInfoResolver, IPlayerHelper players, PlayerInfo player) : base(item, receiverGame, senderGame, itemInfoResolver, player) { IsReceiverRelatedToActivePlayer = (players.ActivePlayer ?? new PlayerInfo()).IsRelatedTo(player); } } public class JsonMessagePart { [JsonProperty("type")] [JsonConverter(typeof(StringEnumConverter), new object[] { typeof(SnakeCaseNamingStrategy) })] public JsonMessagePartType? Type { get; set; } [JsonProperty("color")] [JsonConverter(typeof(StringEnumConverter), new object[] { typeof(SnakeCaseNamingStrategy) })] public JsonMessagePartColor? Color { get; set; } [JsonProperty("text")] public string Text { get; set; } [JsonProperty("player")] public int? Player { get; set; } [JsonProperty("flags")] public ItemFlags? Flags { get; set; } [JsonProperty("hint_status")] public HintStatus? HintStatus { get; set; } } public struct NetworkItem { [JsonProperty("item")] public long Item { get; set; } [JsonProperty("location")] public long Location { get; set; } [JsonProperty("player")] public int Player { get; set; } [JsonProperty("flags")] public ItemFlags Flags { get; set; } } public struct NetworkPlayer { [JsonProperty("team")] public int Team { get; set; } [JsonProperty("slot")] public int Slot { get; set; } [JsonProperty("alias")] public string Alias { get; set; } [JsonProperty("name")] public string Name { get; set; } } public struct NetworkSlot { [JsonProperty("name")] public string Name { get; set; } [JsonProperty("game")] public string Game { get; set; } [JsonProperty("type")] public SlotType Type { get; set; } [JsonProperty("group_members")] public int[] GroupMembers { get; set; } } public class NetworkVersion { [JsonProperty("major")] public int Major { get; set; } [JsonProperty("minor")] public int Minor { get; set; } [JsonProperty("build")] public int Build { get; set; } [JsonProperty("class")] public string Class => "Version"; public NetworkVersion() { } public NetworkVersion(int major, int minor, int build) { Major = major; Minor = minor; Build = build; } public NetworkVersion(Version version) { Major = version.Major; Minor = version.Minor; Build = version.Build; } public Version ToVersion() { return new Version(Major, Minor, Build); } } public class OperationSpecification { [JsonProperty("operation")] [JsonConverter(typeof(StringEnumConverter), new object[] { typeof(SnakeCaseNamingStrategy) })] public OperationType OperationType; [JsonProperty("value")] public JToken Value { get; set; } public override string ToString() { return $"{OperationType}: {Value}"; } } public static class Operation { public static OperationSpecification Min(int i) { return new OperationSpecification { OperationType = OperationType.Min, Value = JToken.op_Implicit(i) }; } public static OperationSpecification Min(long i) { return new OperationSpecification { OperationType = OperationType.Min, Value = JToken.op_Implicit(i) }; } public static OperationSpecification Min(float i) { return new OperationSpecification { OperationType = OperationType.Min, Value = JToken.op_Implicit(i) }; } public static OperationSpecification Min(double i) { return new OperationSpecification { OperationType = OperationType.Min, Value = JToken.op_Implicit(i) }; } public static OperationSpecification Min(decimal i) { return new OperationSpecification { OperationType = OperationType.Min, Value = JToken.op_Implicit(i) }; } public static OperationSpecification Min(JToken i) { return new OperationSpecification { OperationType = OperationType.Min, Value = i }; } public static OperationSpecification Min(BigInteger i) { return new OperationSpecification { OperationType = OperationType.Min, Value = JToken.Parse(i.ToString()) }; } public static OperationSpecification Max(int i) { return new OperationSpecification { OperationType = OperationType.Max, Value = JToken.op_Implicit(i) }; } public static OperationSpecification Max(long i) { return new OperationSpecification { OperationType = OperationType.Max, Value = JToken.op_Implicit(i) }; } public static OperationSpecification Max(float i) { return new OperationSpecification { OperationType = OperationType.Max, Value = JToken.op_Implicit(i) }; } public static OperationSpecification Max(double i) { return new OperationSpecification { OperationType = OperationType.Max, Value = JToken.op_Implicit(i) }; } public static OperationSpecification Max(decimal i) { return new OperationSpecification { OperationType = OperationType.Max, Value = JToken.op_Implicit(i) }; } public static OperationSpecification Max(JToken i) { return new OperationSpecification { OperationType = OperationType.Max, Value = i }; } public static OperationSpecification Max(BigInteger i) { return new OperationSpecification { OperationType = OperationType.Max, Value = JToken.Parse(i.ToString()) }; } public static OperationSpecification Remove(JToken value) { return new OperationSpecification { OperationType = OperationType.Remove, Value = value }; } public static OperationSpecification Pop(int value) { return new OperationSpecification { OperationType = OperationType.Pop, Value = JToken.op_Implicit(value) }; } public static OperationSpecification Pop(JToken value) { return new OperationSpecification { OperationType = OperationType.Pop, Value = value }; } public static OperationSpecification Update(IDictionary dictionary) { return new OperationSpecification { OperationType = OperationType.Update, Value = (JToken)(object)JObject.FromObject((object)dictionary) }; } public static OperationSpecification Floor() { return new OperationSpecification { OperationType = OperationType.Floor, Value = null }; } public static OperationSpecification Ceiling() { return new OperationSpecification { OperationType = OperationType.Ceil, Value = null }; } } public static class Bitwise { public static OperationSpecification Xor(long i) { return new OperationSpecification { OperationType = OperationType.Xor, Value = JToken.op_Implicit(i) }; } public static OperationSpecification Xor(BigInteger i) { return new OperationSpecification { OperationType = OperationType.Xor, Value = JToken.Parse(i.ToString()) }; } public static OperationSpecification Or(long i) { return new OperationSpecification { OperationType = OperationType.Or, Value = JToken.op_Implicit(i) }; } public static OperationSpecification Or(BigInteger i) { return new OperationSpecification { OperationType = OperationType.Or, Value = JToken.Parse(i.ToString()) }; } public static OperationSpecification And(long i) { return new OperationSpecification { OperationType = OperationType.And, Value = JToken.op_Implicit(i) }; } public static OperationSpecification And(BigInteger i) { return new OperationSpecification { OperationType = OperationType.And, Value = JToken.Parse(i.ToString()) }; } public static OperationSpecification LeftShift(long i) { return new OperationSpecification { OperationType = OperationType.LeftShift, Value = JToken.op_Implicit(i) }; } public static OperationSpecification RightShift(long i) { return new OperationSpecification { OperationType = OperationType.RightShift, Value = JToken.op_Implicit(i) }; } } public class Callback { internal DataStorageHelper.DataStorageUpdatedHandler Method { get; set; } private Callback() { } public static Callback Add(DataStorageHelper.DataStorageUpdatedHandler callback) { return new Callback { Method = callback }; } } public class AdditionalArgument { internal string Key { get; set; } internal JToken Value { get; set; } private AdditionalArgument() { } public static AdditionalArgument Add(string name, JToken value) { return new AdditionalArgument { Key = name, Value = value }; } } public class MinimalSerializableItemInfo { public long ItemId { get; set; } public long LocationId { get; set; } public int PlayerSlot { get; set; } public ItemFlags Flags { get; set; } public string ItemGame { get; set; } public string LocationGame { get; set; } } public class SerializableItemInfo : MinimalSerializableItemInfo { public bool IsScout { get; set; } public PlayerInfo Player { get; set; } public string ItemName { get; set; } public string LocationName { get; set; } [JsonIgnore] public string ItemDisplayName => ItemName ?? $"Item: {base.ItemId}"; [JsonIgnore] public string LocationDisplayName => LocationName ?? $"Location: {base.LocationId}"; public string ToJson(bool full = false) { //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Expected O, but got Unknown MinimalSerializableItemInfo minimalSerializableItemInfo = this; if (!full) { minimalSerializableItemInfo = new MinimalSerializableItemInfo { ItemId = base.ItemId, LocationId = base.LocationId, PlayerSlot = base.PlayerSlot, Flags = base.Flags }; if (IsScout) { minimalSerializableItemInfo.ItemGame = base.ItemGame; } else { minimalSerializableItemInfo.LocationGame = base.LocationGame; } } JsonSerializerSettings val = new JsonSerializerSettings { NullValueHandling = (NullValueHandling)1, Formatting = (Formatting)0 }; return JsonConvert.SerializeObject((object)minimalSerializableItemInfo, val); } public static SerializableItemInfo FromJson(string json, IArchipelagoSession session = null) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Expected O, but got Unknown ItemInfoStreamingContext additional = ((session != null) ? new ItemInfoStreamingContext { Items = session.Items, Locations = session.Locations, PlayerHelper = session.Players, ConnectionInfo = session.ConnectionInfo } : null); JsonSerializerSettings val = new JsonSerializerSettings { Context = new StreamingContext(StreamingContextStates.Other, additional) }; return JsonConvert.DeserializeObject<SerializableItemInfo>(json, val); } [OnDeserialized] internal void OnDeserializedMethod(StreamingContext streamingContext) { if (base.ItemGame == null && base.LocationGame != null) { IsScout = false; } else if (base.ItemGame != null && base.LocationGame == null) { IsScout = true; } if (streamingContext.Context is ItemInfoStreamingContext itemInfoStreamingContext) { if (IsScout && base.LocationGame == null) { base.LocationGame = itemInfoStreamingContext.ConnectionInfo.Game; } else if (!IsScout && base.ItemGame == null) { base.ItemGame = itemInfoStreamingContext.ConnectionInfo.Game; } if (ItemName == null) { ItemName = itemInfoStreamingContext.Items.GetItemName(base.ItemId, base.ItemGame); } if (LocationName == null) { LocationName = itemInfoStreamingContext.Locations.GetLocationNameFromId(base.LocationId, base.LocationGame); } if (Player == null) { Player = itemInfoStreamingContext.PlayerHelper.GetPlayerInfo(base.PlayerSlot); } } } } internal class ItemInfoStreamingContext { public IReceivedItemsHelper Items { get; set; } public ILocationCheckHelper Locations { get; set; } public IPlayerHelper PlayerHelper { get; set; } public IConnectionInfoProvider ConnectionInfo { get; set; } } } namespace Archipelago.MultiClient.Net.MessageLog.Parts { public class EntranceMessagePart : MessagePart { internal EntranceMessagePart(JsonMessagePart messagePart) : base(MessagePartType.Entrance, messagePart, Archipelago.MultiClient.Net.Colors.PaletteColor.Blue) { base.Text = messagePart.Text; } } public class HintStatusMessagePart : MessagePart { internal HintStatusMessagePart(JsonMessagePart messagePart) : base(MessagePartType.HintStatus, messagePart) { base.Text = messagePart.Text; if (messagePart.HintStatus.HasValue) { base.PaletteColor = ColorUtils.GetColor(messagePart.HintStatus.Value); } } } public class ItemMessagePart : MessagePart { public ItemFlags Flags { get; } public long ItemId { get; } public int Player { get; } internal ItemMessagePart(IPlayerHelper players, IItemInfoResolver items, JsonMessagePart part) : base(MessagePartType.Item, part) { Flags = part.Flags.GetValueOrDefault(); base.PaletteColor = ColorUtils.GetColor(Flags); Player = part.Player.GetValueOrDefault(); string game = (players.GetPlayerInfo(Player) ?? new PlayerInfo()).Game; JsonMessagePartType? type = part.Type; if (type.HasValue) { switch (type.GetValueOrDefault()) { case JsonMessagePartType.ItemId: ItemId = long.Parse(part.Text); base.Text = items.GetItemName(ItemId, game) ?? $"Item: {ItemId}"; break; case JsonMessagePartType.ItemName: ItemId = 0L; base.Text = part.Text; break; } } } } public class LocationMessagePart : MessagePart { public long LocationId { get; } public int Player { get; } internal LocationMessagePart(IPlayerHelper players, IItemInfoResolver itemInfoResolver, JsonMessagePart part) : base(MessagePartType.Location, part, Archipelago.MultiClient.Net.Colors.PaletteColor.Green) { Player = part.Player.GetValueOrDefault(); string game = (players.GetPlayerInfo(Player) ?? new PlayerInfo()).Game; JsonMessagePartType? type = part.Type; if (type.HasValue) { switch (type.GetValueOrDefault()) { case JsonMessagePartType.LocationId: LocationId = long.Parse(part.Text); base.Text = itemInfoResolver.GetLocationName(LocationId, game) ?? $"Location: {LocationId}"; break; case JsonMessagePartType.LocationName: LocationId = itemInfoResolver.GetLocationId(part.Text, game); base.Text = part.Text; break; } } } } public class MessagePart { public string Text { get; internal set; } public MessagePartType Type { get; internal set; } public Color Color => GetColor(BuiltInPalettes.Dark); public PaletteColor? PaletteColor { get; protected set; } public bool IsBackgroundColor { get; internal set; } internal MessagePart(MessagePartType type, JsonMessagePart messagePart, PaletteColor? color = null) { Type = type; Text = messagePart.Text; if (color.HasValue) { PaletteColor = color.Value; } else if (messagePart.Color.HasValue) { PaletteColor = ColorUtils.GetColor(messagePart.Color.Value); IsBackgroundColor = messagePart.Color.Value >= JsonMessagePartColor.BlackBg; } else { PaletteColor = null; } } public T GetColor<T>(Palette<T> palette) { return palette[PaletteColor]; } public override string ToString() { return Text; } } public enum MessagePartType { Text, Player, Item, Location, Entrance, HintStatus } public class PlayerMessagePart : MessagePart { public bool IsActivePlayer { get; } public int SlotId { get; } internal PlayerMessagePart(IPlayerHelper players, IConnectionInfoProvider connectionInfo, JsonMessagePart part) : base(MessagePartType.Player, part) { switch (part.Type) { case JsonMessagePartType.PlayerId: SlotId = int.Parse(part.Text); IsActivePlayer = SlotId == connectionInfo.Slot; base.Text = players.GetPlayerAlias(SlotId) ?? $"Player {SlotId}"; break; case JsonMessagePartType.PlayerName: SlotId = 0; IsActivePlayer = false; base.Text = part.Text; break; } base.PaletteColor = (IsActivePlayer ? Archipelago.MultiClient.Net.Colors.PaletteColor.Magenta : Archipelago.MultiClient.Net.Colors.PaletteColor.Yellow); } } } namespace Archipelago.MultiClient.Net.MessageLog.Messages { public class AdminCommandResultLogMessage : LogMessage { internal AdminCommandResultLogMessage(MessagePart[] parts) : base(parts) { } } public class ChatLogMessage : PlayerSpecificLogMessage { public string Message { get; } internal ChatLogMessage(MessagePart[] parts, IPlayerHelper players, int team, int slot, string message) : base(parts, players, team, slot) { Message = message; } } public class CollectLogMessage : PlayerSpecificLogMessage { internal CollectLogMessage(MessagePart[] parts, IPlayerHelper players, int team, int slot) : base(parts, players, team, slot) { } } public class CommandResultLogMessage : LogMessage { internal CommandResultLogMessage(MessagePart[] parts) : base(parts) { } } public class CountdownLogMessage : LogMessage { public int RemainingSeconds { get; } internal CountdownLogMessage(MessagePart[] parts, int remainingSeconds) : base(parts) { RemainingSeconds = remainingSeconds; } } public class GoalLogMessage : PlayerSpecificLogMessage { internal GoalLogMessage(MessagePart[] parts, IPlayerHelper players, int team, int slot) : base(parts, players, team, slot) { } } public class HintItemSendLogMessage : ItemSendLogMessage { public bool IsFound { get; } internal HintItemSendLogMessage(MessagePart[] parts, IPlayerHelper players, int receiver, int sender, NetworkItem item, bool found, IItemInfoResolver itemInfoResolver) : base(parts, players, receiver, sender, item, itemInfoResolver) { IsFound = found; } } public class ItemCheatLogMessage : ItemSendLogMessage { internal ItemCheatLogMessage(MessagePart[] parts, IPlayerHelper players, int team, int slot, NetworkItem item, IItemInfoResolver itemInfoResolver) : base(parts, players, slot, 0, item, team, itemInfoResolver) { } } public class ItemSendLogMessage : LogMessage { private PlayerInfo ActivePlayer { get; } public PlayerInfo Receiver { get; } public PlayerInfo Sender { get; } public bool IsReceiverTheActivePlayer => Receiver == ActivePlayer; public bool IsSenderTheActivePlayer => Sender == ActivePlayer; public bool IsRelatedToActivePlayer { get { if (!ActivePlayer.IsRelatedTo(Receiver)) { return ActivePlayer.IsRelatedTo(Sender); } return true; } } public ItemInfo Item { get; } internal ItemSendLogMessage(MessagePart[] parts, IPlayerHelper players, int receiver, int sender, NetworkItem item, IItemInfoResolver itemInfoResolver) : this(parts, players, receiver, sender, item, players.ActivePlayer.Team, itemInfoResolver) { } internal ItemSendLogMessage(MessagePart[] parts, IPlayerHelper players, int receiver, int sender, NetworkItem item, int team, IItemInfoResolver itemInfoResolver) : base(parts) { ActivePlayer = players.ActivePlayer ?? new PlayerInfo(); Receiver = players.GetPlayerInfo(team, receiver) ?? new PlayerInfo(); Sender = players.GetPlayerInfo(team, sender) ?? new PlayerInfo(); PlayerInfo player = players.GetPlayerInfo(team, item.Player) ?? new PlayerInfo(); Item = new ItemInfo(item, Receiver.Game, Sender.Game, itemInfoResolver, player); } } public class JoinLogMessage : PlayerSpecificLogMessage { public string[] Tags { get; } internal JoinLogMessage(MessagePart[] parts, IPlayerHelper players, int team, int slot, string[] tags) : base(parts, players, team, slot) { Tags = tags; } } public class LeaveLogMessage : PlayerSpecificLogMessage { internal LeaveLogMessage(MessagePart[] parts, IPlayerHelper players, int team, int slot) : base(parts, players, team, slot) { } } public class LogMessage { public MessagePart[] Parts { get; } internal LogMessage(MessagePart[] parts) { Parts = parts; } public override string ToString() { if (Parts.Length == 1) { return Parts[0].Text; } StringBuilder stringBuilder = new StringBuilder(); MessagePart[] parts = Parts; foreach (MessagePart messagePart in parts) { stringBuilder.Append(messagePart.Text); } return stringBuilder.ToString(); } } public abstract class PlayerSpecificLogMessage : LogMessage { private PlayerInfo ActivePlayer { get; } public PlayerInfo Player { get; } public bool IsActivePlayer => Player == ActivePlayer; public bool IsRelatedToActivePlayer => ActivePlayer.IsRelatedTo(Player); internal PlayerSpecificLogMessage(MessagePart[] parts, IPlayerHelper players, int team, int slot) : base(parts) { ActivePlayer = players.ActivePlayer ?? new PlayerInfo(); Player = players.GetPlayerInfo(team, slot) ?? new PlayerInfo(); } } public class ReleaseLogMessage : PlayerSpecificLogMessage { internal ReleaseLogMessage(MessagePart[] parts, IPlayerHelper players, int team, int slot) : base(parts, players, team, slot) { } } public class ServerChatLogMessage : LogMessage { public string Message { get; } internal ServerChatLogMessage(MessagePart[] parts, string message) : base(parts) { Message = message; } } public class TagsChangedLogMessage : PlayerSpecificLogMessage { public string[] Tags { get; } internal TagsChangedLogMessage(MessagePart[] parts, IPlayerHelper players, int team, int slot, string[] tags) : base(parts, players, team, slot) { Tags = tags; } } public class TutorialLogMessage : LogMessage { internal TutorialLogMessage(MessagePart[] parts) : base(parts) { } } } namespace Archipelago.MultiClient.Net.Helpers { public class ArchipelagoSocketHelper : BaseArchipelagoSocketHelper<ClientWebSocket>, IArchipelagoSocketHelper { public Uri Uri { get; } internal ArchipelagoSocketHelper(Uri hostUri) : base(CreateWebSocket(), 1024) { Uri = hostUri; } private static ClientWebSocket CreateWebSocket() { return new ClientWebSocket(); } public async Task ConnectAsync() { await ConnectToProvidedUri(Uri); StartPolling(); } private async Task ConnectToProvidedUri(Uri uri) { if (uri.Scheme != "unspecified") { try { await Socket.ConnectAsync(uri, CancellationToken.None); return; } catch (Exception e) { OnError(e); throw; } } List<Exception> errors = new List<Exception>(0); try { await Socket.ConnectAsync(uri.AsWss(), CancellationToken.None); if (Socket.State == WebSocketState.Open) { return; } } catch (Exception item) { errors.Add(item); Socket = CreateWebSocket(); } try { await Socket.ConnectAsync(uri.AsWs(), CancellationToken.None); } catch (Exception item2) { errors.Add(item2); OnError(new AggregateException(errors)); throw; } } } public class BaseArchipelagoSocketHelper<T> where T : WebSocket { private static readonly ArchipelagoPacketConverter Converter = new ArchipelagoPacketConverter(); private readonly BlockingCollection<Tuple<ArchipelagoPacketBase, TaskCompletionSource<bool>>> sendQueue = new BlockingCollection<Tuple<ArchipelagoPacketBase, TaskCompletionSource<bool>>>(); internal T Socket; private readonly int bufferSize; public bool Connected { get { if (Socket.State != WebSocketState.Open) { return Socket.State == WebSocketState.CloseReceived; } return true; } } public event ArchipelagoSocketHelperDelagates.PacketReceivedHandler PacketReceived; public event ArchipelagoSocketHelperDelagates.PacketsSentHandler PacketsSent; public event ArchipelagoSocketHelperDelagates.ErrorReceivedHandler ErrorReceived; public event ArchipelagoSocketHelperDelagates.SocketClosedHandler SocketClosed; public event ArchipelagoSocketHelperDelagates.SocketOpenedHandler SocketOpened; internal BaseArchipelagoSocketHelper(T socket, int bufferSize = 1024) { Socket = socket; this.bufferSize = bufferSize; } internal void StartPolling() { if (this.SocketOpened != null) { this.SocketOpened(); } Task.Run((Func<Task?>)PollingLoop); Task.Run((Func<Task?>)SendLoop); } private async Task PollingLoop() { byte[] buffer = new byte[bufferSize]; while (Socket.State == WebSocketState.Open) { string message = null; try { message = await ReadMessageAsync(buffer); } catch (Exception e) { OnError(e); } OnMessageReceived(message); } } private async Task SendLoop() { while (Socket.State == WebSocketState.Open) { try { await HandleSendBuffer(); } catch (Exception e) { OnError(e); } await Task.Delay(20); } } private async Task<string> ReadMessageAsync(byte[] buffer) { using MemoryStream readStream = new MemoryStream(buffer.Length); WebSocketReceiveResult result; do { result = await Socket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None); if (result.MessageType == WebSocketMessageType.Close) { try { await Socket.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty, CancellationToken.None); } catch { } OnSocketClosed(); } else { readStream.Write(buffer, 0, result.Count); } } while (!result.EndOfMessage); return Encoding.UTF8.GetString(readStream.ToArray()); } public async Task DisconnectAsync() { await Socket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Closure requested by client", CancellationToken.None); OnSocketClosed(); } public void SendPacket(ArchipelagoPacketBase packet) { SendMultiplePackets(new List<ArchipelagoPacketBase> { packet }); } public void SendMultiplePackets(List<ArchipelagoPacketBase> packets) { SendMultiplePackets(packets.ToArray()); } public void SendMultiplePackets(params ArchipelagoPacketBase[] packets) { SendMultiplePacketsAsync(packets).Wait(); } public Task SendPacketAsync(ArchipelagoPacketBase packet) { return SendMultiplePacketsAsync(new List<ArchipelagoPacketBase> { packet }); } public Task SendMultiplePacketsAsync(List<ArchipelagoPacketBase> packets) { return SendMultiplePacketsAsync(packets.ToArray()); } public Task SendMultiplePacketsAsync(params ArchipelagoPacketBase[] packets) { TaskCompletionSource<bool> taskCompletionSource = new TaskCompletionSource<bool>(); foreach (ArchipelagoPacketBase item in packets) { sendQueue.Add(new Tuple<ArchipelagoPacketBase, TaskCompletionSource<bool>>(item, taskCompletionSource)); } return taskCompletionSource.Task; } private async Task HandleSendBuffer() { List<ArchipelagoPacketBase> list = new List<ArchipelagoPacketBase>(); List<TaskCompletionSource<bool>> tasks = new List<TaskCompletionSource<bool>>(); Tuple<ArchipelagoPacketBase, TaskCompletionSource<bool>> tuple = sendQueue.Take(); list.Add(tuple.Item1); tasks.Add(tuple.Item2); Tuple<ArchipelagoPacketBase, TaskCompletionSource<bool>> item; while (sendQueue.TryTake(out item)) { list.Add(item.Item1); tasks.Add(item.Item2); } if (!list.Any()) { return; } if (Socket.State != WebSocketState.Open) { throw new ArchipelagoSocketClosedException(); } ArchipelagoPacketBase[] packets = list.ToArray(); string s = JsonConvert.SerializeObject((object)packets); byte[] messageBuffer = Encoding.UTF8.GetBytes(s); int messagesCount = (int)Math.Ceiling((double)messageBuffer.Length / (double)bufferSize); for (int i = 0; i < messagesCount; i++) { int num = bufferSize * i; int num2 = bufferSize; bool endOfMessage = i + 1 == messagesCount; if (num2 * (i + 1) > messageBuffer.Length) { num2 = messageBuffer.Length - num; } await Socket.SendAsync(new ArraySegment<byte>(messageBuffer, num, num2), WebSocketMessageType.Text, endOfMessage, CancellationToken.None); } foreach (TaskCompletionSource<bool> item2 in tasks) { item2.TrySetResult(result: true); } OnPacketSend(packets); } private void OnPacketSend(ArchipelagoPacketBase[] packets) { try { if (this.PacketsSent != null) { this.PacketsSent(packets); } } catch (Exception e) { OnError(e); } } private void OnSocketClosed() { try { if (this.SocketClosed != null) { this.SocketClosed(""); } } catch (Exception e) { OnError(e); } } private void OnMessageReceived(string message) { try { if (string.IsNullOrEmpty(message) || this.PacketReceived == null) { return; } List<ArchipelagoPacketBase> list = null; try { list = JsonConvert.DeserializeObject<List<ArchipelagoPacketBase>>(message, (JsonConverter[])(object)new JsonConverter[1] { Converter }); } catch (Exception e) { OnError(e); } if (list == null) { return; } foreach (ArchipelagoPacketBase item in list) { this.PacketReceived(item); } } catch (Exception e2) { OnError(e2); } } protected void OnError(Exception e) { try { if (this.ErrorReceived != null) { this.ErrorReceived(e, e.Message); } } catch (Exception ex) { Console.Out.WriteLine("Error occured during reporting of errorOuter Errror: " + e.Message + " " + e.StackTrace + "Inner Errror: " + ex.Message + " " + ex.StackTrace); } } } public interface IConnectionInfoProvider { string Game { get; } int Team { get; } int Slot { get; } string[] Tags { get; } ItemsHandlingFlags ItemsHandlingFlags { get; } string Uuid { get; } void UpdateConnectionOptions(string[] tags); void UpdateConnectionOptions(ItemsHandlingFlags itemsHandlingFlags); void UpdateConnectionOptions(string[] tags, ItemsHandlingFlags itemsHandlingFlags); } public class ConnectionInfoHelper : IConnectionInfoProvider { private readonly IArchipelagoSocketHelper socket; public string Game { get; private set; } public int Team { get; private set; } public int Slot { get; private set; } public string[] Tags { get; internal set; } public ItemsHandlingFlags ItemsHandlingFlags { get; internal set; } public string Uuid { get; private set; } internal ConnectionInfoHelper(IArchipelagoSocketHelper socket) { this.socket = socket; Reset(); socket.PacketReceived += PacketReceived; } private void PacketReceived(ArchipelagoPacketBase packet) { if (!(packet is ConnectedPacket connectedPacket)) { if (packet is ConnectionRefusedPacket) { Reset(); } return; } Team = connectedPacket.Team; Slot = connectedPacket.Slot; if (connectedPacket.SlotInfo != null && connectedPacket.SlotInfo.ContainsKey(Slot)) { Game = connectedPacket.SlotInfo[Slot].Game; } } internal void SetConnectionParameters(string game, string[] tags, ItemsHandlingFlags itemsHandlingFlags, string uuid) { Game = game; Tags = tags ?? new string[0]; ItemsHandlingFlags = itemsHandlingFlags; Uuid = uuid ?? Guid.NewGuid().ToString(); } private void Reset() { Game = null; Team = -1; Slot = -1; Tags = new string[0]; ItemsHandlingFlags = ItemsHandlingFlags.NoItems; Uuid = null; } public void UpdateConnectionOptions(string[] tags) { UpdateConnectionOptions(tags, ItemsHandlingFlags); } public void UpdateConnectionOptions(ItemsHandlingFlags itemsHandlingFlags) { UpdateConnectionOptions(Tags, ItemsHandlingFlags); } public void UpdateConnectionOptions(string[] tags, ItemsHandlingFlags itemsHandlingFlags) { SetConnectionParameters(Game, tags, itemsHandlingFlags, Uuid); socket.SendPacket(new ConnectUpdatePacket { Tags = Tags, ItemsHandling = ItemsHandlingFlags }); } } public interface IDataStorageHelper : IDataStorageWrapper { DataStorageElement this[Scope scope, string key] { get; set; } DataStorageElement this[string key] { get; set; } } public class DataStorageHelper : IDataStorageHelper, IDataStorageWrapper { public delegate void DataStorageUpdatedHandler(JToken originalValue, JToken newValue, Dictionary<string, JToken> additionalArguments); private readonly Dictionary<string, DataStorageUpdatedHandler> onValueChangedEventHandlers = new Dictionary<string, DataStorageUpdatedHandler>(); private readonly Dictionary<Guid, DataStorageUpdatedHandler> operationSpecificCallbacks = new Dictionary<Guid, DataStorageUpdatedHandler>(); private readonly Dictionary<string, TaskCompletionSource<JToken>> asyncRetrievalTasks = new Dictionary<string, TaskCompletionSource<JToken>>(); private readonly IArchipelagoSocketHelper socket; private readonly IConnectionInfoProvider connectionInfoProvider; public DataStorageElement this[Scope scope, string key] { get { return this[AddScope(scope, key)]; } set { this[AddScope(scope, key)] = value; } } public DataStorageElement this[string key] { get { return new DataStorageElement(GetContextForKey(key)); } set { SetValue(key, value); } } internal DataStorageHelper(IArchipelagoSocketHelper socket, IConnectionInfoProvider connectionInfoProvider) { this.socket = socket; this.connectionInfoProvider = connectionInfoProvider; socket.PacketReceived += OnPacketReceived; } private void OnPacketReceived(ArchipelagoPacketBase packet) { //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Invalid comparison between Unknown and I4 if (!(packet is RetrievedPacket retrievedPacket)) { if (packet is SetReplyPacket setReplyPacket) { if (setReplyPacket.AdditionalArguments != null && setReplyPacket.AdditionalArguments.ContainsKey("Reference") && (int)setReplyPacket.AdditionalArguments["Reference"].Type == 15 && operationSpecificCallbacks.TryGetValue((Guid)setReplyPacket.AdditionalArguments["Reference"], out var value)) { value(setReplyPacket.OriginalValue, setReplyPacket.Value, setReplyPacket.AdditionalArguments); operationSpecificCallbacks.Remove((Guid)setReplyPacket.AdditionalArguments["Reference"]); } if (onValueChangedEventHandlers.TryGetValue(setReplyPacket.Key, out var value2)) { value2(setReplyPacket.OriginalValue, setReplyPacket.Value, setReplyPacket.AdditionalArguments); } } return; } foreach (KeyValuePair<string, JToken> datum in retrievedPacket.Data) { if (asyncRetrievalTasks.TryGetValue(datum.Key, out var value3)) { value3.TrySetResult(datum.Value); asyncRetrievalTasks.Remove(datum.Key); } } } private Task<JToken> GetAsync(string key) { if (asyncRetrievalTasks.TryGetValue(key, out var value)) { return value.Task; } TaskCompletionSource<JToken> taskCompletionSource = new TaskCompletionSource<JToken>(); asyncRetrievalTasks[key] = taskCompletionSource; socket.SendPacketAsync(new GetPacket { Keys = new string[1] { key } }); return taskCompletionSource.Task; } private void Initialize(string key, JToken value) { socket.SendPacketAsync(new SetPacket { Key = key, DefaultValue = value, Operations = new OperationSpecification[1] { new OperationSpecification { OperationType = OperationType.Default } } }); } private JToken GetValue(string key) { Task<JToken> async = GetAsync(key); if (!async.Wait(TimeSpan.FromSeconds(2.0))) { throw new TimeoutException("Timed out retrieving data for key `" + key + "`. This may be due to an attempt to retrieve a value from the DataStorageHelper in a synchronous fashion from within a PacketReceived handler. When using the DataStorageHelper from within code which runs on the websocket thread then use the asynchronous getters. Ex: `DataStorageHelper[\"" + key + "\"].GetAsync().ContinueWith(x => {});`Be aware that DataStorageHelper calls tend to cause packet responses, so making a call from within a PacketReceived handler may cause an infinite loop."); } return async.Result; } private void SetValue(string key, DataStorageElement e) { if (key.StartsWith("_read_")) { throw new InvalidOperationException("DataStorage write operation on readonly key '" + key + "' is not allowed"); } if (e == null) { e = new DataStorageElement(OperationType.Replace, (JToken)(object)JValue.CreateNull()); } if (e.Context == null) { e.Context = GetContextForKey(key); } else if (e.Context.Key != key) { e.Operations.Insert(0, new OperationSpecification { OperationType = OperationType.Replace, Value = GetValue(e.Context.Key) }); } Dictionary<string, JToken> dictionary = e.AdditionalArguments ?? new Dictionary<string, JToken>(0); if (e.Callbacks != null) { Guid guid = Guid.NewGuid(); operationSpecificCallbacks[guid] = e.Callbacks; dictionary["Reference"] = JToken.FromObject((object)guid); socket.SendPacketAsync(new SetPacket { Key = key, Operations = e.Operations.ToArray(), WantReply = true, AdditionalArguments = dictionary }); } else { socket.SendPacketAsync(new SetPacket { Key = key, Operations = e.Operations.ToArray(), AdditionalArguments = dictionary }); } } private DataStorageElementContext GetContextForKey(string key) { return new DataStorageElementContext { Key = key, GetData = GetValue, GetAsync = GetAsync, Initialize = Initialize, AddHandler = AddHandler, RemoveHandler = RemoveHandler }; } private void AddHandler(string key, DataStorageUpdatedHandler handler) { if (onValueChangedEventHandlers.ContainsKey(key)) { Dictionary<string, DataStorageUpdatedHandler> dictionary = onValueChangedEventHandlers; dictionary[key] = (DataStorageUpdatedHandler)Delegate.Combine(dictionary[key], handler); } else { onValueChangedEventHandlers[key] = handler; } socket.SendPacketAsync(new SetNotifyPacket { Keys = new string[1] { key } }); } private void RemoveHandler(string key, DataStorageUpdatedHandler handler) { if (onValueChangedEventHandlers.ContainsKey(key)) { Dictionary<string, DataStorageUpdatedHandler> dictionary = onValueChangedEventHandlers; dictionary[key] = (DataStorageUpdatedHandler)Delegate.Remove(dictionary[key], handler); if (onValueChangedEventHandlers[key] == null) { onValueChangedEventHandlers.Remove(key); } } } private string AddScope(Scope scope, string key) { return scope switch { Scope.Global => key, Scope.Game => $"{scope}:{connectionInfoProvider.Game}:{key}", Scope.Team => $"{scope}:{connectionInfoProvider.Team}:{key}", Scope.Slot => $"{scope}:{connectionInfoProvider.Slot}:{key}", Scope.ReadOnly => "_read_" + key, _ => throw new ArgumentOutOfRangeException("scope", scope, "Invalid scope for key " + key), }; } private DataStorageElement GetHintsElement(int? slot = null, int? team = null) { return this[Scope.ReadOnly, $"hints_{team ?? connectionInfoProvider.Team}_{slot ?? connectionInfoProvider.Slot}"]; } private DataStorageElement GetSlotDataElement(int? slot = null) { return this[Scope.ReadOnly, $"slot_data_{slot ?? connectionInfoProvider.Slot}"]; } private DataStorageElement GetItemNameGroupsElement(string game = null) { return this[Scope.ReadOnly, "item_name_groups_" + (game ?? connectionInfoProvider.Game)]; } private DataStorageElement GetLocationNameGroupsElement(string game = null) { return this[Scope.ReadOnly, "location_name_groups_" + (game ?? connectionInfoProvider.Game)]; } private DataStorageElement GetClientStatusElement(int? slot = null, int? team = null) { return this[Scope.ReadOnly, $"client_status_{team ?? connectionInfoProvider.Team}_{slot ?? connectionInfoProvider.Slot}"]; } private DataStorageElement GetRaceModeElement() { return this[Scope.ReadOnly, "race_mode"]; } public Hint[] GetHints(int? slot = null, int? team = null) { return GetHintsElement(slot, team).To<Hint[]>(); } public Task<Hint[]> GetHintsAsync(int? slot = null, int? team = null) { return GetHintsElement(slot, team).GetAsync<Hint[]>(); } public void TrackHints(Action<Hint[]> onHintsUpdated, bool retrieveCurrentlyUnlockedHints = true, int? slot = null, int? team = null) { GetHintsElement(slot, team).OnValueChanged += delegate(JToken _, JToken newValue, Dictionary<string, JToken> x) { onHintsUpdated(newValue.ToObject<Hint[]>()); }; if (retrieveCurrentlyUnlockedHints) { GetHintsAsync(slot, team).ContinueWith(delegate(Task<Hint[]> t) { onHintsUpdated(t.Result); }); } } public Dictionary<string, object> GetSlotData(int? slot = null) { return GetSlotData<Dictionary<string, object>>(slot); } public T GetSlotData<T>(int? slot = null) where T : class { return GetSlotDataElement(slot).To<T>(); } public Task<Dictionary<string, object>> GetSlotDataAsync(int? slot = null) { return GetSlotDataAsync<Dictionary<string, object>>(slot); } public Task<T> GetSlotDataAsync<T>(int? slot = null) where T : class { return GetSlotDataElement(slot).GetAsync<T>(); } public Dictionary<string, string[]> GetItemNameGroups(string game = null) { return GetItemNameGroupsElement(game).To<Dictionary<string, string[]>>(); } public Task<Dictionary<string, string[]>> GetItemNameGroupsAsync(string game = null) { return GetItemNameGroupsElement(game).GetAsync<Dictionary<string, string[]>>(); } public Dictionary<string, string[]> GetLocationNameGroups(string game = null) { return GetLocationNameGroupsElement(game).To<Dictionary<string, string[]>>(); } public Task<Dictionary<string, string[]>> GetLocationNameGroupsAsync(string game = null) { return GetLocationNameGroupsElement(game).GetAsync<Dictionary<string, string[]>>(); } public ArchipelagoClientState GetClientStatus(int? slot = null, int? team = null) { return GetClientStatusElement(slot, team).To<ArchipelagoClientState?>().GetValueOrDefault(); } public Task<ArchipelagoClientState> GetClientStatusAsync(int? slot = null, int? team = null) { return GetClientStatusElement(slot, team).GetAsync<ArchipelagoClientState?>().ContinueWith((Task<ArchipelagoClientState?> r) => r.Result.GetValueOrDefault()); } public void TrackClientStatus(Action<ArchipelagoClientState> onStatusUpdated, bool retrieveCurrentClientStatus = true, int? slot = null, int? team = null) { GetClientStatusElement(slot, team).OnValueChanged += delegate(JToken _, JToken newValue, Dictionary<string, JToken> x) { onStatusUpdated(newValue.ToObject<ArchipelagoClientState>()); }; if (retrieveCurrentClientStatus) { GetClientStatusAsync(slot, team).ContinueWith(delegate(Task<ArchipelagoClientState> t) { onStatusUpdated(t.Result); }); } } public bool GetRaceMode() { return GetRaceModeElement().To<int?>().GetValueOrDefault() > 0; } public Task<bool> GetRaceModeAsync() { return GetRaceModeElement().GetAsync<int?>().ContinueWith((Task<int?> t) => t.Result.GetValueOrDefault() > 0); } } public interface IDataStorageWrapper { Hint[] GetHints(int? slot = null, int? tea