using Archipelago.MultiClient.Net; using Archipelago.MultiClient.Net.Enums; using Archipelago.MultiClient.Net.MessageLog.Messages; using Archipelago.MultiClient.Net.Models; using Archipelago.MultiClient.Net.Packets; using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; using System.Threading.Tasks; namespace ManifoldGardenArchipelago { public class ArchipelagoManager { private ArchipelagoSession _session; private int _itemIndex = 0; private HashSet _items = []; private HashSet _locations = []; private bool _roomShuffle = false; public bool RoomShuffle => _roomShuffle; public Dictionary EntranceMapping = []; public async Task Connect(string url, string slotName, string password) { LoginResult result; try { _session = ArchipelagoSessionFactory.CreateSession(url); _session.MessageLog.OnMessageReceived += OnMessageReceived; RoomInfoPacket roomInfoPacket = await _session.ConnectAsync(); result = await _session.LoginAsync("Manifold Garden", slotName, ItemsHandlingFlags.AllItems, null, null, null, password == "" ? null : password); } catch (Exception ex) { Plugin.Logger.LogError(ex.GetBaseException().Message); return new LoginFailure(ex.GetBaseException().Message); } LoginSuccessful login = result as LoginSuccessful; if (login.SlotData.ContainsKey("connections")) { _roomShuffle = true; foreach (var connection in (JArray)login.SlotData["connections"]) { var connList = (JArray)connection; EntranceIdentifier ei1 = new((string)connList[0], (string)connList[1]); EntranceIdentifier ei2 = new((string)connList[2], (string)connList[3]); EntranceMapping[ei1] = ei2; EntranceMapping[ei2] = ei1; } } return result; } ~ArchipelagoManager() { Disconnect(); } public void Disconnect() { if (_session == null) { return; } _session.Socket.DisconnectAsync(); _session = null; } public bool HasItem(string itemName) { return _items.Contains(itemName); } public void CheckLocation(string locationName) { if (_locations.Contains(locationName)) { return; } _locations.Add(locationName); _session.Locations.CompleteLocationChecks(_session.Locations.GetLocationIdFromName("Manifold Garden", locationName)); } public void SendGoal() { _session.Socket.SendPacket(new StatusUpdatePacket() { Status = ArchipelagoClientState.ClientGoal, }); Plugin.notificationManager.AddMessage("You completed your goal!"); } 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; Plugin.Logger.LogInfo($"Received {itemName}"); Plugin.notificationManager.AddMessage($"Received {itemName}"); _items.Add(itemName); if (GameData.listenersByItem.TryGetValue(itemName, out var listeners)) { //Plugin.Logger.LogInfo($"Evaluating for {itemName}"); GameState.EvaluateGameStateListeners(listeners); } } _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() ); */ } } private void OnMessageReceived(LogMessage message) { if (message is ItemSendLogMessage itemSendLogMessage && itemSendLogMessage.IsSenderTheActivePlayer && !itemSendLogMessage.IsReceiverTheActivePlayer) { string itemName = itemSendLogMessage.Item.ItemName; string otherPlayer = itemSendLogMessage.Receiver.Name; string messageText = $"Sent {itemName} to {otherPlayer}"; Plugin.notificationManager.AddMessage(messageText); } } } }