using Archipelago.MultiClient.Net; using Archipelago.MultiClient.Net.Enums; using Archipelago.MultiClient.Net.Models; using Archipelago.MultiClient.Net.Packets; using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; using UnityEngine.SceneManagement; using static ManifoldGardenArchipelago.GameData; namespace ManifoldGardenArchipelago { public class ArchipelagoManager { private ArchipelagoSession _session; private int _itemIndex = 0; public Dictionary> chainListenersByScene = new(); public ArchipelagoManager() { foreach (var item in GameData.door_by_item) { foreach (var chainListenerReference in item.Value) { if (!chainListenersByScene.TryGetValue(chainListenerReference.scene, out var listenersInScene)) { listenersInScene = []; chainListenersByScene.Add(chainListenerReference.scene, listenersInScene); } listenersInScene[chainListenerReference.index] = false; } } } public async Task Connect(string url, string slotName, string password) { LoginResult result; try { _session = ArchipelagoSessionFactory.CreateSession(url); RoomInfoPacket roomInfoPacket = await _session.ConnectAsync(); result = await _session.LoginAsync("Manifold Garden", slotName, ItemsHandlingFlags.AllItems, null, null, null, password == "" ? null : password); } catch (Exception ex) { return new LoginFailure(ex.GetBaseException().Message); } return result; } ~ArchipelagoManager() { Disconnect(); } public void Disconnect() { if (_session == null) { return; } _session.Socket.DisconnectAsync(); _session = null; } public void Update() { if (_session == null) { return; } if (_session.Items.AllItemsReceived.Count > _itemIndex) { for (int i = _itemIndex; i < _session.Items.AllItemsReceived.Count; i++) { ItemInfo item = _session.Items.AllItemsReceived[i]; string itemName = item.ItemName; if (GameData.door_by_item.TryGetValue(itemName, out List door)) { foreach (GameData.ChainListenerReference chainListenerReference in door) { chainListenersByScene[chainListenerReference.scene][chainListenerReference.index] = true; if (SceneManager.GetSceneByName(chainListenerReference.scene) is Scene doorScene && doorScene.isLoaded) { LevelSystems levelSystems = doorScene.GetRootGameObjects().Single((obj) => obj.name == "Level Systems").GetComponent(); if (levelSystems.isActiveAndEnabled) { LineDoorController ldc = levelSystems.chainListeners[chainListenerReference.index].GetComponent(); ldc.chains.Clear(); FieldInfo fieldInfo = typeof(LineDoorController).GetField("doorShouldOpenImmediatelyOnEnable", BindingFlags.Instance | BindingFlags.NonPublic); fieldInfo.SetValue(ldc, true); MethodInfo methodInfo = typeof(LineDoorController).GetMethod("SetDoorOpenCloseStateAnimated", BindingFlags.NonPublic | BindingFlags.Instance); methodInfo.Invoke(ldc, [true, false]); } } } } } _itemIndex = _session.Items.AllItemsReceived.Count; /* var hi = new StringBuilder(); foreach (var thing in chainListenersByScene) { hi.AppendLine(thing.Key); foreach (var thing2 in thing.Value) { hi.AppendLine($" {thing2.Key}: {thing2.Value}"); } } Plugin.Logger.LogInfo( hi.ToString() ); */ } } } }