using System; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.IO; using System.Linq; using System.Numerics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; using Archipelago.MultiClient.Net; 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.MessageLog.Parts; using Archipelago.MultiClient.Net.Models; using Archipelago.MultiClient.Net.Packets; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using Rewired; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.SceneManagement; using UnityEngine.UI; using VeryVeryValetAPClient.Hooks; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETFramework,Version=v4.6", FrameworkDisplayName = ".NET Framework 4.6")] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: AssemblyCompany("VeryVeryValetAPClient")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+fe2fcfe8929f9cb67c2647e3e03069ee7f83216a")] [assembly: AssemblyProduct("VeryVeryValetAPClient")] [assembly: AssemblyTitle("VeryVeryValetAPClient")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } } namespace VeryVeryValetAPClient { public class APConsole : MonoBehaviour { private enum ConsoleAnchorCorner { BottomLeft, BottomRight, TopLeft, TopRight } [Serializable] public class LogEntry { public enum State { SlideIn, Hold, FadeOut } public State state = State.SlideIn; public float stateTimer; public float offsetY; public float baseY; public float animatedY; public TextMeshProUGUI? text; public Image? background; public string message; public string colorizedMessage; public float height; public LogEntry(string msg) { message = msg; colorizedMessage = msg; height = 28f; } } private static readonly Dictionary KeywordColors = new Dictionary(); private const string FontName = ""; private Color TextColor = Color.white; private Color BackColor = new Color(0f, 0f, 0f, 0.8f); private const int MaxHistoryEntries = 1000; private const KeyCode LogToggleKey = 288; private const KeyCode HistoryToggleKey = 289; private const CursorLockMode DefaultCursorMode = 1; private const bool DefaultCursorVisible = false; private const float DefaultMessageHeight = 28f; private const float DefaultConsoleHeight = 250f; private const float DefaultConsoleWidth = 600f; private float _slideInTime = 0.25f; private float _holdTime = 3f; private float _fadeOutTime = 0.5f; private const float SlideInOffset = -50f; private const float FadeUpOffset = 20f; private float _paddingX = 25f; private float _paddingY = 25f; private float _messageSpacing = 2.5f; private ConsoleAnchorCorner _anchorCorner = ConsoleAnchorCorner.BottomLeft; private float _consoleWidth = 600f; private float _consoleHeight = 250f; private float _messageHeight = 28f; private bool _rebuildHistoryDirty; private int _historyBuiltCount; private static TMP_FontAsset? _font; private readonly ConcurrentQueue _backgroundPool = new ConcurrentQueue(); private ConcurrentQueue _cachedEntries = new ConcurrentQueue(); private readonly ConcurrentQueue _textPool = new ConcurrentQueue(); private readonly List _visibleEntries = new List(); private readonly List _historyEntries = new List(); private GameObject? _historyPanel; private RectTransform? _historyContent; private bool _showHistory; private ScrollRect? _historyScrollRect; private RectTransform? _historyViewport; private Transform? _messageParent; private bool _showConsole = true; private static APConsole? _instance; public static APConsole Instance { get { if ((Object)(object)_instance == (Object)null) { Create(); } return _instance; } } private static void Create() { //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Expected O, but got Unknown if ((Object)(object)_instance != (Object)null) { return; } TMP_FontAsset[] array = Resources.FindObjectsOfTypeAll(); TMP_FontAsset[] array2 = array; foreach (TMP_FontAsset val in array2) { Console.WriteLine(((Object)val).name); } _font = ((IEnumerable)Resources.FindObjectsOfTypeAll()).FirstOrDefault((Func)((TMP_FontAsset x) => ((Object)x).name == "")); GameObject val2 = new GameObject("ArchipelagoConsoleUI"); Object.DontDestroyOnLoad((Object)(object)val2); _instance = val2.AddComponent(); _instance.BuildUI(); if (PluginMain.MessageInTime != null) { _instance._slideInTime = PluginMain.MessageInTime.Value; } if (PluginMain.MessageHoldTime != null) { _instance._holdTime = PluginMain.MessageHoldTime.Value; } if (PluginMain.MessageOutTime != null) { _instance._fadeOutTime = PluginMain.MessageOutTime.Value; } _instance.Log("by xMcacutt"); _instance.Log($"Press {(object)(KeyCode)288} to Toggle log & {(object)(KeyCode)289} to toggle history"); _instance.DebugLog("Colour Test"); foreach (string key in KeywordColors.Keys) { _instance.DebugLog(key); } } private void Update() { UpdateMessages(Time.deltaTime); TryAddNewMessages(); if (Input.GetKeyDown((KeyCode)288)) { ToggleConsole(); } if (Input.GetKeyDown((KeyCode)289)) { ToggleHistory(); } if (_showHistory) { Cursor.lockState = (CursorLockMode)0; Cursor.visible = true; } if (_showHistory && _rebuildHistoryDirty) { _rebuildHistoryDirty = false; RebuildHistory(); } } private void UpdateMessages(float delta) { for (int num = _visibleEntries.Count - 1; num >= 0; num--) { LogEntry entry = _visibleEntries[num]; if (AnimateEntry(entry, delta)) { RecycleEntry(entry); _visibleEntries.RemoveAt(num); RecalculateBaseY(); } else { UpdateEntryVisual(entry); } } } private void RecalculateBaseY() { float num = 0f; for (int num2 = _visibleEntries.Count - 1; num2 >= 0; num2--) { LogEntry logEntry = _visibleEntries[num2]; logEntry.baseY = num; num += logEntry.height + _messageSpacing; } } private bool AnimateEntry(LogEntry entry, float delta) { //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) entry.stateTimer += delta; switch (entry.state) { case LogEntry.State.SlideIn: { float num3 = Mathf.Clamp01(entry.stateTimer / _slideInTime); entry.offsetY = Mathf.Lerp(-50f, 0f, EaseOutQuad(num3)); if (num3 >= 1f) { entry.state = LogEntry.State.Hold; entry.stateTimer = 0f; } break; } case LogEntry.State.Hold: entry.offsetY = 0f; if (entry.stateTimer >= _holdTime) { entry.state = LogEntry.State.FadeOut; entry.stateTimer = 0f; } break; case LogEntry.State.FadeOut: { float num = Mathf.Clamp01(entry.stateTimer / _fadeOutTime); entry.offsetY = Mathf.Lerp(0f, 20f, num); float num2 = 1f - num; if ((Object)(object)entry.text != (Object)null) { ((Graphic)entry.text).color = new Color(TextColor.r, TextColor.g, TextColor.b, num2); } if ((Object)(object)entry.background != (Object)null) { ((Graphic)entry.background).color = new Color(BackColor.r, BackColor.g, BackColor.b, num2); } if (num >= 1f) { return true; } break; } } return false; } private static float EaseOutQuad(float x) { return 1f - (1f - x) * (1f - x); } private void TryAddNewMessages() { if (_showHistory || !_cachedEntries.Any()) { return; } int num = Mathf.FloorToInt(_consoleHeight / _messageHeight); if (_visibleEntries.Count < num) { _cachedEntries.TryDequeue(out LogEntry result); if (result != null) { result.state = LogEntry.State.SlideIn; result.stateTimer = 0f; result.offsetY = -50f; result.animatedY = result.baseY + result.offsetY; CreateEntryVisual(result); _visibleEntries.Add(result); RecalculateBaseY(); result.animatedY = result.baseY + result.offsetY; } } } private void ApplyRectSettings(RectTransform rt, Vector2 min, Vector2 max, Vector2 pivot, Vector2 pos, Vector2 size) { //IL_0002: 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_0012: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) rt.anchorMin = min; rt.anchorMax = max; rt.pivot = pivot; rt.anchoredPosition = pos; rt.sizeDelta = size; } private void PositionMessageContainer(RectTransform rect) { //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_003c: 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_0067: 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_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_0134: 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_0136: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) Vector2 val = default(Vector2); Vector2 min; Vector2 val2 = default(Vector2); Vector2 pos = default(Vector2); switch (_anchorCorner) { case ConsoleAnchorCorner.BottomLeft: ((Vector2)(ref val))..ctor(0f, 0f); min = (val2 = val); ((Vector2)(ref pos))..ctor(_paddingX, _paddingY); break; case ConsoleAnchorCorner.BottomRight: ((Vector2)(ref val2))..ctor(1f, 0f); min = val2; ((Vector2)(ref val))..ctor(1f, 0f); ((Vector2)(ref pos))..ctor(0f - _paddingX, _paddingY); break; case ConsoleAnchorCorner.TopLeft: ((Vector2)(ref val2))..ctor(0f, 1f); min = val2; ((Vector2)(ref val))..ctor(0f, 1f); ((Vector2)(ref pos))..ctor(_paddingX, 0f - _paddingY); break; case ConsoleAnchorCorner.TopRight: ((Vector2)(ref val2))..ctor(1f, 1f); min = val2; ((Vector2)(ref val))..ctor(1f, 1f); ((Vector2)(ref pos))..ctor(0f - _paddingX, 0f - _paddingY); break; default: ((Vector2)(ref val))..ctor(0f, 0f); min = (val2 = val); ((Vector2)(ref pos))..ctor(_paddingX, _paddingY); break; } ApplyRectSettings(rect, min, val2, val, pos, new Vector2(_consoleWidth, _consoleHeight)); } private void PositionHistoryPanel(RectTransform rect) { PositionMessageContainer(rect); } private void AddHistoryEntryVisual(LogEntry entry) { //IL_002e: 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_004c: 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_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0094: 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_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: 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_0114: Unknown result type (might be due to invalid IL or missing references) Image background = GetBackground(); ((Component)background).transform.SetParent((Transform)(object)_historyContent, false); RectTransform rectTransform = ((Graphic)background).rectTransform; ApplyRectSettings(rectTransform, new Vector2(0f, 1f), new Vector2(1f, 1f), new Vector2(0.5f, 1f), Vector2.zero, new Vector2(_consoleWidth, _messageHeight)); TextMeshProUGUI text = GetText(); RectTransform rectTransform2 = ((TMP_Text)text).rectTransform; ((Transform)rectTransform2).SetParent(((Component)background).transform, false); rectTransform2.anchorMin = new Vector2(0f, 0f); rectTransform2.anchorMax = new Vector2(1f, 1f); rectTransform2.pivot = new Vector2(0f, 0.5f); rectTransform2.offsetMin = new Vector2(8f, 4f); rectTransform2.offsetMax = new Vector2(-8f, -4f); entry.text = text; entry.background = background; ((Graphic)text).color = TextColor; ((Graphic)background).color = BackColor; ((TMP_Text)text).text = entry.colorizedMessage; Canvas.ForceUpdateCanvases(); LayoutRebuilder.ForceRebuildLayoutImmediate(rectTransform2); float preferredHeight = Mathf.Max(_messageHeight, ((TMP_Text)text).preferredHeight + 8f); LayoutElement val = ((Component)background).GetComponent() ?? ((Component)background).gameObject.AddComponent(); val.preferredHeight = preferredHeight; } private void CreateEntryVisual(LogEntry entry) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: 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) Image background = GetBackground(); ((Component)background).transform.SetParent(_messageParent, false); RectTransform rectTransform = ((Graphic)background).rectTransform; ApplyRectSettings(rectTransform, Vector2.zero, Vector2.zero, Vector2.zero, Vector2.zero, new Vector2(_consoleWidth, _messageHeight)); TextMeshProUGUI text = GetText(); RectTransform rectTransform2 = ((TMP_Text)text).rectTransform; ((Transform)rectTransform2).SetParent(((Component)background).transform, false); rectTransform2.anchorMin = new Vector2(0f, 0f); rectTransform2.anchorMax = new Vector2(1f, 1f); rectTransform2.pivot = new Vector2(0f, 0.5f); rectTransform2.offsetMin = new Vector2(8f, 4f); rectTransform2.offsetMax = new Vector2(-8f, -4f); entry.text = text; entry.background = background; ((Graphic)text).color = TextColor; ((Graphic)background).color = BackColor; UpdateEntryVisual(entry); } private void UpdateEntryVisual(LogEntry entry) { //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)entry.text != (Object)null) { ((TMP_Text)entry.text).text = entry.colorizedMessage; float preferredHeight = ((TMP_Text)entry.text).preferredHeight; entry.height = Mathf.Max(_messageHeight, preferredHeight + 8f); if ((Object)(object)entry.background != (Object)null) { ((Graphic)entry.background).rectTransform.sizeDelta = new Vector2(_consoleWidth, entry.height); } } float num = entry.baseY + entry.offsetY; entry.animatedY = Mathf.Lerp(entry.animatedY, num, Time.deltaTime * 12f); if ((Object)(object)entry.background != (Object)null) { ((Graphic)entry.background).rectTransform.anchoredPosition = new Vector2(0f, entry.animatedY); } } private TextMeshProUGUI GetText() { //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Expected O, but got Unknown //IL_0081: Unknown result type (might be due to invalid IL or missing references) if (_textPool.TryDequeue(out TextMeshProUGUI result) && (Object)(object)result != (Object)null) { ((Component)result).gameObject.SetActive(true); return result; } GameObject val = new GameObject("LogText", new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(TextMeshProUGUI) }); TextMeshProUGUI component = val.GetComponent(); ((TMP_Text)component).fontSize = 19f; ((Graphic)component).color = TextColor; ((TMP_Text)component).font = _font; ((TMP_Text)component).wordSpacing = 20f; ((TMP_Text)component).alignment = (TextAlignmentOptions)4097; return component; } private Image GetBackground() { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Expected O, but got Unknown //IL_0045: Unknown result type (might be due to invalid IL or missing references) if (_backgroundPool.TryDequeue(out Image result) && (Object)(object)result != (Object)null) { ((Component)result).gameObject.SetActive(true); return result; } GameObject val = new GameObject("LogBG"); Image val2 = val.AddComponent(); ((Graphic)val2).color = BackColor; val2.type = (Type)1; return val2; } private void RecycleEntry(LogEntry entry) { if ((Object)(object)entry.text != (Object)null) { ((Component)entry.text).gameObject.SetActive(false); _textPool.Enqueue(entry.text); entry.text = null; } if ((Object)(object)entry.background != (Object)null) { ((Component)entry.background).gameObject.SetActive(false); _backgroundPool.Enqueue(entry.background); entry.background = null; } } private string Colorize(string input) { if (string.IsNullOrEmpty(input)) { return input; } List list = Tokenize(input); ApplyMultiWordColoring(list); ApplySingleWordColoring(list); return string.Concat(list); } private List Tokenize(string input) { return string.IsNullOrEmpty(input) ? new List() : Regex.Split(input, "(\\s+)").ToList(); } private void ApplySingleWordColoring(List tokens) { Dictionary dictionary = KeywordColors.Where>((KeyValuePair kvp) => !kvp.Key.Contains(" ")).ToDictionary((KeyValuePair k) => k.Key.ToLowerInvariant(), (KeyValuePair v) => v.Value); for (int i = 0; i < tokens.Count; i++) { string text = tokens[i]; if (IsWord(text)) { string key = Regex.Replace(text.ToLowerInvariant(), "[^a-z0-9]", ""); if (dictionary.TryGetValue(key, out var value)) { tokens[i] = "" + text + ""; } } } } private void ApplyMultiWordColoring(List tokens) { List> list = (from kvp in KeywordColors where kvp.Key.Contains(" ") select kvp into k orderby k.Key.Length descending select k).ToList(); if (list.Count == 0) { return; } for (int i = 0; i < tokens.Count; i++) { if (!IsWord(tokens[i])) { continue; } string text = string.Concat(tokens.Skip(i)); string text2 = text.ToLowerInvariant(); foreach (KeyValuePair item in list) { if (!text2.StartsWith(item.Key.ToLowerInvariant())) { continue; } int num = 0; string text3 = ""; for (int j = i; j < tokens.Count; j++) { if (text3.Length >= item.Key.Length) { break; } text3 += tokens[j]; num++; } tokens[i] = "" + text3 + ""; for (int l = 1; l < num; l++) { tokens[i + l] = ""; } i += num - 1; break; } } } private bool IsWord(string token) { return !string.IsNullOrWhiteSpace(token); } public void Log(string text) { ManualLogSource? logger = PluginMain.logger; if (logger != null) { logger.LogInfo((object)text); } string colorizedMessage = Colorize(text); LogEntry item = new LogEntry(text) { colorizedMessage = colorizedMessage }; _historyEntries.Add(item); if (_historyEntries.Count > 1000) { _historyEntries.RemoveAt(0); _historyBuiltCount = Mathf.Max(0, _historyBuiltCount - 1); } if (_showHistory) { _rebuildHistoryDirty = true; } else { _cachedEntries.Enqueue(item); } } public void DebugLog(string text) { if (PluginMain.EnableDebugLogging != null && PluginMain.EnableDebugLogging.Value) { Log(text); } } private void ToggleHistory() { _showHistory = !_showHistory; if ((Object)(object)_messageParent == (Object)null || (Object)(object)_historyPanel == (Object)null) { return; } ((Component)_messageParent).gameObject.SetActive(!_showHistory); _historyPanel.SetActive(_showHistory); if (_showHistory) { foreach (LogEntry visibleEntry in _visibleEntries) { if ((Object)(object)visibleEntry.text != (Object)null) { ((Component)visibleEntry.text).gameObject.SetActive(false); _textPool.Enqueue(visibleEntry.text); } if ((Object)(object)visibleEntry.background != (Object)null) { ((Component)visibleEntry.background).gameObject.SetActive(false); _backgroundPool.Enqueue(visibleEntry.background); } } _visibleEntries.Clear(); _cachedEntries = new ConcurrentQueue(); RebuildHistory(); } else { Cursor.lockState = (CursorLockMode)1; Cursor.visible = false; ((Component)_messageParent).gameObject.SetActive(_showConsole); } } private void ToggleConsole() { _showConsole = !_showConsole; if ((Object)(object)_messageParent == (Object)null || (Object)(object)_historyPanel == (Object)null) { return; } foreach (LogEntry visibleEntry in _visibleEntries) { if ((Object)(object)visibleEntry.background != (Object)null) { ((Component)visibleEntry.background).gameObject.SetActive(_showConsole); } if ((Object)(object)visibleEntry.text != (Object)null) { ((Component)visibleEntry.text).gameObject.SetActive(_showConsole); } } ((Component)_messageParent).gameObject.SetActive(_showConsole); if (!_showConsole) { _showHistory = false; _historyPanel.SetActive(false); } } private void BuildUI() { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Expected O, but got Unknown //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Expected O, but got Unknown //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Expected O, but got Unknown //IL_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_01e9: Unknown result type (might be due to invalid IL or missing references) //IL_0200: 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_0206: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Unknown result type (might be due to invalid IL or missing references) //IL_0222: Unknown result type (might be due to invalid IL or missing references) //IL_0295: Unknown result type (might be due to invalid IL or missing references) //IL_029c: Expected O, but got Unknown //IL_02c1: Unknown result type (might be due to invalid IL or missing references) //IL_02d8: Unknown result type (might be due to invalid IL or missing references) //IL_02ef: 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_0313: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("APConsoleCanvas", new Type[3] { typeof(Canvas), typeof(CanvasScaler), typeof(GraphicRaycaster) }); val.transform.SetParent(((Component)this).transform); Canvas component = val.GetComponent(); component.renderMode = (RenderMode)0; component.sortingOrder = 2000; CanvasScaler component2 = val.GetComponent(); component2.uiScaleMode = (ScaleMode)1; component2.referenceResolution = new Vector2(1920f, 1080f); GameObject val2 = new GameObject("Messages", new Type[1] { typeof(RectTransform) }); RectTransform component3 = val2.GetComponent(); ((Transform)component3).SetParent(val.transform, false); _messageParent = val2.transform; PositionMessageContainer(component3); _historyPanel = new GameObject("HistoryPanel", new Type[1] { typeof(RectTransform) }); RectTransform component4 = _historyPanel.GetComponent(); ((Transform)component4).SetParent(val.transform, false); PositionHistoryPanel(component4); _historyPanel.SetActive(false); _historyScrollRect = _historyPanel.AddComponent(); _historyScrollRect.horizontal = false; _historyScrollRect.vertical = true; _historyScrollRect.scrollSensitivity = 5f; _historyScrollRect.movementType = (MovementType)2; GameObject val3 = new GameObject("Viewport", new Type[3] { typeof(RectTransform), typeof(Image), typeof(Mask) }); _historyViewport = val3.GetComponent(); val3.transform.SetParent(_historyPanel.transform, false); _historyViewport.anchorMin = Vector2.zero; _historyViewport.anchorMax = Vector2.one; RectTransform? historyViewport = _historyViewport; Vector2 offsetMin = (_historyViewport.offsetMax = Vector2.zero); historyViewport.offsetMin = offsetMin; Image component5 = val3.GetComponent(); ((Graphic)component5).color = BackColor; component5.type = (Type)0; ((Graphic)component5).raycastTarget = true; Mask component6 = val3.GetComponent(); component6.showMaskGraphic = false; _historyScrollRect.viewport = _historyViewport; GameObject val4 = new GameObject("Content", new Type[3] { typeof(RectTransform), typeof(VerticalLayoutGroup), typeof(ContentSizeFitter) }); RectTransform component7 = val4.GetComponent(); ((Transform)component7).SetParent(val3.transform, false); component7.anchorMin = new Vector2(0f, 1f); component7.anchorMax = new Vector2(1f, 1f); component7.pivot = new Vector2(0.5f, 1f); component7.anchoredPosition = Vector2.zero; component7.sizeDelta = new Vector2(0f, 0f); VerticalLayoutGroup component8 = val4.GetComponent(); ((HorizontalOrVerticalLayoutGroup)component8).childForceExpandHeight = false; ((HorizontalOrVerticalLayoutGroup)component8).childForceExpandWidth = true; ((HorizontalOrVerticalLayoutGroup)component8).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)component8).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)component8).spacing = 8f; ((LayoutGroup)component8).childAlignment = (TextAnchor)0; ContentSizeFitter component9 = val4.GetComponent(); component9.verticalFit = (FitMode)2; component9.horizontalFit = (FitMode)0; _historyScrollRect.content = component7; _historyContent = component7; } private void RebuildHistory() { if (!((Object)(object)_historyContent == (Object)null)) { for (int i = _historyBuiltCount; i < _historyEntries.Count; i++) { AddHistoryEntryVisual(_historyEntries[i]); } _historyBuiltCount = _historyEntries.Count; Canvas.ForceUpdateCanvases(); LayoutRebuilder.ForceRebuildLayoutImmediate(_historyContent); Canvas.ForceUpdateCanvases(); if ((Object)(object)_historyScrollRect != (Object)null) { _historyScrollRect.verticalNormalizedPosition = 0f; } } } } public class ArchipelagoHandler : MonoBehaviour { [CompilerGenerated] private sealed class <>c__DisplayClass39_0 { public Task connectTask; public Task loginTask; internal bool b__0() { return connectTask.IsCompleted; } internal bool b__1() { return loginTask.IsCompleted; } } [CompilerGenerated] private sealed class d__39 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public ArchipelagoHandler <>4__this; private <>c__DisplayClass39_0 <>8__1; private LoginSuccessful 5__2; private LoginFailure 5__3; private string 5__4; object? IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object? IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__39(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>8__1 = null; 5__2 = null; 5__3 = null; 5__4 = null; <>1__state = -2; } private bool MoveNext() { //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Expected O, but got Unknown //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Expected O, but got Unknown //IL_0237: Unknown result type (might be due to invalid IL or missing references) //IL_0241: Expected O, but got Unknown //IL_02f2: Unknown result type (might be due to invalid IL or missing references) //IL_02fc: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>8__1 = new <>c__DisplayClass39_0(); APConsole.Instance.Log("Logging in to " + <>4__this.Server + " as " + <>4__this.Slot + "..."); <>8__1.connectTask = <>4__this.Session.ConnectAsync(); <>2__current = (object)new WaitUntil((Func)(() => <>8__1.connectTask.IsCompleted)); <>1__state = 1; return true; case 1: { <>1__state = -1; if (<>8__1.connectTask.Exception != null) { APConsole.Instance.Log(<>8__1.connectTask.Exception.ToString()); return false; } <>4__this.seed = <>8__1.connectTask.Result.SeedName; <>c__DisplayClass39_0 <>c__DisplayClass39_ = <>8__1; ArchipelagoSession? session = <>4__this.Session; <>c__DisplayClass39_.loginTask = ((session != null) ? session.LoginAsync("Very Very Valet", <>4__this.Slot, (ItemsHandlingFlags)7, new Version(0, 6, 5), new string[0], (string)null, <>4__this.Password, true) : null); <>2__current = (object)new WaitUntil((Func)(() => <>8__1.loginTask.IsCompleted)); <>1__state = 2; return true; } case 2: { <>1__state = -1; if (<>8__1.loginTask?.Exception != null) { APConsole.Instance.Log(<>8__1.loginTask.Exception.ToString()); return false; } Task loginTask = <>8__1.loginTask; if (loginTask != null && loginTask.Result.Successful) { APConsole.Instance.Log("Success! Connected to " + <>4__this.Server); 5__2 = (LoginSuccessful)<>8__1.loginTask.Result; PluginMain.SlotData = new SlotData(5__2.SlotData); ((MonoBehaviour)PluginMain.ArchipelagoHandler).StartCoroutine(<>4__this.RunCheckQueue()); <>4__this.connectionSucceeded = true; <>4__this.connectionFinished = true; <>4__this.OnConnected?.Invoke(); return false; } <>4__this.connectionSucceeded = false; <>4__this.connectionFinished = true; if (<>8__1.loginTask?.Result != null) { 5__3 = (LoginFailure)<>8__1.loginTask.Result; 5__4 = "Failed to Connect to " + <>4__this.Server + " as " + <>4__this.Slot + ":"; 5__4 = 5__3.Errors.Aggregate(5__4, (string current, string error) => current + "\n " + error); 5__4 = 5__3.ErrorCodes.Aggregate(5__4, (string current, ConnectionRefusedError error) => current + $"\n {error}"); <>4__this.OnConnectionFailed?.Invoke(5__4); APConsole.Instance.Log(5__4); 5__3 = null; 5__4 = null; } APConsole.Instance.Log("Attempting reconnect..."); return false; } } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class d__48 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public ArchipelagoHandler <>4__this; private long 5__1; object? IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object? IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__48(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; break; case 1: <>1__state = -1; break; } if (<>4__this._locationsToCheck.TryDequeue(out 5__1)) { ArchipelagoSession? session = <>4__this.Session; if (session != null) { session.Locations.CompleteLocationChecks(new long[1] { 5__1 }); } APConsole.Instance.DebugLog($"Sent location check: {5__1}"); } if (<>4__this._queueBreak) { return false; } <>2__current = (object)new WaitForSeconds(0.1f); <>1__state = 1; return true; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } public string? seed; private ConcurrentQueue _locationsToCheck = new ConcurrentQueue(); private readonly Random _random = new Random(); public volatile bool connectionFinished; public volatile bool connectionSucceeded; private readonly bool _queueBreak = false; private string? _lastDeath; private DateTime _lastDeathLinkTime = DateTime.Now; private readonly string[] _deathMessages = new string[11] { "had a skill issue (died)", "drove off a cliff (died)", "wasn't very valet (died)", "never got their license (died)", "was abducted by aliens (died)", "caused a pile-up (died)", "went the wrong way down a one way street (died)", "took too long (died)", "only knows how to drive automatic (died)", "didn't check their mirrors (died)", "forgot to look both ways (died)" }; private ArchipelagoSession? Session { get; set; } private string? Server { get; set; } public string? Slot { get; set; } private string? Password { get; set; } public bool IsConnected { get { ArchipelagoSession? session = Session; return session != null && session.Socket.Connected; } } public event Action? OnConnected; public event Action? OnConnectionFailed; public event Action? OnDisconnected; public int GetReceivedStarCount() { ArchipelagoSession? session = Session; return ((session != null) ? session.Items.AllItemsReceived : null)?.Count((ItemInfo i) => i.ItemId == 256) ?? 0; } public void CreateSession(string server, string slot, string password) { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Expected O, but got Unknown //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Expected O, but got Unknown //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Expected O, but got Unknown //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Expected O, but got Unknown //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Expected O, but got Unknown Server = server; Slot = slot; Password = password; _locationsToCheck = new ConcurrentQueue(); Session = ArchipelagoSessionFactory.CreateSession(Server, 38281); Session.MessageLog.OnMessageReceived += new MessageReceivedHandler(OnMessageReceived); Session.Socket.ErrorReceived += new ErrorReceivedHandler(OnError); Session.Socket.SocketClosed += new SocketClosedHandler(OnSocketClosed); Session.Items.ItemReceived += new ItemReceivedHandler(ItemReceived); Session.Socket.PacketReceived += new PacketReceivedHandler(PacketReceived); } private void OnDestroy() { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected O, but got Unknown //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Expected O, but got Unknown //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Expected O, but got Unknown //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Expected O, but got Unknown //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Expected O, but got Unknown if (Session != null) { Session.Socket.ErrorReceived -= new ErrorReceivedHandler(OnError); Session.MessageLog.OnMessageReceived -= new MessageReceivedHandler(OnMessageReceived); Session.Socket.SocketClosed -= new SocketClosedHandler(OnSocketClosed); Session.Items.ItemReceived -= new ItemReceivedHandler(ItemReceived); Session.Socket.PacketReceived -= new PacketReceivedHandler(PacketReceived); } } [IteratorStateMachine(typeof(d__39))] public IEnumerator ConnectRoutine() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__39(0) { <>4__this = this }; } public void Connect() { ((MonoBehaviour)this).StartCoroutine(ConnectRoutine()); } public void Disconnect() { if (Session != null) { ((MonoBehaviour)this).StopAllCoroutines(); Session.Socket.DisconnectAsync(); Session = null; APConsole.Instance.Log("Disconnected from Archipelago"); } } private void OnError(Exception ex, string message) { APConsole.Instance.Log("Socket error: " + message + " - " + ex.Message); } private void OnSocketClosed(string reason) { ((MonoBehaviour)this).StopAllCoroutines(); APConsole.Instance.Log("Socket closed: " + reason); this.OnDisconnected?.Invoke(); } private void ItemReceived(ReceivedItemsHelper helper) { try { while (helper.Any()) { int index = helper.Index; ItemInfo item = helper.DequeueItem(); PluginMain.logger.LogWarning((object)index); PluginMain.ItemHandler.HandleItem(index, item); } } catch (Exception arg) { APConsole.Instance.Log($"ItemReceived Error: {arg}"); throw; } } public void Release() { ArchipelagoSession? session = Session; if (session != null) { session.SetGoalAchieved(); } ArchipelagoSession? session2 = Session; if (session2 != null) { session2.SetClientState((ArchipelagoClientState)30); } } public void CheckLocations(long[] ids) { ids.ToList().ForEach(CheckLocation); } public void CheckLocation(long id) { if (!IsLocationChecked(id)) { _locationsToCheck.Enqueue(id); } } [IteratorStateMachine(typeof(d__48))] private IEnumerator RunCheckQueue() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__48(0) { <>4__this = this }; } public void ResyncItems() { if (!IsConnected) { APConsole.Instance.DebugLog("Cannot resync items: Not connected to Archipelago"); return; } APConsole.Instance.DebugLog("Resyncing items from server..."); ArchipelagoSession? session = Session; ReadOnlyCollection readOnlyCollection = ((session != null) ? session.Items.AllItemsReceived : null); if (readOnlyCollection != null) { for (int i = 0; i < readOnlyCollection.Count; i++) { PluginMain.ItemHandler?.HandleItem(i, readOnlyCollection[i], save: false); } } CustomSaveDataHandler.Save(); if (readOnlyCollection != null) { APConsole.Instance.DebugLog($"Resync complete. Processed up to item {readOnlyCollection.Count}"); } } private void PacketReceived(ArchipelagoPacketBase packet) { BouncePacket val = (BouncePacket)(object)((packet is BouncePacket) ? packet : null); if (val != null) { BouncePacketReceived(val); } } public void SendDeath() { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Expected O, but got Unknown APConsole.Instance.DebugLog("SendDeath called"); SlotData? slotData = PluginMain.SlotData; if (slotData == null || !slotData.DeathLink) { return; } BouncePacket val = new BouncePacket(); DateTime now = DateTime.Now; if (!(now - _lastDeathLinkTime < TimeSpan.FromSeconds(2.0))) { val.Tags = new List { "DeathLink" }; val.Data = new Dictionary { { "time", JToken.op_Implicit(UnixTimeConverter.ToUnixTimeStamp(now)) }, { "source", JToken.op_Implicit(Slot) }, { "cause", JToken.op_Implicit(Slot + " " + _deathMessages[_random.Next(_deathMessages.Length)]) } }; _lastDeathLinkTime = now; ArchipelagoSession? session = Session; if (session != null) { session.Socket.SendPacket((ArchipelagoPacketBase)(object)val); } } } private void BouncePacketReceived(BouncePacket packet) { SlotData? slotData = PluginMain.SlotData; if (slotData != null && slotData.DeathLink) { ProcessBouncePacket(packet, "DeathLink", ref _lastDeath, delegate(string source, Dictionary data) { HandleDeathLink(source, ((object)data["cause"])?.ToString() ?? "Unknown"); }); } } private static void ProcessBouncePacket(BouncePacket packet, string tag, ref string? lastTime, Action> handler) { if (!packet.Tags.Contains(tag) || !packet.Data.TryGetValue("time", out var value) || lastTime == ((object)value).ToString()) { return; } lastTime = ((object)value).ToString(); if (packet.Data.TryGetValue("source", out var value2)) { string arg = ((object)value2)?.ToString() ?? "Unknown"; if (packet.Data.TryGetValue("cause", out var value3)) { string text = ((object)value3)?.ToString() ?? "Unknown"; APConsole.Instance.DebugLog("Received Bounce Packet with Tag: " + tag + " :: " + text); } handler(arg, packet.Data); } } private void HandleDeathLink(string source, string cause) { SlotData? slotData = PluginMain.SlotData; if (slotData != null && slotData.DeathLink) { APConsole.Instance.Log(cause); if (!(source == Slot)) { Kill(); } } } public void Kill() { PlayerMgr val = Object.FindObjectOfType(); if (!((Object)(object)val == (Object)null)) { val.SessionStart(false); } } public bool IsLocationChecked(long id) { return Session != null && Session.Locations.AllLocationsChecked.Contains(id); } public int CountLocationsCheckedInRange(long start, long end) { return (Session != null) ? Session.Locations.AllLocationsChecked.Count((long loc) => loc >= start && loc < end) : 0; } public int CountLocationsCheckedInRange(long start, long end, long delta) { return (Session != null) ? Session.Locations.AllLocationsChecked.Count((long loc) => loc >= start && loc < end && loc % delta == start % delta) : 0; } public void UpdateTags(List tags) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown ConnectUpdatePacket val = new ConnectUpdatePacket { Tags = tags.ToArray(), ItemsHandling = (ItemsHandlingFlags)7 }; ArchipelagoSession? session = Session; if (session != null) { session.Socket.SendPacket((ArchipelagoPacketBase)(object)val); } } private void OnMessageReceived(LogMessage message) { if (message.Parts.Any((MessagePart x) => (int)x.Type == 1) && PluginMain.FilterLog != null && PluginMain.FilterLog.Value && !message.Parts.Any((MessagePart x) => x.Text.Contains(Session.Players.GetPlayerName(Session.ConnectionInfo.Slot)))) { return; } string text; if (message.Parts.Length == 1) { text = message.Parts[0].Text; } else { StringBuilder stringBuilder = new StringBuilder(); MessagePart[] parts = message.Parts; foreach (MessagePart val in parts) { stringBuilder.Append(val.Text ?? ""); } text = stringBuilder.ToString(); } APConsole.Instance.Log(text); } public ScoutedItemInfo? TryScoutLocation(long locationId) { ArchipelagoSession? session = Session; return (session == null) ? null : session.Locations.ScoutLocationsAsync(new long[1] { locationId })?.Result?.Values.First(); } } public class ConnectionInfo { public string Server { get; set; } public string Slot { get; set; } public string Password { get; set; } public ConnectionInfo(string server, string slot, string password) { Server = server; Slot = slot; Password = password; } } public static class ConnectionInfoHandler { private const string Path = "./ArchipelagoSaves/connection_info.json"; public static string SavedServer = "Archipelago.gg:"; public static string SavedSlot = "Player1"; public static string SavedPassword = ""; public static void Save(string server, string slot, string password) { SavedServer = server; SavedSlot = slot; SavedPassword = password; if (!Directory.Exists("./ArchipelagoSaves/")) { Directory.CreateDirectory("./ArchipelagoSaves/"); } ConnectionInfo connectionInfo = new ConnectionInfo(server, slot, password); string contents = JsonConvert.SerializeObject((object)connectionInfo); File.WriteAllText("./ArchipelagoSaves/connection_info.json", contents); } public static bool Load() { if (!File.Exists("./ArchipelagoSaves/connection_info.json")) { Save(SavedServer, SavedSlot, SavedPassword); } string text = File.ReadAllText("./ArchipelagoSaves/connection_info.json"); ConnectionInfo connectionInfo = JsonConvert.DeserializeObject(text); if (connectionInfo == null) { return false; } SavedServer = connectionInfo.Server; SavedSlot = connectionInfo.Slot; SavedPassword = connectionInfo.Password; return true; } } public class CustomSaveData { public int ItemIndex; public int StoredPowerups; } public class CustomSaveDataHandler { public static CustomSaveData Data = new CustomSaveData(); public static void Save() { ArchipelagoHandler? archipelagoHandler = PluginMain.ArchipelagoHandler; if (archipelagoHandler != null && archipelagoHandler.IsConnected) { string saveFolder = PlayerSave.GetSaveFolder(); if (!Directory.Exists(saveFolder)) { Directory.CreateDirectory(saveFolder); } string path = Path.Combine(saveFolder, "AP_" + PluginMain.ArchipelagoHandler.Slot + "_" + PluginMain.ArchipelagoHandler.seed + ".json"); string contents = JsonConvert.SerializeObject((object)Data); File.WriteAllText(path, contents); } } public static void Load() { ArchipelagoHandler? archipelagoHandler = PluginMain.ArchipelagoHandler; if (archipelagoHandler != null && archipelagoHandler.IsConnected) { string saveFolder = PlayerSave.GetSaveFolder(); string path = Path.Combine(saveFolder, "AP_" + PluginMain.ArchipelagoHandler.Slot + "_" + PluginMain.ArchipelagoHandler.seed + ".json"); if (!File.Exists(path)) { Save(); } string text = File.ReadAllText(path); CustomSaveData customSaveData = JsonConvert.DeserializeObject(text); if (customSaveData != null) { Data.ItemIndex = customSaveData.ItemIndex; Data.StoredPowerups = customSaveData.StoredPowerups; } } } } public class ItemWrapper { public int Index; public ItemInfo Info; public ItemWrapper(int index, ItemInfo info) { Index = index; Info = info; } } public class ItemHandler : MonoBehaviour { [CompilerGenerated] private sealed class d__6 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public PowerupSpawner spawner; public ItemHandler <>4__this; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__6(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = null; <>1__state = 1; return true; case 1: <>1__state = -1; ((BasicSpawner)spawner).Spawn(); return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private Queue cachedItems = new Queue(); private bool IsGameReady() { return PluginMain.ArchipelagoHandler.IsConnected; } public void HandleItem(int index, ItemInfo item, bool save = true) { try { if (!IsGameReady()) { APConsole.Instance.DebugLog($"Game not ready, caching item: {item.ItemName} (index {index})"); cachedItems.Enqueue(new ItemWrapper(index, item)); return; } if (cachedItems.Count > 0) { APConsole.Instance.DebugLog($"Processing {cachedItems.Count} cached items..."); FlushQueue(); } ProcessItem(index, item); } catch (Exception arg) { APConsole.Instance.DebugLog($"HandleItem Error: {arg}"); } } private void Update() { if (Input.GetKeyDown((KeyCode)286)) { FlushQueue(); } } public void FlushQueue() { if (!IsGameReady()) { APConsole.Instance.DebugLog("Attempted to flush queue but game is not ready"); return; } int num = 0; while (cachedItems.Count > 0) { ItemWrapper itemWrapper = cachedItems.Dequeue(); ProcessItem(itemWrapper.Index, itemWrapper.Info); num++; } APConsole.Instance.DebugLog($"Flushed {num} cached items"); if (num > 0) { CustomSaveDataHandler.Save(); } } private void ProcessItem(int index, ItemInfo item) { if (index < CustomSaveDataHandler.Data.ItemIndex) { APConsole.Instance.DebugLog($"Item {index} already processed (current: {CustomSaveDataHandler.Data.ItemIndex})"); return; } CustomSaveDataHandler.Data.ItemIndex++; switch (item.ItemId) { case 256L: { ScreenUI_LevelSelect val2 = Object.FindObjectOfType(); if ((Object)(object)val2 != (Object)null && ((Behaviour)val2).enabled) { val2.RefreshStarCount(true); } break; } case 257L: { PowerupSpawner val = Object.FindObjectOfType(); if ((Object)(object)val == (Object)null) { CustomSaveDataHandler.Data.StoredPowerups++; } else { ((MonoBehaviour)this).StartCoroutine(SpawnPowerup(val)); } break; } default: PluginMain.logger.LogWarning((object)$"Unknown item: {item.ItemId} ({item.ItemName})"); break; } CustomSaveDataHandler.Save(); } [IteratorStateMachine(typeof(d__6))] private IEnumerator SpawnPowerup(PowerupSpawner spawner) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__6(0) { <>4__this = this, spawner = spawner }; } } public enum APLevelType { Level, Bonus, Final } public struct APLevelData { public string Name; public APLevelType Type; public APLevelData(string name, APLevelType type) { Name = name; Type = type; } } public class LevelOrderHandler { public static Dictionary SaveKeyToLevelName = new Dictionary { { "Rooftop1", "Rooftop Parking" }, { "AcrossSt", "Across the Street" }, { "Bowling3", "Bowled Over" }, { "tunnelpa", "Alley Avenue" }, { "CliffRnd", "Cliffside Overlook" }, { "Obvservy", "The Observatory" }, { "nphotel", "Hotel No Vacancy" }, { "Quarry", "Quartz Quarry" }, { "Tunnel", "Up and Down" }, { "Garbage1", "Cleanup Crew" }, { "OverPass", "Overpass Galleria" }, { "Airport", "Now Departing" }, { "CarWash", "Rinse and Return" }, { "Downtown", "Downtown" }, { "Sweeper1", "Home Sweep Home" }, { "CarDealr", "Macho Motors" }, { "DblPark", "Double Parking" }, { "Earthqk", "Seismic Stories" }, { "twozones", "Dueling Venues" }, { "MallLot", "The Lot" }, { "sharedlt", "Sharing Spaces" }, { "Combo1", "Three In One" }, { "railroad", "Chaos Caboose" }, { "Boss0", "Auto Recall" } }; public static Dictionary LevelNumberToName = new Dictionary { { 0, new APLevelData("Rooftop Parking", APLevelType.Level) }, { 1, new APLevelData("Across the Street", APLevelType.Level) }, { 2, new APLevelData("Bowled Over", APLevelType.Bonus) }, { 3, new APLevelData("Alley Avenue", APLevelType.Level) }, { 4, new APLevelData("Cliffside Overlook", APLevelType.Level) }, { 5, new APLevelData("The Observatory", APLevelType.Final) }, { 6, new APLevelData("Hotel No Vacancy", APLevelType.Level) }, { 7, new APLevelData("Quartz Quarry", APLevelType.Level) }, { 8, new APLevelData("Up and Down", APLevelType.Level) }, { 9, new APLevelData("Cleanup Crew", APLevelType.Bonus) }, { 10, new APLevelData("Overpass Galleria", APLevelType.Level) }, { 11, new APLevelData("Now Departing", APLevelType.Final) }, { 12, new APLevelData("Rinse and Return", APLevelType.Level) }, { 13, new APLevelData("Downtown", APLevelType.Level) }, { 14, new APLevelData("Home Sweep Home", APLevelType.Bonus) }, { 15, new APLevelData("Macho Motors", APLevelType.Level) }, { 16, new APLevelData("Double Parking", APLevelType.Level) }, { 17, new APLevelData("Seismic Stories", APLevelType.Final) }, { 18, new APLevelData("Dueling Venues", APLevelType.Level) }, { 19, new APLevelData("The Lot", APLevelType.Level) }, { 20, new APLevelData("Sharing Spaces", APLevelType.Level) }, { 21, new APLevelData("Three In One", APLevelType.Bonus) }, { 22, new APLevelData("Chaos Caboose", APLevelType.Level) }, { 23, new APLevelData("Auto Recall", APLevelType.Final) } }; public static Dictionary LevelNameToNumber = new Dictionary { { "Rooftop Parking", 0 }, { "Across the Street", 1 }, { "Bowled Over", 2 }, { "Alley Avenue", 3 }, { "Cliffside Overlook", 4 }, { "The Observatory", 5 }, { "Hotel No Vacancy", 6 }, { "Quartz Quarry", 7 }, { "Up and Down", 8 }, { "Cleanup Crew", 9 }, { "Overpass Galleria", 10 }, { "Now Departing", 11 }, { "Rinse and Return", 12 }, { "Downtown", 13 }, { "Home Sweep Home", 14 }, { "Macho Motors", 15 }, { "Double Parking", 16 }, { "Seismic Stories", 17 }, { "Dueling Venues", 18 }, { "The Lot", 19 }, { "Sharing Spaces", 20 }, { "Three In One", 21 }, { "Chaos Caboose", 22 }, { "Auto Recall", 23 } }; public static Dictionary LevelNameToNormalizedNumber = new Dictionary { { "Rooftop Parking", 0 }, { "Across the Street", 1 }, { "Alley Avenue", 2 }, { "Cliffside Overlook", 3 }, { "Bowled Over", 4 }, { "The Observatory", 5 }, { "Hotel No Vacancy", 6 }, { "Quartz Quarry", 7 }, { "Up and Down", 8 }, { "Overpass Galleria", 9 }, { "Cleanup Crew", 10 }, { "Now Departing", 11 }, { "Rinse and Return", 12 }, { "Downtown", 13 }, { "Macho Motors", 14 }, { "Double Parking", 15 }, { "Home Sweep Home", 16 }, { "Seismic Stories", 17 }, { "Dueling Venues", 18 }, { "The Lot", 19 }, { "Sharing Spaces", 20 }, { "Chaos Caboose", 21 }, { "Three In One", 22 }, { "Auto Recall", 23 } }; } [BepInPlugin("very_very_valet_ap_client", "VeryVeryValetAPClient", "1.0.2")] public class PluginMain : BaseUnityPlugin { public static ConfigEntry? EnableDebugLogging; public static ConfigEntry? FilterLog; public static ConfigEntry? MessageInTime; public static ConfigEntry? MessageHoldTime; public static ConfigEntry? MessageOutTime; public const string GameName = "Very Very Valet"; private const string PluginName = "VeryVeryValetAPClient"; private const string GUID = "very_very_valet_ap_client"; private const string Version = "1.0.2"; private readonly Harmony _harmony = new Harmony("very_very_valet_ap_client"); public static ManualLogSource? logger; public static ArchipelagoHandler? ArchipelagoHandler; public static SlotData? SlotData; public static ConnectInputHandler? ConnectInputHandler; public static ItemHandler? ItemHandler; private void Awake() { logger = ((BaseUnityPlugin)this).Logger; _harmony.PatchAll(); Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject); SceneManager.sceneLoaded += delegate { }; ArchipelagoHandler = ((Component)this).gameObject.AddComponent(); ConnectInputHandler = ((Component)this).gameObject.AddComponent(); ItemHandler = ((Component)this).gameObject.AddComponent(); EnableDebugLogging = ((BaseUnityPlugin)this).Config.Bind("Logging", "EnableDebugLogging", false, "Enables or disables debug logging in the Archipelago Console."); FilterLog = ((BaseUnityPlugin)this).Config.Bind("Logging", "FilterLog", false, "Filter the archipelago log to only show messages relevant to you."); MessageInTime = ((BaseUnityPlugin)this).Config.Bind("Logging", "MessageInTime", 0.25f, "How long messages take to animate in."); MessageHoldTime = ((BaseUnityPlugin)this).Config.Bind("Logging", "MessageHoldTime", 3f, "How long messages stay in the log before animating out."); MessageOutTime = ((BaseUnityPlugin)this).Config.Bind("Logging", "MessageOutTime", 0.5f, "How long messages take to animate out."); } } public class SlotData { public readonly bool LimitStars; public readonly bool RequireRedStars; public readonly bool RequireLevelCompletions; public readonly Dictionary LevelMap; public readonly Dictionary BonusMap; public readonly Dictionary FinalMap; public readonly bool DeathLink; public SlotData(Dictionary slotDict) { foreach (KeyValuePair item in slotDict) { APConsole.Instance.DebugLog($"{item.Key} {item.Value}"); } if (slotDict.TryGetValue("LimitStars", out object value) && value is long num) { LimitStars = num == 1; } if (slotDict.TryGetValue("RequireRedStars", out object value2) && value2 is long num2) { RequireRedStars = num2 == 1; } if (slotDict.TryGetValue("RequireLevelCompletions", out object value3) && value3 is long num3) { RequireLevelCompletions = num3 == 1; } if (slotDict.TryGetValue("LevelMapping", out object value4)) { JObject val = (JObject)((value4 is JObject) ? value4 : null); if (val != null) { LevelMap = ((JToken)val).ToObject>() ?? new Dictionary(); goto IL_0148; } } LevelMap = new Dictionary(); goto IL_0148; IL_01da: if (slotDict.TryGetValue("DeathLink", out object value5) && value5 is long) { long num4 = (long)value5; if (true) { DeathLink = num4 == 1; } } return; IL_0191: if (slotDict.TryGetValue("FinalMapping", out object value6)) { JObject val2 = (JObject)((value6 is JObject) ? value6 : null); if (val2 != null) { FinalMap = ((JToken)val2).ToObject>() ?? new Dictionary(); goto IL_01da; } } FinalMap = new Dictionary(); goto IL_01da; IL_0148: if (slotDict.TryGetValue("BonusMapping", out object value7)) { JObject val3 = (JObject)((value7 is JObject) ? value7 : null); if (val3 != null) { BonusMap = ((JToken)val3).ToObject>() ?? new Dictionary(); goto IL_0191; } } BonusMap = new Dictionary(); goto IL_0191; } } } namespace VeryVeryValetAPClient.Hooks { [HarmonyPatch(typeof(LevelController))] public class LevelController_Patches { [HarmonyPatch("OnTractorPenalty")] [HarmonyPrefix] public static void OnTractorPenalty(LevelController __instance, Vector3 position) { if (PluginMain.SlotData.DeathLink) { PluginMain.ArchipelagoHandler.SendDeath(); } } [HarmonyPatch("CraneEject")] [HarmonyPrefix] [HarmonyPatch(new Type[] { typeof(Car) })] public static void OnCraneEject(Car car) { if (PluginMain.SlotData.DeathLink) { PluginMain.ArchipelagoHandler.SendDeath(); } } } [HarmonyPatch(typeof(MapManager))] public class MapManager_Patches { [HarmonyPatch("Init")] [HarmonyPrefix] private static void OnInit(MapManager __instance) { ArchipelagoHandler? archipelagoHandler = PluginMain.ArchipelagoHandler; if (archipelagoHandler == null || !archipelagoHandler.IsConnected) { return; } LevelMap data = __instance._data; List list = data._sections.Skip(1).SelectMany((LevelMapSection s) => s.levels).ToList(); List source = BuildNormalizedIndices(); Dictionary dictionary = source.Select((int vanillaIndex, int normalizedIndex) => new { vanillaIndex, normalizedIndex }).ToDictionary(x => x.vanillaIndex, x => x.normalizedIndex); Entry[] array = (Entry[])(object)new Entry[list.Count]; for (int i = 0; i < list.Count; i++) { int num = dictionary[i]; array[num] = list[i]; } Dictionary dictionary2 = source.Select((int vanillaIndex, int normalizedIndex) => new { name = LevelOrderHandler.LevelNumberToName[vanillaIndex].Name, normalizedIndex = normalizedIndex }).ToDictionary(x => x.name, x => x.normalizedIndex); Entry[] array2 = (Entry[])(object)new Entry[array.Length]; for (int j = 0; j < list.Count; j++) { int num2 = dictionary[j]; APLevelData aPLevelData = LevelOrderHandler.LevelNumberToName[j]; APLevelType type = aPLevelData.Type; if (1 == 0) { } string text = type switch { APLevelType.Level => PluginMain.SlotData?.LevelMap[aPLevelData.Name], APLevelType.Bonus => PluginMain.SlotData?.BonusMap[aPLevelData.Name], APLevelType.Final => PluginMain.SlotData?.FinalMap[aPLevelData.Name], _ => null, }; if (1 == 0) { } string text2 = text; if (text2 != null) { int num3 = dictionary2[text2]; array2[num2] = array[num3]; } } int num4 = 0; for (int k = 1; k < data._sections.Length; k++) { LevelMapSection val = data._sections[k]; for (int l = 0; l < val.levels.Length; l++) { val.levels[l] = array2[num4++]; } } num4 = 0; LevelData val2 = null; for (int m = 1; m < data._sections.Length; m++) { LevelMapSection val3 = data._sections[m]; for (int n = 0; n < val3.levels.Length; n++) { MapTerminalEntry val4 = __instance._terminals[m]._entries[n]; int num5 = 2 * num4; if (num5 > 0) { FaceData val5 = val4._spindleTitle._faces[4]; val5.text.SetKey("locked", Array.Empty()); ((Behaviour)val5.text).enabled = true; ((Behaviour)val5.text.m_Text).enabled = true; MapTerminalSpindle val6 = val4._spindleStars[0]; val6.SetFace((Face)4, true, (StarType)0); FaceData val7 = val4._spindleStars[1]._faces[4]; val7.text.SetKey("generic_key", Array.Empty()); val7.text.m_Text.text = ((num5 < 10) ? "0" : num5.ToString()[0].ToString()); ((Behaviour)val7.text.m_Text).enabled = true; FaceData val8 = val4._spindleStars[2]._faces[4]; val8.text.SetKey("generic_key", Array.Empty()); val8.text.m_Text.text = ((num5 < 10) ? num5.ToString() : num5.ToString()[1].ToString()); ((Behaviour)val8.text.m_Text).enabled = true; val3.levels[n].starCount = num5; } if ((Object)(object)val2 != (Object)null) { val3.levels[n].prereqs = (LevelData[])(object)new LevelData[1] { val2 }; } else { val3.levels[n].prereqs = (LevelData[])(object)new LevelData[0]; } val2 = val3.levels[n].data; num4++; } } } private static List BuildNormalizedIndices() { List list = new List(); for (int i = 0; i < 4; i++) { int num = i * 6; List list2 = new List(); int item = -1; int item2 = -1; for (int j = 0; j < 6; j++) { int num2 = num + j; switch (LevelOrderHandler.LevelNumberToName[num2].Type) { case APLevelType.Level: list2.Add(num2); break; case APLevelType.Bonus: item = num2; break; case APLevelType.Final: item2 = num2; break; } } list.AddRange(list2); list.Add(item); list.Add(item2); } return list; } [HarmonyPatch("GetDisplayStarCount")] [HarmonyPrefix] public static bool GetDisplayStarCount(ref int __result) { __result = PluginMain.ArchipelagoHandler.GetReceivedStarCount(); return false; } } [HarmonyPatch(typeof(MapTerminalEntry))] public class MapTerminalEntry_Patches { [HarmonyPatch("Refresh")] [HarmonyPrefix] private static bool Refresh(MapTerminalEntry __instance, bool instant = true, bool debugUnlock = false, bool updateVisuals = true) { //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0125: 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_0133: Unknown result type (might be due to invalid IL or missing references) MapManager val = Object.FindObjectOfType(); if ((Object)(object)val == (Object)null || (PluginMain.SlotData.RequireLevelCompletions && (Object)(object)__instance.data != (Object)(object)val.data._sections[1].levels[0].data)) { return true; } __instance._isGated = __instance._entry.starCount > 0; __instance._animState = (AnimState)0; __instance._isRevealed = true; __instance._startStarList = null; __instance._finalStarList = null; __instance._isCompleted = PlayerSave.GetLevelHasBeenCompleted(__instance.data.saveKey); LevelCompleteData levelCompleteData = PlayerSave.GetLevelCompleteData(__instance.data.saveKey); if (levelCompleteData != null) { __instance._finalStarList = levelCompleteData.GetStarListCombined(); } MapEntry mapEntry = PlayerSave.GetMapEntry(__instance.data.saveKey); if (mapEntry != null) { __instance._isRevealed = mapEntry.isRevealed; __instance._isGated = mapEntry.isGated; __instance._startStarList = mapEntry.lastStarList; } __instance.SetDisplay(__instance._entry.entryType, __instance._startStarList); Face val2 = __instance._entry.entryType; if (__instance.isGated) { val2 = (Face)4; } __instance.ShowFace(val2, instant, 0); return false; } } [HarmonyPatch(typeof(PlayerSave))] public class PlayerSave_Patches { public static readonly char[] APHeader = new char[4] { 'A', 'P', 'C', 'M' }; [HarmonyPatch("GetSaveFolder")] [HarmonyPrefix] public static bool GetSaveFolder(ref string __result) { __result = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "ArchipelagoSaves"); return false; } [HarmonyPatch("_getFilenameForSlot")] [HarmonyPrefix] public static bool _getFilenameForSlot(int slot, ref string __result) { __result = "Save_" + PluginMain.ArchipelagoHandler.Slot + "_" + PluginMain.ArchipelagoHandler.seed + ".sav"; return false; } [HarmonyPatch("GetTotalStarsEarned")] [HarmonyPatch(new Type[] { typeof(StarFilter) })] [HarmonyPrefix] public static bool OnGetTotalStarsEarned(StarFilter filter, ref int __result) { __result = PluginMain.ArchipelagoHandler.GetReceivedStarCount(); return false; } [HarmonyPatch("SaveLevelComplete")] [HarmonyPostfix] public static void OnSaveLevelComplete(string shortLevelName, SaveLevelResult __result) { if (!LevelOrderHandler.SaveKeyToLevelName.TryGetValue(shortLevelName, out string value)) { Console.WriteLine(shortLevelName); return; } int starCount = __result.starCount; int num = LevelOrderHandler.LevelNameToNormalizedNumber[value]; if (num == 23) { APConsole.Instance.Log("GOAL!!!"); PluginMain.ArchipelagoHandler.Release(); return; } int num2 = 256 + num * 3; List list = new List(); for (int i = 0; i < starCount; i++) { list.Add(num2 + i); } PluginMain.ArchipelagoHandler.CheckLocations(list.ToArray()); } [HarmonyPatch("_save")] [HarmonyPostfix] public static void _save(string filename) { CustomSaveDataHandler.Save(); } [HarmonyPatch("_actuallyLoad")] [HarmonyPostfix] public static void _actuallyLoad(string filename) { CustomSaveDataHandler.Load(); } } [HarmonyPatch(typeof(PowerupSpawner))] public class PowerupSpawner_Patches { [HarmonyPatch("OnLevelStart")] [HarmonyPostfix] public static void OnOnLevelStart(PowerupSpawner __instance) { if (CustomSaveDataHandler.Data.StoredPowerups > 0) { CustomSaveDataHandler.Data.StoredPowerups--; ((BasicSpawner)__instance).Spawn(); } } } [HarmonyPatch(typeof(ScreenUI_LevelBriefing))] public class ScreenUI_LevelBriefing_Patches { [HarmonyPatch("SetDisplayText")] [HarmonyPostfix] [HarmonyPatch(new Type[] { typeof(LevelData) })] public static void SetDisplayText(ScreenUI_LevelBriefing __instance, LevelData data) { //IL_0074: Unknown result type (might be due to invalid IL or missing references) __instance._allowRuleSets = false; ActiveSceneManager.instance.gameRuleDictionary.GetCurrentPreset(); ScreenUI_OptionsMain val = Object.FindObjectOfType(); string displayKey = (PluginMain.SlotData.RequireRedStars ? "difficulty_hard" : "difficulty_normal"); if ((Object)(object)val != (Object)null) { GameRuleDifficultyPresetData val2 = ((IEnumerable)((ScreenUI_OptionsBase)val)._ruleDictionary._presets).FirstOrDefault((Func)((GameRuleDifficultyPresetData x) => x._displayKey == displayKey)); ((ScreenUI_OptionsBase)val).SetPreset(val2); PlayerSave.SavePreset(data.objective, val2); if (((ScreenUI_OptionsBase)val).RefreshCheckmarks()) { ((ScreenUI_OptionsBase)val)._toasterUi.Toast(((ScreenUI_OptionsBase)val)._toastDifficultyChangedKey, 0f, new object[1] { val2.displayTranslated }); } } } } public class ConnectInputHandler : MonoBehaviour { public static bool IsInputMode = false; private static bool inputModeRequested = false; private static TextMeshProUGUI? currentText = null; private static Stack savedMaps = new Stack(); private static void DisableInput() { foreach (Player player in ReInput.players.Players) { foreach (ControllerMap item in from x in player.controllers.maps.GetAllMaps() where x.enabled select x) { savedMaps.Push(item); item.enabled = false; } } } private static void EnableInput() { while (savedMaps.Count > 0) { ControllerMap val = savedMaps.Pop(); val.enabled = true; } } public static void InitializeInputMode(TextMeshProUGUI text) { inputModeRequested = true; currentText = text; DisableInput(); } private static void CompleteInput() { IsInputMode = false; currentText = null; EnableInput(); } private static void ProcessInput(char c) { if (IsInputMode) { if (c == '\b' && ((TMP_Text)currentText).text.Length > 0) { ((TMP_Text)currentText).text = ((TMP_Text)currentText).text.Substring(0, ((TMP_Text)currentText).text.Length - 1); } if (!char.IsControl(c)) { TextMeshProUGUI? obj = currentText; ((TMP_Text)obj).text = ((TMP_Text)obj).text + c; } } } private void Update() { if (IsInputMode) { string inputString = Input.inputString; foreach (char c in inputString) { ProcessInput(c); } if (Input.GetKeyDown((KeyCode)13)) { CompleteInput(); } } if (!IsInputMode && inputModeRequested) { IsInputMode = true; inputModeRequested = false; } } } [HarmonyPatch(typeof(ScreenUI_SaveSelect))] public class ScreenUI_SaveSelect_Patches { private static TMP_FontAsset? font; [HarmonyPatch("Init")] [HarmonyPrefix] private static void OnInit(ScreenUI_SaveSelect __instance) { Transform child = ((Component)((SplitScreenUI)__instance)._rootGroup).gameObject.transform.GetChild(0); if (((Component)((SplitScreenUI)__instance)._rootGroup).transform.childCount != 4) { APConsole.Instance.Log("Welcome to Very Very Valet Archipelago!"); font = Resources.FindObjectsOfTypeAll().First((TMP_FontAsset x) => ((Object)x).name == "Text-regular"); Object.Instantiate(child, ((Component)((SplitScreenUI)__instance)._rootGroup).transform); } } [HarmonyPatch("ScreenShow")] [HarmonyPostfix] private static void OnScreenShow(ScreenUI_SaveSelect __instance, bool doShow) { //IL_03aa: Unknown result type (might be due to invalid IL or missing references) //IL_03b4: Expected O, but got Unknown //IL_03c2: Unknown result type (might be due to invalid IL or missing references) //IL_03cc: Expected O, but got Unknown //IL_03cf: Unknown result type (might be due to invalid IL or missing references) //IL_03d9: Expected O, but got Unknown //IL_03e8: Unknown result type (might be due to invalid IL or missing references) //IL_03f2: Expected O, but got Unknown //IL_03f5: Unknown result type (might be due to invalid IL or missing references) //IL_03ff: Expected O, but got Unknown //IL_040e: Unknown result type (might be due to invalid IL or missing references) //IL_0418: Expected O, but got Unknown //IL_041b: Unknown result type (might be due to invalid IL or missing references) //IL_0425: Expected O, but got Unknown //IL_0434: Unknown result type (might be due to invalid IL or missing references) //IL_043e: Expected O, but got Unknown ScreenUI_SaveSelect __instance2 = __instance; if (!doShow) { return; } Transform child = ((Component)((SplitScreenUI)__instance2)._rootGroup).gameObject.transform.GetChild(0); Button component = ((Component)child).GetComponent