Decompiled source of EasyDeliveryCoArchipelago v0.3.0
BepInEx/plugins/EasyDeliveryAP/EasyDeliveryAP.dll
Decompiled 12 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Threading; using Archipelago.MultiClient.Net; using Archipelago.MultiClient.Net.BounceFeatures.DeathLink; using Archipelago.MultiClient.Net.Enums; using Archipelago.MultiClient.Net.Helpers; using Archipelago.MultiClient.Net.MessageLog.Messages; using Archipelago.MultiClient.Net.Models; using Archipelago.MultiClient.Net.Packets; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using EasyDeliveryAP.Archipelago; using EasyDeliveryAP.Utils; using EasyDeliveryAPI; using HarmonyLib; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using UnityEngine; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [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] [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; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace Archipelago.MultiClient.Net { [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, Inherited = false, AllowMultiple = false)] internal sealed class DataStoragePropertyAttribute : Attribute { public string? SessionVariable { get; } public Scope Scope { get; } public string Key { get; } public DataStoragePropertyAttribute(string sessionVariable, Scope scope, string key) { //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) SessionVariable = sessionVariable; Scope = scope; Key = key; } public DataStoragePropertyAttribute(string sessionVariable, string key) : this(sessionVariable, (Scope)0, key) { } } } namespace EasyDeliveryAP { internal struct APSaveFile { public int handledIndex; public string APSeed; public string uri; public string slotName; public string password; public string modVersion; } public class APData { private static readonly ArchipelagoClient archipelago = EasyDeliveryAP.ArchipelagoClient; public static string payload_checks; public static string perfect_deliveries; public static string intercity_deliveries; public static string snowcats; public static string blind_bags; public static string lock_towns; public static string blocked_tunnels; public static string require_handheld_radio; public static string radio_towers; public static string car_upgrades; public static string progressive_car_upgrades; public static int car_trail_color; public static string vending_machines; public static string garbage_bins; public static string signs; public static Hint[] hints; public static void SetSlotSettings(Dictionary<string, object> slotData) { slotData.TryGetValue("payload_checks", out var value); payload_checks = value.ToString(); slotData.TryGetValue("perfect_deliveries", out var value2); perfect_deliveries = value2.ToString(); slotData.TryGetValue("intercity_deliveries", out var value3); intercity_deliveries = value3.ToString(); slotData.TryGetValue("snowcats", out var value4); snowcats = value4.ToString(); slotData.TryGetValue("blind_bags", out var value5); blind_bags = value5.ToString(); slotData.TryGetValue("lock_towns", out var value6); lock_towns = value6.ToString(); slotData.TryGetValue("blocked_tunnels", out var value7); blocked_tunnels = value7.ToString(); slotData.TryGetValue("require_handheld_radio", out var value8); require_handheld_radio = value8.ToString(); slotData.TryGetValue("radio_towers", out var value9); radio_towers = value9.ToString(); slotData.TryGetValue("car_upgrades", out var value10); car_upgrades = value10.ToString(); if (slotData.TryGetValue("progressive_car_upgrades", out var value11)) { progressive_car_upgrades = value11.ToString(); } else { progressive_car_upgrades = "0"; } if (slotData.TryGetValue("randomize_trail_color", out var value12)) { car_trail_color = int.Parse(value12.ToString()); } else { car_trail_color = 16777215; } if (slotData.TryGetValue("vending_machines", out var value13)) { vending_machines = value13.ToString(); } else { vending_machines = "0"; } if (slotData.TryGetValue("garbage_bins", out var value14)) { garbage_bins = value14.ToString(); } else { garbage_bins = "0"; } if (slotData.TryGetValue("signs", out var value15)) { signs = value15.ToString(); } else { signs = "0"; } if (intercity_deliveries == "2" || intercity_deliveries == "3") { TrackerApp.pages.Add(2); } if (payload_checks == "1") { TrackerApp.pages.Add(3); } if (snowcats == "1" || snowcats == "2") { TrackerApp.pages.Add(4); } if (blind_bags == "1") { TrackerApp.pages.Add(5); } if (radio_towers == "1" || radio_towers == "2") { TrackerApp.pages.Add(6); } if (vending_machines == "1") { TrackerApp.pages.Add(7); } if (garbage_bins == "1") { TrackerApp.pages.Add(8); } if (signs == "1") { TrackerApp.pages.Add(9); } } public static void SaveConnectionOrConnect() { if (ArchipelagoClient.Authenticated) { EasyDeliveryAP.save.data.uri = ArchipelagoClient.ServerData.Uri; EasyDeliveryAP.save.data.slotName = ArchipelagoClient.ServerData.SlotName; EasyDeliveryAP.save.data.password = ArchipelagoClient.ServerData.Password; EasyDeliveryAP.save.data.modVersion = "0.3.0"; EasyDeliveryAP.save.data.APSeed = ArchipelagoClient.ServerData.seed; } else if (!Utility.IsNullOrWhiteSpace(EasyDeliveryAP.save.data.slotName) && EasyDeliveryAP.configAutoConnect.Value) { ArchipelagoClient.ServerData.Uri = EasyDeliveryAP.save.data.uri; ArchipelagoClient.ServerData.SlotName = EasyDeliveryAP.save.data.slotName; ArchipelagoClient.ServerData.Password = EasyDeliveryAP.save.data.password; archipelago.Connect(); } } public static void OnHintsReceived(Hint[] hint) { hints = hint; } public static bool IsHinted(int locationId, bool hinted = false) { if (hinted) { return true; } Hint[] array = hints; foreach (Hint val in array) { if (val.FindingPlayer == archipelago.session.Players.ActivePlayer.Slot && val.LocationId == locationId) { return true; } } return false; } } public class ItemData { public string Name { get; set; } public int Id { get; set; } public int Received { get; set; } public bool Enabled { get; set; } public bool Toggle { get; set; } public int Given { get; set; } public ItemData() { } public ItemData(string name) { Name = name; Id = -1; Received = 0; Enabled = false; Toggle = false; Given = 0; } public ItemData(string name, int id) { Name = name; Id = id; Received = 0; Enabled = false; Toggle = false; Given = 0; } } public class Items { public static ItemData GPS = new ItemData("Map"); public static ItemData Tires = new ItemData("Snow Tires"); public static ItemData Bumper = new ItemData("Bumper"); public static ItemData Chains = new ItemData("Ice Chains"); public static ItemData ProgCarUpgrade = new ItemData("Progressive Car Upgrade"); public static ItemData EnergyDrink = new ItemData("Energy Drink", 0); public static ItemData EmptyCan = new ItemData("Empty Can", 1); public static ItemData Lantern = new ItemData("Lantern", 2); public static ItemData Lighter = new ItemData("Lighter", 3); public static ItemData Firewood = new ItemData("Firewood", 4); public static ItemData Shovel = new ItemData("Shovel", 5); public static ItemData BirdSeed = new ItemData("Bird Seed", 6); public static ItemData CookingPot = new ItemData("Cooking Pot", 7); public static ItemData Coffee = new ItemData("Coffee", 8); public static ItemData CoffeePowder = new ItemData("Coffee Powder", 9); public static ItemData Tea = new ItemData("Tea", 10); public static ItemData TeaBags = new ItemData("Tea Bags", 11); public static ItemData Fish = new ItemData("Fish", 12); public static ItemData FishingRod = new ItemData("Fishing Rod", 13); public static ItemData FishSoup = new ItemData("Fish Soup", 14); public static ItemData DuctTape = new ItemData("Duct Tape", 15); public static ItemData RestoreDisc = new ItemData("Restore Disc", 16); public static ItemData HandheldRadio = new ItemData("Handheld Radio", 17); public static ItemData IceTrap = new ItemData("Ice Trap"); public static ItemData ShrinkTrap = new ItemData("Shrink Trap"); public static ItemData FrozenSteeringWheelTrap = new ItemData("Frozen Steering Wheel Trap"); public static ItemData ForcedAccelerationTrap = new ItemData("Forced Acceleration Trap"); public static ItemData TunnelSP = new ItemData("Snowy Peaks Tunnel"); public static ItemData TunnelFT = new ItemData("Fishing Town Tunnel"); public static ItemData TunnelFactory = new ItemData("Factory Tunnel"); public static ItemData Upton = new ItemData("Upton"); public static ItemData Weston = new ItemData("Weston"); public static ItemData Easton = new ItemData("Easton"); public static ItemData Winton = new ItemData("Winton"); public static ItemData Munton = new ItemData("Munton"); public static ItemData Lopton = new ItemData("Lopton"); public static ItemData Clifton = new ItemData("Clifton"); public static ItemData Damton = new ItemData("Damton"); public static ItemData Smalton = new ItemData("Smalton"); public static ItemData Money = new ItemData("Money"); public static ItemData RadioTower = new ItemData("Radio Tower"); public static Dictionary<int, ItemData> APIdToItem = new Dictionary<int, ItemData> { { 1, GPS }, { 2, Tires }, { 3, Bumper }, { 4, Chains }, { 5, ProgCarUpgrade }, { 10, Money }, { 11, TunnelSP }, { 12, TunnelFT }, { 13, TunnelFactory }, { 20, RadioTower }, { 30, Upton }, { 31, Weston }, { 32, Easton }, { 33, Winton }, { 34, Munton }, { 35, Lopton }, { 36, Clifton }, { 37, Damton }, { 38, Smalton }, { 100, EnergyDrink }, { 101, EmptyCan }, { 102, Lantern }, { 103, Lighter }, { 104, Firewood }, { 105, Shovel }, { 106, BirdSeed }, { 107, CookingPot }, { 108, Coffee }, { 109, CoffeePowder }, { 110, Tea }, { 111, TeaBags }, { 112, Fish }, { 113, FishingRod }, { 114, FishSoup }, { 115, DuctTape }, { 116, RestoreDisc }, { 117, HandheldRadio }, { 130, IceTrap }, { 131, ShrinkTrap }, { 132, FrozenSteeringWheelTrap }, { 133, ForcedAccelerationTrap } }; public static Dictionary<string, ItemData> NameToItem = new Dictionary<string, ItemData> { { "Upton", Upton }, { "Weston", Weston }, { "Easton", Easton }, { "Winton", Winton }, { "Munton", Munton }, { "Lopton", Lopton }, { "Clifton", Clifton }, { "Damton", Damton }, { "Smalton", Smalton } }; public static Dictionary<string, ItemData> TunnelToItem = new Dictionary<string, ItemData> { { "Snowy Peaks", TunnelSP }, { "Fishing Town", TunnelFT } }; public static Dictionary<string, ItemData> TownToItem = new Dictionary<string, ItemData> { { "Upton", Upton }, { "Weston", Weston }, { "Easton", Easton }, { "Winton", Winton }, { "Munton", Munton }, { "Lopton", Lopton }, { "Clifton", Clifton }, { "Damton", Damton }, { "Smalton", Smalton } }; } public class Locations { public class MountainTown { public static NodeData EasyFlowers = new NodeData("Easy Flowers", "Upton", 0); public static NodeData Node57 = new NodeData("Node (57)", "Upton", 1); public static NodeData Node48 = new NodeData("Node (48)", "Upton", 2); public static NodeData Node56 = new NodeData("Node (56)", "Upton", 3); public static NodeData Node55 = new NodeData("Node (55)", "Upton", 4); public static NodeData EasyEats = new NodeData("Easy Eats", "Upton", 5); public static NodeData Node47 = new NodeData("Node (47)", "Upton", 6); public static NodeData Node54 = new NodeData("Node (54)", "Upton", 7); public static NodeData Node5 = new NodeData("Node (5)", "Weston", 8); public static NodeData EZBakery = new NodeData("EZ Bakery", "Weston", 9); public static NodeData Node59 = new NodeData("Node (59)", "Weston", 10); public static NodeData Node60 = new NodeData("Node (60)", "Weston", 11); public static NodeData Bar1 = new NodeData("Bar", "Weston", 12); public static NodeData EasyDepot = new NodeData("Node (57)", "Weston", 13); public static NodeData Bar2 = new NodeData("Bar 2", "Weston", 14); public static NodeData EZCafe = new NodeData("EZ Cafe", "Weston", 15); public static NodeData Node65 = new NodeData("Node (65)", "Weston", 16); public static NodeData Node71 = new NodeData("Node (71)", "Easton", 17); public static NodeData Node72 = new NodeData("Node (72)", "Easton", 18); public static NodeData EasyPizza = new NodeData("Easy Pizza", "Easton", 19); public static NodeData Node74 = new NodeData("Node (74)", "Easton", 20); public static NodeData PawnShop = new NodeData("Pawn Shop", "Easton", 21); public static NodeData EZAuto = new NodeData("EZ Auto", "Easton", 22); public static NodeData EZMart = new NodeData("EZ Mart", "Easton", 23); public static NodeData Node92 = new NodeData("Node (92)", "Upton", 24); public static NodeData Node93 = new NodeData("Node (93)", "Upton", 25); public static PositionData VMUEats = new PositionData("VMUEats", "Upton", 100, "Vending Machine"); public static PositionData RBUFlowers = new PositionData("RBUFlowers", "Upton", 121, "Bin"); public static PositionData BBUFlowers = new PositionData("BBUFlowers", "Upton", 122, "Bin"); public static PositionData BBUFlowersEats = new PositionData("BBUFlowersEats", "Upton", 123, "Bin"); public static PositionData BBUEats = new PositionData("BBUEats", "Upton", 124, "Bin"); public static PositionData RBUEats = new PositionData("RBUEats", "Upton", 125, "Bin"); public static PositionData RBUTownEdge = new PositionData("RBUTownEdge", "Upton", 126, "Bin"); public static PositionData BBWEntry = new PositionData("BBWEntry", "Weston", 127, "Bin"); public static PositionData RBWEntry = new PositionData("RBWEntry", "Weston", 128, "Bin"); public static PositionData BBWBakeryAcross = new PositionData("BBWBakeryAcross", "Weston", 129, "Bin"); public static PositionData RBWBakeryLeft = new PositionData("RBWBakeryLeft", "Weston", 130, "Bin"); public static PositionData BBWBakeryLeft = new PositionData("BBWBakeryLeft", "Weston", 131, "Bin"); public static PositionData RBWBarTunnel = new PositionData("RBWBarTunnel", "Weston", 132, "Bin"); public static PositionData VMWBarTunnel = new PositionData("VMWBarTunnel", "Weston", 101, "Vending Machine"); public static PositionData BBWDepot = new PositionData("BBWDepot", "Weston", 133, "Bin"); public static PositionData BBWBarLower = new PositionData("BBWBarLower", "Weston", 134, "Bin"); public static PositionData RBWCafe = new PositionData("RBWCafe", "Weston", 135, "Bin"); public static PositionData BBEMart = new PositionData("BBEMart", "Easton", 136, "Bin"); public static PositionData RBEFuel = new PositionData("RBEFuel", "Easton", 137, "Bin"); public static PositionData BBEFuel = new PositionData("BBEFuel", "Easton", 138, "Bin"); public static PositionData VMEFuel = new PositionData("VMEFuel", "Easton", 102, "Vending Machine"); public static PositionData BBEPizzaRight = new PositionData("BBEPizzaRight", "Easton", 139, "Bin"); public static PositionData RBEPizzaLeft = new PositionData("RBEPizzaLeft", "Easton", 140, "Bin"); public static PositionData SignToSP = new PositionData("Welcome to Mountain Town", "Upton", 200, "Sign"); public static PositionData SignUptonExit = new PositionData("To Weston, To Easton", "Upton", 201, "Sign"); public static PositionData SignUptonRadio = new PositionData("Upton Radio Tower", "Upton", 202, "Sign"); public static PositionData SignWestonEntryUpton = new PositionData("Weston Upper To Upton", "Weston", 203, "Sign"); public static PositionData SignWestonEntryEaston = new PositionData("Weston Upper To Easton", "Weston", 204, "Sign"); public static PositionData SignFactory = new PositionData("Factory", "Weston", 205, "Sign"); public static PositionData SignWestonExitUpton = new PositionData("Weston To Upton", "Weston", 206, "Sign"); public static PositionData SignWestonExitEaston = new PositionData("Weston To Easton", "Weston", 207, "Sign"); public static PositionData SignToEaston = new PositionData("Weston Bar", "Weston", 208, "Sign"); public static PositionData SignEastonEntry = new PositionData("Weston Bridge", "Weston", 209, "Sign"); public static PositionData SignEastonOtherEntry = new PositionData("Easton To Weston, To Upton", "Easton", 210, "Sign"); public static PositionData SignToFTLower = new PositionData("Easton Tunnel to Fishing Town", "Easton", 211, "Sign"); public static PositionData SignEastonExit = new PositionData("Easton", "Easton", 212, "Sign"); public static PositionData SignToFTUpper = new PositionData("Easton Edge Tunnel to Fishing Town", "Easton", 213, "Sign"); public static PositionData SignEastonRadio = new PositionData("Easton Radio Tower", "Easton", 214, "Sign"); public static PositionData SignToFT = new PositionData("Easton Tunnel", "Easton", 215, "Sign"); } public class SnowyPeaks { public static NodeData Destnode5 = new NodeData("Destnode5", "Lopton", 0); public static NodeData Destnode1 = new NodeData("Destnode1", "Lopton", 1); public static NodeData Destnode3 = new NodeData("Destnode3", "Lopton", 2); public static NodeData Destnode2 = new NodeData("Destnode2", "Lopton", 3); public static NodeData Destnode4 = new NodeData("Destnode4", "Lopton", 4); public static NodeData Destnode6 = new NodeData("Destnode6", "Lopton", 5); public static NodeData Destnode = new NodeData("Destnode", "Lopton", 6); public static NodeData Destnode10 = new NodeData("Destnode10", "Munton", 7); public static NodeData Destnode8 = new NodeData("Destnode8", "Lopton", 8); public static NodeData Destnode7 = new NodeData("Destnode7", "Lopton", 9); public static NodeData Destnode9 = new NodeData("Destnode9", "Winton", 10); public static NodeData EasyEats = new NodeData("Easy Eats", "Winton", 11); public static NodeData EZBakery = new NodeData("EZ Bakery", "Lopton", 12); public static NodeData EasyPizza = new NodeData("Easy Pizza", "Lopton", 13); public static NodeData EasyFlowers = new NodeData("Easy Flowers", "Winton", 14); public static NodeData Bar1 = new NodeData("Bar 1", "Munton", 15); public static NodeData EasyDepot = new NodeData("Easy Depot", "Lopton", 16); public static NodeData EZAuto = new NodeData("EZ Auto", "Munton", 17); public static NodeData EZCafe = new NodeData("EZ Cafe", "Lopton", 18); public static NodeData Bar2 = new NodeData("Bar 2", "Lopton", 19); public static NodeData EZMart = new NodeData("EZ Mart", "Munton", 20); public static NodeData PawnShop = new NodeData("Pawn Shop", "Munton", 21); public static PositionData BBWFlowers = new PositionData("BBWFlowers", "Winton", 141, "Bin"); public static PositionData RBWEats = new PositionData("RBWEats", "Winton", 142, "Bin"); public static PositionData VMWFuel = new PositionData("VMWFuel", "Winton", 103, "Vending Machine"); public static PositionData BBWFuel = new PositionData("BBWFuel", "Winton", 143, "Bin"); public static PositionData RBWFuel = new PositionData("RBWFuel", "Winton", 144, "Bin"); public static PositionData VMMAuto = new PositionData("VMMAuto", "Munton", 104, "Vending Machine"); public static PositionData RBMPawn = new PositionData("RBMPawn", "Munton", 145, "Bin"); public static PositionData RBMMart = new PositionData("RBMMart", "Munton", 146, "Bin"); public static PositionData BBMMart = new PositionData("BBMMart", "Munton", 147, "Bin"); public static PositionData VMMBar = new PositionData("VMMBar", "Munton", 105, "Vending Machine"); public static PositionData RBLBar = new PositionData("RBLBar", "Lopton", 148, "Bin"); public static PositionData VMLDepot = new PositionData("VMLDepot", "Lopton", 106, "Vending Machine"); public static PositionData RBLDepot = new PositionData("RBLDepot", "Lopton", 149, "Bin"); public static PositionData BBLDepot = new PositionData("BBLDepot", "Lopton", 150, "Bin"); public static PositionData SignToMT = new PositionData("Welcome to Snowy Peaks", "Winton", 216, "Sign"); public static PositionData SignWintonExit = new PositionData("To Munton", "Winton", 217, "Sign"); public static PositionData SignWintonEntry = new PositionData("Winton", "Winton", 218, "Sign"); public static PositionData SignMuntonEntry = new PositionData("Munton", "Munton", 219, "Sign"); public static PositionData SignMuntonBridgeWinton = new PositionData("To Winton", "Munton", 220, "Sign"); public static PositionData SignMuntonBridgeLopton = new PositionData("To Lopton", "Munton", 221, "Sign"); public static PositionData SignUpperMunton = new PositionData("Upper Munton", "Munton", 222, "Sign"); public static PositionData SignLoptonEntry = new PositionData("Lopton", "Lopton", 223, "Sign"); public static PositionData SignLoptonBridge = new PositionData("To Munton, To Winton", "Lopton", 224, "Sign"); public static PositionData SignLoptonRadio = new PositionData("Snowy Peaks Radio Tower", "Lopton", 225, "Sign"); } public class FishingTown { public static NodeData Node93 = new NodeData("Node (93)", "Clifton", 0); public static NodeData Nodedock = new NodeData("Node(dock)", "Smalton", 1); public static NodeData Node59 = new NodeData("Node (59)", "Damton", 2); public static NodeData Node101 = new NodeData("Node (101)", "Clifton", 3); public static NodeData Nodedock2 = new NodeData("Node (dock2)", "Smalton", 4); public static NodeData Node11 = new NodeData("Node (11)", "Damton", 5); public static NodeData Nodedock31 = new NodeData("Node (dock3) (1)", "Damton", 6); public static NodeData Node58 = new NodeData("Node (58)", "Damton", 7); public static NodeData Node91 = new NodeData("Node (91)", "Clifton", 8); public static NodeData Node54 = new NodeData("Node (54)", "Damton", 9); public static NodeData Node18 = new NodeData("Node (18)", "Damton", 10); public static NodeData Node64 = new NodeData("Node (64)", "Damton", 11); public static NodeData Node97 = new NodeData("Node (97)", "Clifton", 12); public static NodeData Node20 = new NodeData("Node (20)", "Damton", 13); public static NodeData Node22 = new NodeData("Node (22)", "Damton", 14); public static NodeData Node89 = new NodeData("Node (89)", "Clifton", 15); public static NodeData Node55 = new NodeData("Node (55)", "Damton", 16); public static NodeData Node112 = new NodeData("Node (112)", "Damton", 17); public static NodeData Node12 = new NodeData("Node (12)", "Damton", 18); public static NodeData Nodedock3 = new NodeData("Node (dock3)", "Damton", 19); public static NodeData Nodedock1 = new NodeData("Node(dock)(1)", "Smalton", 20); public static NodeData Node14 = new NodeData("Node (14)", "Damton", 21); public static NodeData Nodedock21 = new NodeData("Node (dock2) (1)", "Smalton", 22); public static NodeData Node102 = new NodeData("Node (102)", "Clifton", 23); public static NodeData Node98 = new NodeData("Node (98)", "Clifton", 24); public static NodeData EasyFlowers = new NodeData("Easy Flowers", "Smalton", 25); public static NodeData EasyEats = new NodeData("Easy Eats", "Smalton", 26); public static NodeData PawnShop = new NodeData("Pawn Shop", "Clifton", 27); public static NodeData EZMart = new NodeData("EZ Mart", "Clifton", 28); public static NodeData Bar2 = new NodeData("Bar", "Damton", 29); public static NodeData EasyDepot = new NodeData("Easy Depot", "Damton", 30); public static NodeData Bar1 = new NodeData("Bar", "Clifton", 31); public static NodeData EZCafe = new NodeData("EZ Cafe", "Damton", 32); public static NodeData EasyPizza = new NodeData("Easy Pizza", "Smalton", 33); public static NodeData EZAuto = new NodeData("EZ Auto", "Clifton", 34); public static NodeData EZBakery = new NodeData("EZ Bakery", "Damton", 35); public static PositionData RBCBar = new PositionData("RBCBar", "Clifton", 151, "Bin"); public static PositionData BBCBar = new PositionData("BBCBar", "Clifton", 152, "Bin"); public static PositionData VMCMart = new PositionData("VMCMart", "Clifton", 107, "Vending Machine"); public static PositionData BBCMart = new PositionData("BBCMart", "Clifton", 153, "Bin"); public static PositionData RBCMart = new PositionData("RBCMart", "Clifton", 154, "Bin"); public static PositionData RBDBar = new PositionData("RBDBar", "Damton", 155, "Bin"); public static PositionData BBDBar = new PositionData("BBDBar", "Damton", 156, "Bin"); public static PositionData VMDBar = new PositionData("VMDBar", "Damton", 108, "Vending Machine"); public static PositionData RBDDepot = new PositionData("RBDDepot", "Damton", 157, "Bin"); public static PositionData BBDDepot = new PositionData("BBDDepot", "Damton", 158, "Bin"); public static PositionData VMDDepot = new PositionData("VMDDepot", "Damton", 109, "Vending Machine"); public static PositionData BBSPizza = new PositionData("BBSPizza", "Smalton", 159, "Bin"); public static PositionData RBSPizza = new PositionData("RBSPizza", "Smalton", 160, "Bin"); public static PositionData VMSEatsLeft = new PositionData("VMSEatsLeft", "Smalton", 110, "Vending Machine"); public static PositionData VMSEatsRight = new PositionData("VMSEatsRight", "Smalton", 111, "Vending Machine"); public static PositionData RBSEats = new PositionData("RBSEats", "Smalton", 161, "Bin"); public static PositionData BBSEats = new PositionData("BBSEats", "Smalton", 162, "Bin"); public static PositionData SignWelcome = new PositionData("Welcome to Fishing Town", "Clifton", 226, "Sign"); public static PositionData SignToMT = new PositionData("Tunnel to Mountain Town", "Clifton", 227, "Sign"); public static PositionData SignCliftonEdgeTSTD = new PositionData("To Smalton, To Damton", "Clifton", 228, "Sign"); public static PositionData SignCliftonC = new PositionData("Clifton", "Clifton", 229, "Sign"); public static PositionData SignCliftonToMT = new PositionData("Tunnel to Mountain Town", "Clifton", 232, "Sign"); public static PositionData SignCliftonTSTD = new PositionData("To Smalton, To Damton", "Clifton", 233, "Sign"); public static PositionData SignCliftonTD = new PositionData("Fork To Damton", "Clifton", 230, "Sign"); public static PositionData SignCliftonTS = new PositionData("Fork To Smalton", "Clifton", 231, "Sign"); public static PositionData SignLCliftonRLC = new PositionData("SignLCliftonRLC", "Clifton", 234, "Sign"); public static PositionData SignLCliftonRTS = new PositionData("SignLCliftonRTS", "Clifton", 235, "Sign"); public static PositionData SignLCliftonRTD = new PositionData("SignLCliftonRTD", "Clifton", 236, "Sign"); public static PositionData SignLCliftonLTD = new PositionData("SignLCliftonLTD", "Clifton", 237, "Sign"); public static PositionData SignLCliftonLTS = new PositionData("SignLCliftonLTS", "Clifton", 238, "Sign"); public static PositionData SignLCliftonLLC = new PositionData("SignLCliftonLLC", "Clifton", 239, "Sign"); public static PositionData SignSmaltonBS = new PositionData("Smalton Bridge", "Smalton", 240, "Sign"); public static PositionData SignSmaltonTD = new PositionData("Smalton Dam", "Smalton", 241, "Sign"); public static PositionData SignDamtonDTS = new PositionData("SignDamtonDTS", "Damton", 242, "Sign"); public static PositionData SignDamtonDTCTS = new PositionData("SignDamtonDTCTS", "Damton", 243, "Sign"); public static PositionData SignDamtonDLD = new PositionData("SignDamtonDLD", "Damton", 244, "Sign"); public static PositionData SignDamtonUD = new PositionData("Upper Damton", "Damton", 245, "Sign"); public static PositionData SignDamtonLD = new PositionData("Lower Damton", "Damton", 246, "Sign"); public static PositionData SignDamtonD = new PositionData("SignDamtonD", "Damton", 247, "Sign"); public static PositionData SignDamtonTCTS = new PositionData("SignDamtonTCTS", "Damton", 248, "Sign"); public static PositionData SignDamtonTS = new PositionData("SignDamtonTS", "Damton", 249, "Sign"); public static PositionData SignDamtonTD = new PositionData("SignDamtonTD", "Damton", 250, "Sign"); } public static readonly Dictionary<string, int> Town = new Dictionary<string, int> { { "Upton", 11 }, { "Weston", 12 }, { "Easton", 13 }, { "Winton", 21 }, { "Munton", 22 }, { "Lopton", 23 }, { "Clifton", 31 }, { "Damton", 32 }, { "Smalton", 33 } }; public static readonly Dictionary<string, int> City = new Dictionary<string, int> { { "Mountain Town", 10 }, { "Snowy Peaks", 20 }, { "Fishing Town", 30 } }; public static Dictionary<string, int> Deliveries = GetDeliveries(); public static readonly Dictionary<string, int> PayloadDeliveries = new Dictionary<string, int> { { "PAYLOAD Big Box", 1 }, { "PAYLOAD BixBoxStack", 2 }, { "PAYLOAD BoxBunch", 3 }, { "PAYLOAD BoxStack", 4 }, { "PAYLOAD Crate", 5 }, { "PAYLOAD CrateOfDrinks", 6 }, { "PAYLOAD CrateStack", 7 }, { "PAYLOAD LotsOfCratesOfDrinks", 8 }, { "PAYLOAD PizzaStack", 9 }, { "PAYLOAD PizzaStackMega", 10 }, { "PAYLOAD PlantPot", 11 }, { "PAYLOAD PlantPotBunch", 12 }, { "PAYLOAD PlantPotStack", 13 }, { "PAYLOAD PlantPotWide", 14 }, { "PAYLOAD Sack", 15 }, { "PAYLOAD SackStack", 16 }, { "Drink", 17 } }; public static readonly Dictionary<string, int> BlindBags = new Dictionary<string, int> { { "1Blind Bag", 20 }, { "1Blind Bag (1)", 21 }, { "1Blind Bag (2)", 22 }, { "1Blind Bag (3)", 23 }, { "5Blind Bag", 24 }, { "5Blind Bag (1)", 25 }, { "5Blind Bag (2)", 26 }, { "5Blind Bag (3)", 27 }, { "4Blind Bag", 28 }, { "4Blind Bag (1)", 29 }, { "4Blind Bag (2)", 30 }, { "4Blind Bag (3)", 31 } }; public static readonly Dictionary<string, NodeData> MountainTownNode = new Dictionary<string, NodeData> { { "Easy Flowers", MountainTown.EasyFlowers }, { "Node (57)", MountainTown.Node57 }, { "Node (48)", MountainTown.Node48 }, { "Node (56)", MountainTown.Node56 }, { "Node (55)", MountainTown.Node55 }, { "Easy Eats", MountainTown.EasyEats }, { "Node (47)", MountainTown.Node47 }, { "Node (54)", MountainTown.Node54 }, { "Node (5)", MountainTown.Node5 }, { "EZ Bakery", MountainTown.EZBakery }, { "Node (59)", MountainTown.Node59 }, { "Node (60)", MountainTown.Node60 }, { "Bar 1", MountainTown.Bar1 }, { "Easy Depot", MountainTown.EasyDepot }, { "Bar 2", MountainTown.Bar2 }, { "EZ Cafe", MountainTown.EZCafe }, { "Node (65)", MountainTown.Node65 }, { "Node (71)", MountainTown.Node71 }, { "Node (72)", MountainTown.Node72 }, { "Easy Pizza", MountainTown.EasyPizza }, { "Node (74)", MountainTown.Node74 }, { "Pawn Shop", MountainTown.PawnShop }, { "EZ Auto", MountainTown.EZAuto }, { "EZ Mart", MountainTown.EZMart }, { "Node (92)", MountainTown.Node92 }, { "Node (93)", MountainTown.Node93 } }; public static readonly Dictionary<int, NodeData> MountainTownIndex = new Dictionary<int, NodeData> { { 0, MountainTown.EasyFlowers }, { 1, MountainTown.Node57 }, { 2, MountainTown.Node48 }, { 3, MountainTown.Node56 }, { 4, MountainTown.Node55 }, { 5, MountainTown.EasyEats }, { 6, MountainTown.Node47 }, { 7, MountainTown.Node54 }, { 8, MountainTown.Node5 }, { 9, MountainTown.EZBakery }, { 10, MountainTown.Node59 }, { 11, MountainTown.Node60 }, { 12, MountainTown.Bar1 }, { 13, MountainTown.EasyDepot }, { 14, MountainTown.Bar2 }, { 15, MountainTown.EZCafe }, { 16, MountainTown.Node65 }, { 17, MountainTown.Node71 }, { 18, MountainTown.Node72 }, { 19, MountainTown.EasyPizza }, { 20, MountainTown.Node74 }, { 21, MountainTown.PawnShop }, { 22, MountainTown.EZAuto }, { 23, MountainTown.EZMart }, { 24, MountainTown.Node92 }, { 25, MountainTown.Node93 } }; public static readonly Dictionary<string, NodeData> SnowyPeaksNode = new Dictionary<string, NodeData> { { "Destnode5", SnowyPeaks.Destnode5 }, { "Destnode1", SnowyPeaks.Destnode1 }, { "Destnode3", SnowyPeaks.Destnode3 }, { "Destnode2", SnowyPeaks.Destnode2 }, { "Destnode4", SnowyPeaks.Destnode4 }, { "Destnode6", SnowyPeaks.Destnode6 }, { "Destnode", SnowyPeaks.Destnode }, { "Destnode10", SnowyPeaks.Destnode10 }, { "Destnode8", SnowyPeaks.Destnode8 }, { "Destnode7", SnowyPeaks.Destnode7 }, { "Destnode9", SnowyPeaks.Destnode9 }, { "Easy Eats", SnowyPeaks.EasyEats }, { "EZ Bakery", SnowyPeaks.EZBakery }, { "Easy Pizza", SnowyPeaks.EasyPizza }, { "Easy Flowers", SnowyPeaks.EasyFlowers }, { "Bar 1", SnowyPeaks.Bar1 }, { "Easy Depot", SnowyPeaks.EasyDepot }, { "EZ Auto", SnowyPeaks.EZAuto }, { "EZ Cafe", SnowyPeaks.EZCafe }, { "Bar 2", SnowyPeaks.Bar2 }, { "EZ Mart", SnowyPeaks.EZMart }, { "Pawn Shop", SnowyPeaks.PawnShop } }; public static readonly Dictionary<int, NodeData> SnowyPeaksIndex = new Dictionary<int, NodeData> { { 0, SnowyPeaks.Destnode5 }, { 1, SnowyPeaks.Destnode1 }, { 2, SnowyPeaks.Destnode3 }, { 3, SnowyPeaks.Destnode2 }, { 4, SnowyPeaks.Destnode4 }, { 5, SnowyPeaks.Destnode6 }, { 6, SnowyPeaks.Destnode }, { 7, SnowyPeaks.Destnode10 }, { 8, SnowyPeaks.Destnode8 }, { 9, SnowyPeaks.Destnode7 }, { 10, SnowyPeaks.Destnode9 }, { 11, SnowyPeaks.EasyEats }, { 12, SnowyPeaks.EZBakery }, { 13, SnowyPeaks.EasyPizza }, { 14, SnowyPeaks.EasyFlowers }, { 15, SnowyPeaks.Bar1 }, { 16, SnowyPeaks.EasyDepot }, { 17, SnowyPeaks.EZAuto }, { 18, SnowyPeaks.EZCafe }, { 19, SnowyPeaks.Bar2 }, { 20, SnowyPeaks.EZMart }, { 21, SnowyPeaks.PawnShop } }; public static readonly Dictionary<string, NodeData> FishingTownNode = new Dictionary<string, NodeData> { { "Node93", FishingTown.Node93 }, { "Nodedock", FishingTown.Nodedock }, { "Node59", FishingTown.Node59 }, { "Node101", FishingTown.Node101 }, { "Nodedock2", FishingTown.Nodedock2 }, { "Node11", FishingTown.Node11 }, { "Nodedock31", FishingTown.Nodedock31 }, { "Node58", FishingTown.Node58 }, { "Node91", FishingTown.Node91 }, { "Node54", FishingTown.Node54 }, { "Node18", FishingTown.Node18 }, { "Node64", FishingTown.Node64 }, { "Node97", FishingTown.Node97 }, { "Node20", FishingTown.Node20 }, { "Node22", FishingTown.Node22 }, { "Node89", FishingTown.Node89 }, { "Node55", FishingTown.Node55 }, { "Node112", FishingTown.Node112 }, { "Node12", FishingTown.Node12 }, { "Nodedock3", FishingTown.Nodedock3 }, { "Nodedock1", FishingTown.Nodedock1 }, { "Node14", FishingTown.Node14 }, { "Nodedock21", FishingTown.Nodedock21 }, { "Node102", FishingTown.Node102 }, { "Node98", FishingTown.Node98 }, { "EasyFlowers", FishingTown.EasyFlowers }, { "EasyEats", FishingTown.EasyEats }, { "PawnShop", FishingTown.PawnShop }, { "EZMart", FishingTown.EZMart }, { "Bar2", FishingTown.Bar2 }, { "EasyDepot", FishingTown.EasyDepot }, { "Bar1", FishingTown.Bar1 }, { "EZCafe", FishingTown.EZCafe }, { "EasyPizza", FishingTown.EasyPizza }, { "EZAuto", FishingTown.EZAuto }, { "EZBakery", FishingTown.EZBakery } }; public static readonly Dictionary<int, NodeData> FishingTownIndex = new Dictionary<int, NodeData> { { 0, FishingTown.Node93 }, { 1, FishingTown.Nodedock }, { 2, FishingTown.Node59 }, { 3, FishingTown.Node101 }, { 4, FishingTown.Nodedock2 }, { 5, FishingTown.Node11 }, { 6, FishingTown.Nodedock31 }, { 7, FishingTown.Node58 }, { 8, FishingTown.Node91 }, { 9, FishingTown.Node54 }, { 10, FishingTown.Node18 }, { 11, FishingTown.Node64 }, { 12, FishingTown.Node97 }, { 13, FishingTown.Node20 }, { 14, FishingTown.Node22 }, { 15, FishingTown.Node89 }, { 16, FishingTown.Node55 }, { 17, FishingTown.Node112 }, { 18, FishingTown.Node12 }, { 19, FishingTown.Nodedock3 }, { 20, FishingTown.Nodedock1 }, { 21, FishingTown.Node14 }, { 22, FishingTown.Nodedock21 }, { 23, FishingTown.Node102 }, { 24, FishingTown.Node98 }, { 25, FishingTown.EasyFlowers }, { 26, FishingTown.EasyEats }, { 27, FishingTown.PawnShop }, { 28, FishingTown.EZMart }, { 29, FishingTown.Bar2 }, { 30, FishingTown.EasyDepot }, { 31, FishingTown.Bar1 }, { 32, FishingTown.EZCafe }, { 33, FishingTown.EasyPizza }, { 34, FishingTown.EZAuto }, { 35, FishingTown.EZBakery } }; public static readonly Dictionary<string, PositionData> MountainTownPositions = new Dictionary<string, PositionData> { { "(-323.89, 326.97, -278.76)", MountainTown.VMUEats }, { "(-379.38, 326.80, -291.69)", MountainTown.RBUFlowers }, { "(-378.53, 326.80, -290.91)", MountainTown.BBUFlowers }, { "(-355.97, 326.82, -288.83)", MountainTown.BBUFlowersEats }, { "(-326.58, 326.80, -279.27)", MountainTown.BBUEats }, { "(-325.83, 326.79, -279.25)", MountainTown.RBUEats }, { "(-267.40, 328.12, -278.91)", MountainTown.RBUTownEdge }, { "(287.45, 198.50, -49.99)", MountainTown.BBWEntry }, { "(320.60, 198.86, -65.65)", MountainTown.RBWEntry }, { "(407.72, 196.02, -72.15)", MountainTown.BBWBakeryAcross }, { "(436.57, 195.03, -84.92)", MountainTown.RBWBakeryLeft }, { "(435.85, 195.05, -84.81)", MountainTown.BBWBakeryLeft }, { "(457.49, 195.15, -50.03)", MountainTown.RBWBarTunnel }, { "(446.47, 195.79, -43.11)", MountainTown.VMWBarTunnel }, { "(398.14, 195.00, -37.17)", MountainTown.BBWDepot }, { "(279.93, 156.83, 69.52)", MountainTown.BBWBarLower }, { "(230.71, 156.11, 68.35)", MountainTown.RBWCafe }, { "(-208.38, 146.34, 42.44)", MountainTown.BBEMart }, { "(-143.60, 146.19, 38.97)", MountainTown.RBEFuel }, { "(-144.36, 146.22, 39.11)", MountainTown.BBEFuel }, { "(-140.00, 146.32, 37.85)", MountainTown.VMEFuel }, { "(-202.84, 146.27, 26.13)", MountainTown.BBEPizzaRight }, { "(-139.48, 146.15, 6.84)", MountainTown.RBEPizzaLeft }, { "(-445.35, 329.58, -305.98)", MountainTown.SignToSP }, { "(-192.70, 331.69, -251.75)", MountainTown.SignUptonExit }, { "(385.50, 352.25, -244.08)", MountainTown.SignUptonRadio }, { "(262.00, 199.57, -67.52)", MountainTown.SignWestonEntryUpton }, { "(269.42, 200.02, -45.38)", MountainTown.SignWestonEntryEaston }, { "(486.47, 195.85, -61.77)", MountainTown.SignFactory }, { "(374.95, 164.78, 35.62)", MountainTown.SignWestonExitUpton }, { "(373.63, 163.87, 47.30)", MountainTown.SignWestonExitEaston }, { "(274.21, 159.25, 84.87)", MountainTown.SignToEaston }, { "(126.83, 152.05, 41.89)", MountainTown.SignEastonEntry }, { "(-33.76, 142.62, 62.99)", MountainTown.SignEastonOtherEntry }, { "(-45.99, 142.62, 70.29)", MountainTown.SignToFTLower }, { "(-58.33, 142.32, 54.48)", MountainTown.SignEastonExit }, { "(-382.42, 146.43, 39.41)", MountainTown.SignToFTUpper }, { "(-436.95, 140.38, 35.60)", MountainTown.SignEastonRadio }, { "(-495.71, 126.33, 140.12)", MountainTown.SignToFT } }; public static readonly Dictionary<string, PositionData> SnowyPeaksPositions = new Dictionary<string, PositionData> { { "(-279.34, 277.75, 233.77)", SnowyPeaks.BBWFlowers }, { "(-288.79, 277.53, 232.49)", SnowyPeaks.RBWEats }, { "(-325.92, 277.63, 209.57)", SnowyPeaks.VMWFuel }, { "(-323.14, 277.39, 212.76)", SnowyPeaks.BBWFuel }, { "(-322.31, 277.42, 213.12)", SnowyPeaks.RBWFuel }, { "(120.29, 243.89, 252.13)", SnowyPeaks.VMMAuto }, { "(111.71, 243.84, 222.27)", SnowyPeaks.RBMPawn }, { "(256.12, 331.05, 261.82)", SnowyPeaks.BBMMart }, { "(255.40, 331.02, 262.43)", SnowyPeaks.RBMMart }, { "(273.01, 330.99, 243.18)", SnowyPeaks.VMMBar }, { "(307.56, 277.49, -382.80)", SnowyPeaks.RBLBar }, { "(233.84, 277.28, -440.07)", SnowyPeaks.VMLDepot }, { "(227.77, 277.29, -439.43)", SnowyPeaks.RBLDepot }, { "(228.23, 277.29, -438.71)", SnowyPeaks.BBLDepot }, { "(-156.92, 245.51, 272.73)", SnowyPeaks.SignToMT }, { "(-139.71, 245.77, 249.59)", SnowyPeaks.SignWintonExit }, { "(-153.33, 246.28, 247.21)", SnowyPeaks.SignWintonEntry }, { "(81.62, 246.57, 221.57)", SnowyPeaks.SignMuntonEntry }, { "(335.00, 245.57, 124.35)", SnowyPeaks.SignMuntonBridgeWinton }, { "(335.29, 246.03, 105.27)", SnowyPeaks.SignMuntonBridgeLopton }, { "(360.68, 246.47, 125.37)", SnowyPeaks.SignUpperMunton }, { "(353.74, 248.13, -214.54)", SnowyPeaks.SignLoptonEntry }, { "(-331.79, 246.64, -266.31)", SnowyPeaks.SignLoptonBridge }, { "(-320.11, 247.85, -247.79)", SnowyPeaks.SignLoptonRadio } }; public static readonly Dictionary<string, PositionData> FishingTownPositions = new Dictionary<string, PositionData> { { "(234.21, 92.07, 289.82)", FishingTown.RBCBar }, { "(233.87, 92.06, 288.78)", FishingTown.BBCBar }, { "(278.26, 92.31, 313.60)", FishingTown.VMCMart }, { "(288.85, 92.32, 316.12)", FishingTown.BBCMart }, { "(287.93, 92.33, 316.15)", FishingTown.RBCMart }, { "(416.86, 74.57, -364.26)", FishingTown.RBDBar }, { "(417.68, 74.57, -364.23)", FishingTown.BBDBar }, { "(414.58, 74.61, -364.05)", FishingTown.VMDBar }, { "(211.42, 36.28, -474.88)", FishingTown.RBDDepot }, { "(212.23, 36.32, -474.92)", FishingTown.BBDDepot }, { "(207.45, 36.32, -474.97)", FishingTown.VMDDepot }, { "(-198.02, 25.32, -497.58)", FishingTown.BBSPizza }, { "(-198.83, 25.32, -497.60)", FishingTown.RBSPizza }, { "(-410.32, 76.99, -430.47)", FishingTown.VMSEatsLeft }, { "(-412.82, 76.99, -430.47)", FishingTown.VMSEatsRight }, { "(-407.54, 76.87, -430.97)", FishingTown.RBSEats }, { "(-408.35, 76.87, -430.94)", FishingTown.BBSEats }, { "(-426.09, 125.57, 201.99)", FishingTown.SignWelcome }, { "(-6.70, 82.43, 351.96)", FishingTown.SignToMT }, { "(-2.87, 80.72, 337.14)", FishingTown.SignCliftonEdgeTSTD }, { "(19.71, 81.17, 342.55)", FishingTown.SignCliftonC }, { "(89.07, 92.61, 335.14)", FishingTown.SignCliftonToMT }, { "(87.40, 93.06, 313.40)", FishingTown.SignCliftonTSTD }, { "(-10.98, 68.86, 282.54)", FishingTown.SignCliftonTD }, { "(-25.19, 67.54, 285.79)", FishingTown.SignCliftonTS }, { "(-14.93, 33.02, 195.51)", FishingTown.SignLCliftonRLC }, { "(-14.25, 32.98, 176.99)", FishingTown.SignLCliftonRTS }, { "(2.11, 33.39, 178.20)", FishingTown.SignLCliftonRTD }, { "(238.04, 35.06, 102.83)", FishingTown.SignLCliftonLTD }, { "(231.32, 34.65, 117.80)", FishingTown.SignLCliftonLTS }, { "(249.88, 34.85, 123.69)", FishingTown.SignLCliftonLLC }, { "(-398.06, 45.30, -128.26)", FishingTown.SignSmaltonBS }, { "(-136.70, 26.10, -484.49)", FishingTown.SignSmaltonTD }, { "(93.58, 36.67, -444.48)", FishingTown.SignDamtonDTS }, { "(100.39, 36.67, -432.55)", FishingTown.SignDamtonDTCTS }, { "(115.01, 37.37, -439.39)", FishingTown.SignDamtonDLD }, { "(254.17, 39.26, -376.64)", FishingTown.SignDamtonUD }, { "(419.08, 76.57, -193.78)", FishingTown.SignDamtonLD }, { "(162.18, 31.89, -353.16)", FishingTown.SignDamtonD }, { "(155.50, 31.61, -335.05)", FishingTown.SignDamtonTCTS }, { "(141.19, 32.72, -339.13)", FishingTown.SignDamtonTS }, { "(351.96, 43.82, -138.48)", FishingTown.SignDamtonTD } }; private static Dictionary<string, int> GetDeliveries() { Dictionary<string, int> dictionary = new Dictionary<string, int>(); foreach (KeyValuePair<string, int> item in Town) { foreach (KeyValuePair<string, int> item2 in Town) { dictionary.Add(item.Key + " to " + item2.Key + " Delivery", int.Parse($"{item.Value}{item2.Value}")); } } foreach (KeyValuePair<string, int> item3 in City) { foreach (KeyValuePair<string, int> item4 in City) { dictionary.Add(item3.Key + " to " + item4.Key + " Delivery", int.Parse($"{item3.Value}{item4.Value}")); } } return dictionary; } } public class NodeData { public string Name { get; set; } public string Town { get; set; } public int Index { get; set; } public NodeData() { } public NodeData(string name, string town, int index) { Name = name; Town = town; Index = index; } } public class PositionData { public string Name { get; set; } public string Town { get; set; } public string Type { get; set; } public int LocationId { get; set; } public PositionData(string name, string town, int locId) { Name = name; Town = town; LocationId = locId; Type = "None"; } public PositionData(string name, string town, int locId, string type) { Name = name; Town = town; LocationId = locId; Type = type; } } public class TestData { public static bool optionStartMap = true; } [HarmonyPatch] public class APJobGenerator { [HarmonyPatch(typeof(jobBoard), "GenerateJobBetter")] private static bool Prefix(int __0, jobBoard __instance, ref Job __result) { //IL_0102: 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_012a: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0498: Unknown result type (might be due to invalid IL or missing references) //IL_049f: Expected O, but got Unknown if (!ArchipelagoClient.Authenticated && !EasyDeliveryAP.debug) { __result = null; return false; } List<Transform> list = new List<Transform>(); for (int i = 0; i < __instance.navigation.towns.Length; i++) { if (((Component)__instance.navigation.towns[i]).gameObject.activeSelf && (APData.lock_towns != "1" || Items.TownToItem[((Object)__instance.navigation.towns[i]).name].Received >= 1)) { list.Add(__instance.navigation.towns[i]); } } if (list.Count == 0) { __result = null; return false; } int num = -1; for (int j = 0; j < list.Count; j++) { if (num == -1) { num = j; } float num2 = Vector3.Distance(list[j].position, ((Component)__instance.navigation.car).transform.position); float num3 = Vector3.Distance(list[num].position, ((Component)__instance.navigation.car).transform.position); if (num2 < num3) { num = j; } } Transform val = list[0]; Transform val2 = list[0]; if (list.Count == 2 || __instance.intercityJobs) { int index = Random.Range(0, list.Count); int index2 = Random.Range(0, list.Count); val = list[index]; val2 = list[index2]; } else if (list.Count >= 3) { switch (__0) { case 0: val = list[num]; val2 = list[num]; break; case 1: val = list[num]; val2 = list[(num + 1) % list.Count]; break; case 2: val = list[num]; val2 = list[(num + 2) % list.Count]; break; case 3: val = list[(num + 1) % list.Count]; val2 = list[(num + 2) % list.Count]; break; case 4: val = list[(num + 2) % list.Count]; val2 = list[(num + 1) % list.Count]; break; } } int num4 = 10000; ShopInfo val3; do { val3 = __instance.navigation.shopNodes[Random.Range(0, __instance.navigation.shopNodes.Count)]; num4--; } while (num4 >= 0 && (Object)(object)val3.node.town != (Object)(object)val); TunnelNode val4 = null; int destinationIndex = -1; num4 = 10000; sMapNode val5; if (!__instance.intercityJobs) { while (true) { int num5 = Random.Range(0, __instance.navigation.destinationNodes.Count); val5 = __instance.navigation.destinationNodes[num5]; num4--; if (num4 < 0) { break; } if (!((Object)(object)val5 == (Object)(object)val3.node) && (__instance.sameTownDeliveries || !((Object)(object)val5.town == (Object)(object)val3.node.town)) && list.Contains(val5.town) && !((Object)(object)val5.town != (Object)(object)val2)) { destinationIndex = num5; ArchipelagoConsole.LogMessage(((Object)val5).name); break; } } } else { val4 = __instance.tunnelNodes[Random.Range(0, __instance.tunnelNodes.Length)]; string name = ((Object)val4.node).name; if (!__instance.navigation.nodes.Contains(val4.node) || ((name == "Snowy Peaks" || ScenePatches.currentScene == "Snowy Peaks") && !APLogic.CanReachSnowyPeaks()) || ((name == "Fishing Town" || ScenePatches.currentScene == "Fishing Town") && (!APLogic.CanReachFishingTown() || !APLogic.FTGateIsOpen()))) { __result = null; return false; } val5 = val4.node; } Job val6 = new Job(val3, val5); val6.path = __instance.navigation.FindPath(val6.from, val6.to); val6.distance = sPathFinder.PathLength(val6.path) / 1000f; val6.startingCityName = __instance.cityName; val6.destCityName = __instance.cityName; val6.destinationIndex = destinationIndex; val6.bonusDistance = 0f; if (Object.op_Implicit((Object)(object)val4)) { int num6 = Random.Range(0, val4.distances.Length); while (val4.distances[num6] >= val4.distanceCutoff) { num6 = Random.Range(0, val4.distances.Length); } if (APData.lock_towns == "1") { switch (((Object)val4.node).name) { case "Mountain Town": if (Items.TownToItem[Locations.MountainTownIndex[num6].Town].Received < 1) { __result = null; return false; } break; case "Snowy Peaks": if (Items.TownToItem[Locations.SnowyPeaksIndex[num6].Town].Received < 1) { __result = null; return false; } break; case "Fishing Town": if (Items.TownToItem[Locations.FishingTownIndex[num6].Town].Received < 1) { __result = null; return false; } break; } } val6.destinationIndex = num6; val6.destCityName = ((Object)val4).name; val6.distance += (val4.distances[num6] + val4.distanceToOtherTown) / 1000f; val6.bonusDistance = sPathFinder.PathLength(__instance.navigation.FindPath(__instance.navigation.currentClosestNode, val4.node)) / 1000f; val6.isIntercity = true; } else { val6.bonusDistance = sPathFinder.PathLength(__instance.navigation.FindPath(__instance.navigation.currentClosestNode, val6.shop.node)) / 1000f; } val6.price = __instance.JobPrice(val6, val6.bonusDistance); __result = val6; return false; } } [HarmonyPatch] public class CarPatches { private static readonly ArchipelagoClient archipelago = EasyDeliveryAP.ArchipelagoClient; public static bool shrink = false; private static Vector3 shrinkSpeed = new Vector3(0.01f, 0.01f, 0.01f); private static int shrinkTimer = 0; public static bool iceTrap = false; private static int iceTimer = 0; public static bool teleport = false; private static Vector3 MountainTownTP = new Vector3(-452.94f, 328f, -325.21f); private static Quaternion MountainTownQt = new Quaternion(0.00282f, 0.45403f, -0.00174f, 0.89098f); private static Vector3 SnowyPeaksTP = new Vector3(-350.28f, 288f, 388.1f); private static Quaternion SnowyPeaksQt = new Quaternion(0.00282f, 0.45403f, -0.00174f, 0.89098f); private static Vector3 FishingTownTP = new Vector3(-471.51f, 124.16f, 193.76f); private static Quaternion FishingTownQt = new Quaternion(-0.00178f, 0.75104f, -0.00163f, -0.66025f); public static Color trailColor = new Color(1f, 1f, 1f); public static bool turnTrap = false; private static int turnTimer = 0; private static float randomTurn = 0f; public static bool accelTrap = false; private static int accelTimer = 0; public static bool debugTP = false; public static Vector3 debugTPDest; [HarmonyPatch(typeof(sCarController), "Update")] private static void Prefix(sCarController __instance) { //IL_002f: 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_00fb: 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_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_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: 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_0231: 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_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_02da: Unknown result type (might be due to invalid IL or missing references) //IL_02df: Unknown result type (might be due to invalid IL or missing references) //IL_02e5: Unknown result type (might be due to invalid IL or missing references) //IL_02ea: Unknown result type (might be due to invalid IL or missing references) //IL_0273: Unknown result type (might be due to invalid IL or missing references) //IL_0278: Unknown result type (might be due to invalid IL or missing references) //IL_0299: Unknown result type (might be due to invalid IL or missing references) //IL_029e: Unknown result type (might be due to invalid IL or missing references) //IL_02c1: Unknown result type (might be due to invalid IL or missing references) //IL_02c6: Unknown result type (might be due to invalid IL or missing references) if (!PauseSystem.paused && !__instance.guyActive) { if (shrink) { if (((Component)__instance).transform.localScale.x > 1f) { Transform transform = ((Component)__instance).transform; transform.localScale -= shrinkSpeed; Transform payloadPivot = __instance.payloadPivot; payloadPivot.localScale -= shrinkSpeed; __instance.maxDrivePower -= 4f; __instance.maxSpeed -= 2f / 3f; __instance.maxSpeedScale -= 1f / 150f; __instance.drivePowerScale -= 1f / 150f; } else { shrink = false; shrinkTimer += 1800; ((Component)OtherPatches.guy).transform.localScale = new Vector3(0.75f, 0.75f, 0.75f); } } else if (shrinkTimer > 0) { shrinkTimer--; } else if ((double)((Component)__instance).transform.localScale.x < 1.5) { Transform transform2 = ((Component)__instance).transform; transform2.localScale += shrinkSpeed; Transform payloadPivot2 = __instance.payloadPivot; payloadPivot2.localScale += shrinkSpeed; __instance.maxDrivePower += 4f; __instance.maxSpeed += 2f / 3f; __instance.maxSpeedScale += 1f / 150f; __instance.drivePowerScale += 1f / 150f; ((Component)OtherPatches.guy).transform.localScale = new Vector3(1.13f, 1.13f, 1.13f); } } if (PauseSystem.paused && debugTP && !__instance.guyActive) { debugTP = !debugTP; ((Component)__instance).transform.SetPositionAndRotation(debugTPDest, MountainTownQt); } if (PauseSystem.paused && teleport && !__instance.guyActive) { if (OtherPatches.currentScene == 1) { ((Component)__instance).transform.SetPositionAndRotation(MountainTownTP, MountainTownQt); } if (OtherPatches.currentScene == 5) { ((Component)__instance).transform.SetPositionAndRotation(SnowyPeaksTP, SnowyPeaksQt); } else if (OtherPatches.currentScene == 4) { ((Component)__instance).transform.SetPositionAndRotation(FishingTownTP, FishingTownQt); } teleport = false; } __instance.dirtColor = trailColor; __instance.smokeColor = trailColor; } [HarmonyPatch(typeof(sCarController), "GetMaterialIndex")] private static bool Prefix(sCarController __instance, ref int __result) { if (!PauseSystem.paused && !__instance.guyActive) { if (iceTrap) { iceTimer += 7000; iceTrap = false; } else if (iceTimer > 0) { __result = 3; iceTimer--; return false; } } return true; } [HarmonyPatch(typeof(sCarController), "SetInput", new Type[] { typeof(Vector2) })] private static void Prefix(sCarController __instance, ref Vector2 __0) { //IL_0063: 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_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) if (!PauseSystem.paused && !__instance.guyActive) { if (turnTrap) { turnTimer += 500; turnTrap = false; randomTurn = __0.x; } else if (turnTimer > 0) { __0 = new Vector2(randomTurn, __0.y); turnTimer--; } if (accelTrap) { accelTimer += 500; accelTrap = false; } else if (accelTimer > 0) { __0 = new Vector2(__0.x, 1f); accelTimer--; } } } [HarmonyPatch(typeof(sCharacterInteraction), "ExitObstructed")] private static void Prefix(sCharacterInteraction __instance, ref Vector3 __0) { if (shrinkTimer > 0) { __0.y += 0.5f; } } } [HarmonyPatch] public class DeathLinkPatches { private static readonly ArchipelagoClient archipelago = EasyDeliveryAP.ArchipelagoClient; private static bool dead; public static bool dying; [HarmonyPatch(typeof(DeathManager), "Update")] private static void Prefix(ref DeathManager __instance) { if (__instance.deathTime >= 50f) { __instance.deathTime = 20f; } if (!ArchipelagoClient.Authenticated) { return; } if (dead != __instance.dying) { dead = __instance.dying; if (__instance.dying && !dying) { archipelago.DeathLinkHandler.SendDeathLink(); } dying = false; } if (dying && !dead && !__instance.dying) { sCharacterInteraction val = Object.FindObjectOfType<sCharacterInteraction>(); val.hud.temperature = 0f; } } } [HarmonyPatch] public class ItemHandling { public static float pendingMoney = 0f; public static bool pendingItems; public static List<int> pendingItemIds = new List<int>(); public static List<int> radio; public static bool pendingItem; public static bool pendingRemoval; public static int pendingItemId; public static bool pendingUpgrade; [HarmonyPatch(typeof(sHUD), "Update")] private static void Prefix(sHUD __instance) { if (pendingMoney != 0f) { ArchipelagoConsole.LogMessage($"Adding {pendingMoney}$"); __instance.ReceivePayment(pendingMoney); pendingMoney = 0f; } } [HarmonyPatch(typeof(sItemManager), "Update")] private static void Postfix(sItemManager __instance) { if (pendingItems) { foreach (int pendingItemId in pendingItemIds) { ArchipelagoConsole.LogMessage($"Adding item id {pendingItemId} to inventory"); __instance.AddToInventory(pendingItemId, 1); } pendingItemIds = new List<int>(); pendingItems = false; EasyDeliveryAP.save.data.handledIndex = ArchipelagoClient.ServerData.Index; } radio = __instance.inventory; if (pendingItem) { ArchipelagoConsole.LogMessage($"Adding item id: {ItemHandling.pendingItemId}"); __instance.AddToInventory(ItemHandling.pendingItemId, 1); pendingItem = false; } if (pendingRemoval) { ArchipelagoConsole.LogMessage($"Removing item id: {ItemHandling.pendingItemId}"); __instance.inventory.Remove(ItemHandling.pendingItemId); pendingRemoval = false; } } [HarmonyPatch(typeof(TruckUpgrades), "LateUpdate")] private static void Prefix(TruckUpgrades __instance) { if (TestData.optionStartMap) { __instance.hasGPS = Items.GPS.Enabled; } if (APData.car_upgrades == "1") { __instance.hasGPS = Items.GPS.Enabled; if (APData.progressive_car_upgrades == "1") { __instance.hasTires = Items.ProgCarUpgrade.Received > 0; __instance.hasBumper = Items.ProgCarUpgrade.Received > 1; __instance.hasChains = Items.ProgCarUpgrade.Received > 2; } else { __instance.hasTires = Items.Tires.Received > 0; __instance.hasBumper = Items.Bumper.Received > 0; __instance.hasChains = Items.Chains.Received > 0; } } if (pendingUpgrade) { __instance.hasGPS = Items.GPS.Enabled; __instance.hasTires = Items.Tires.Enabled; __instance.hasBumper = Items.Bumper.Enabled; __instance.hasChains = Items.Chains.Enabled; pendingUpgrade = false; } } } [HarmonyPatch] public class LocationHandling { private static readonly ArchipelagoClient archipelago = EasyDeliveryAP.ArchipelagoClient; public static string jobStartTown; public static string jobStartCity; public static string jobStartShop; public static int jobDestinationIndex; public static string jobPayload; private static bool snowcat = false; [HarmonyPatch(typeof(jobBoard), "ConfirmJob")] private static void Postfix(jobBoard __instance) { ArchipelagoConsole.LogMessage($"Starting delivery from: {((Object)__instance.selectedJob.shop).name} in {((Object)__instance.selectedJob.from.town).name} - {__instance.cityName} (Dest index: {__instance.selectedJob.destinationIndex})"); jobStartTown = ((Object)__instance.selectedJob.from.town).name; jobStartCity = __instance.selectedJob.startingCityName; jobStartShop = ((Object)__instance.selectedJob.shop).name; jobDestinationIndex = __instance.selectedJob.destinationIndex; if (!EasyDeliveryAP.debug) { return; } ArchipelagoConsole.LogMessage($"Destination node: {((Object)__instance.selectedJob.to).name} Bool: {__instance.selectedJob.to.destination}"); foreach (sMapNode connection in __instance.selectedJob.to.connections) { ArchipelagoConsole.LogMessage($"Connections: {((Object)connection).name} Bool: {connection.destination}"); } } [HarmonyPatch(typeof(jobBoard), "CompleteJob")] private static void Prefix(jobBoard __instance) { ArchipelagoConsole.LogMessage($"Completed delivering {((Object)__instance.selectedJob.payloadPrefab).name} to: {((Object)__instance.selectedJob.to.town).name} - {__instance.cityName} (Dest index: {jobDestinationIndex})"); List<long> list = new List<long>(); string key = jobStartTown + " to " + ((Object)__instance.selectedJob.to.town).name + " Delivery"; string key2 = jobStartCity + " to " + __instance.selectedJob.destCityName + " Delivery"; if (Locations.Deliveries.TryGetValue(key, out var value)) { if (APData.perfect_deliveries == "0" || APData.perfect_deliveries == "1") { list.Add(value); } if ((APData.perfect_deliveries == "1" || APData.perfect_deliveries == "2") && __instance.recoveries <= 0) { list.Add(10000 + value); } } if (Locations.Deliveries.TryGetValue(key2, out var value2)) { if (APData.perfect_deliveries == "0" || APData.perfect_deliveries == "1") { list.Add(value2); } if ((APData.perfect_deliveries == "1" || APData.perfect_deliveries == "2") && __instance.recoveries <= 0) { list.Add(10000 + value2); } } if (APData.payload_checks == "1" && Locations.PayloadDeliveries.TryGetValue(((Object)__instance.selectedJob.payloadPrefab).name, out var value3)) { list.Add(value3); } archipelago.SendLocations(list.ToArray()); } [HarmonyPatch(typeof(EndingManager), "SetEnding")] private static void Postfix(Ending __0, EndingManager __instance) { archipelago.SendCompletion(); } [HarmonyPatch(typeof(GenericItemCheckout), "MakePayment")] private static void Prefix(float __0, GenericItemCheckout __instance) { if (EasyDeliveryAP.debug) { ArchipelagoConsole.LogMessage($"Buying {((Object)__instance.item).name} for {__0}$"); } if (Locations.BlindBags.TryGetValue($"{OtherPatches.currentScene}{((Object)__instance.item).name}", out var value) && APData.blind_bags == "1") { archipelago.SendLocation(value); } } [HarmonyPatch(typeof(SnowcatManager), "EnableSnowcat")] private static void Prefix() { snowcat = true; } [HarmonyPatch(typeof(SnowcatManager), "EnableSnowcat")] private static void Postfix() { snowcat = false; } [HarmonyPatch(typeof(SnowcatManager), "ClosestIndex")] private static void Postfix(int __result) { ArchipelagoConsole.LogMessage($"SnowcatBobbleIndex: {__result}"); if (snowcat) { archipelago.SendLocation(__result + 40); } } [HarmonyPatch(typeof(RoadSign), "Update")] private static void Postfix(RoadSign __instance) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: 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_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: 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_010d: Unknown result type (might be due to invalid IL or missing references) Vector3 val = ((Component)__instance.cam).transform.position - ((Component)__instance).transform.position; if (ArchipelagoClient.Authenticated && !(((Vector3)(ref val)).magnitude > 30f) && !(Vector3.Dot(((Component)__instance.cam).transform.forward, ((Vector3)(ref val)).normalized) > 0f)) { Dictionary<string, PositionData> dictionary = new Dictionary<string, PositionData>(); switch (OtherPatches.currentScene) { case 1: dictionary = Locations.MountainTownPositions; break; case 4: dictionary = Locations.FishingTownPositions; break; case 5: dictionary = Locations.SnowyPeaksPositions; break; } if (dictionary.TryGetValue(((object)((Component)__instance).gameObject.transform.position/*cast due to .constrained prefix*/).ToString(), out var value)) { archipelago.SendLocations(new long[1] { value.LocationId }); } else { ArchipelagoConsole.LogMessage($"Unregistered or knocked over sign: {((Component)__instance).gameObject.transform.position}"); } } } } [HarmonyPatch] public class OtherPatches { private static readonly ArchipelagoClient archipelago = EasyDeliveryAP.ArchipelagoClient; public static int currentScene; public static GameObject upgradedBasedProgression; public static GameObject shopInteriors; public static GameObject nodes; public static sCarController car; public static sCharacterController guy; public static Transform[] radios; public static GameObject radio1; public static GameObject radio2; public static Dictionary<string, Transform> progression = new Dictionary<string, Transform>(); public static Dictionary<string, Transform> storeInteriors = new Dictionary<string, Transform>(); public static Dictionary<string, Transform> Nodes = new Dictionary<string, Transform>(); public static Dictionary<string, sMapNode> MapNodes = new Dictionary<string, sMapNode>(); [HarmonyPatch(typeof(EnergyDrink), "ButtonPressed")] private static void Prefix(ref EnergyDrink __instance, ref bool __state) { if (!Items.GPS.Enabled && !__instance.upgrades.hadGPS) { __instance.upgrades.hasGPS = true; __state = true; } } [HarmonyPatch(typeof(EnergyDrink), "ButtonPressed")] private static void Postfix(ref EnergyDrink __instance, ref bool __state) { if (__state) { __instance.upgrades.hasGPS = false; __state = false; } } [HarmonyPatch(typeof(SceneTransition), "LoadScene", new Type[] { typeof(int) })] private static bool Prefix(int __0) { currentScene = __0; if (__0 == 3) { ArchipelagoConsole.LogMessage("Starting new save"); ItemHandling.pendingItemIds = new List<int>(); foreach (ItemData value in Items.APIdToItem.Values) { switch (value.Id) { case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15: case 16: case 17: { for (int num = value.Received; num > 0; num--) { ItemHandling.pendingItemIds.Add(value.Id); } break; } } } return true; } return true; } [HarmonyPatch(typeof(SceneTransition), "fadeIn")] private static void Prefix(SceneTransition __instance) { if (currentScene == 4 || currentScene == 5) { shopInteriors = GameObject.Find("StoreInteriors"); storeInteriors = new Dictionary<string, Transform>(); Transform[] componentsInChildren = shopInteriors.GetComponentsInChildren<Transform>(true); foreach (Transform val in componentsInChildren) { storeInteriors.TryAdd(((Object)val).name, val); } } else if (currentScene == 1) { shopInteriors = GameObject.Find("Store Interiors"); storeInteriors = new Dictionary<string, Transform>(); Transform[] componentsInChildren2 = shopInteriors.GetComponentsInChildren<Transform>(true); foreach (Transform val2 in componentsInChildren2) { storeInteriors.TryAdd(((Object)val2).name, val2); } radios = GameObject.Find("RadioStationManager").GetComponentsInChildren<Transform>(true); Transform[] array = radios; foreach (Transform val3 in array) { string name = ((Object)((Component)val3).gameObject).name; string text = name; if (!(text == "RadioStationOneActive")) { if (text == "RadioStationTwoActive") { radio2 = ((Component)val3).gameObject; } } else { radio1 = ((Component)val3).gameObject; } } } if (currentScene == 1 || currentScene == 4 || currentScene == 5) { nodes = GameObject.Find("NavigationNodes"); Nodes = new Dictionary<string, Transform>(); Transform[] componentsInChildren3 = nodes.GetComponentsInChildren<Transform>(true); foreach (Transform val4 in componentsInChildren3) { Nodes.TryAdd(((Object)val4).name, val4); } MapNodes = new Dictionary<string, sMapNode>(); sMapNode[] componentsInChildren4 = nodes.GetComponentsInChildren<sMapNode>(true); foreach (sMapNode val5 in componentsInChildren4) { MapNodes.TryAdd(((Object)val5).name, val5); } guy = Object.FindObjectOfType<sCharacterController>(); } else if (currentScene == 6) { guy = Object.FindObjectOfType<sCharacterController>(); } RemoveGate(); if (currentScene != 1 || !EasyDeliveryAP.debug) { return; } foreach (string key in MapNodes.Keys) { if (!Locations.MountainTownNode.TryGetValue(((Object)MapNodes[key]).name, out var value) || value.Town == "Upton") { } ArchipelagoConsole.LogMessage($"{key} - D: {MapNodes[key].destination} - E: {((Behaviour)MapNodes[key]).enabled}"); } } public static void RemoveGate() { if (currentScene == 4 && (APData.radio_towers == "1" || APData.radio_towers == "3") && Items.RadioTower.Received >= 3) { GameObject obj = GameObject.Find("ResetContainer"); if (obj != null) { obj.SetActive(false); } GameObject obj2 = GameObject.Find("ResetVolumes"); if (obj2 != null) { obj2.SetActive(false); } GameObject obj3 = GameObject.Find("Destroy Gate Check"); if (obj3 != null) { obj3.SetActive(false); } GameObject obj4 = GameObject.Find("GATE movable"); if (obj4 != null) { obj4.SetActive(false); } } } [HarmonyPatch(typeof(sHUD), "Start")] private static void Postfix(sHUD __instance) { APGUI.hud = __instance; } [HarmonyPatch(typeof(InteractionPoint), "DoAction", new Type[] { })] [HarmonyPatch(typeof(InteractionPoint), "DoAction", new Type[] { typeof(int) })] private unsafe static bool Prefix(InteractionPoint __instance, ref string __state) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) __state = ((Object)__instance).name; Vector3 position = __instance.listener.transform.position; PositionData value; if (((Object)__instance).name == "throw away" || ((Object)__instance).name == "take") { Dictionary<string, PositionData> dictionary = new Dictionary<string, PositionData>(); if (currentScene == 1) { dictionary = Locations.MountainTownPositions; } else if (currentScene == 4) { dictionary = Locations.FishingTownPositions; } else if (currentScene == 5) { dictionary = Locations.SnowyPeaksPositions; } if (dictionary.TryGetValue(((object)(*(Vector3*)(&position))/*cast due to .constrained prefix*/).ToString(), out value)) { ArchipelagoConsole.LogMessage("VendingBin: " + value.Name, console: false); if (APData.lock_towns == "0") { goto IL_0116; } if (APData.lock_towns == "1") { ItemData itemData = Items.NameToItem[value.Town]; if (itemData != null && itemData.Received > 0) { goto IL_0116; } } } else { ArchipelagoConsole.LogMessage($"VendingBin: {position}", console: false); } } goto IL_0150; IL_0116: archipelago.SendLocations(new long[1] { value.LocationId }); goto IL_0150; IL_0150: if (currentScene == 6 && APData.require_handheld_radio == "1" && ((Object)__instance).name == "enter" && !ItemHandling.radio.Contains(17)) { APGUI.Inform("Cannot enter without a Handheld Radio"); return false; } if (((Object)__instance).name == "Snow Tires" && Items.Tires.Received == 0) { APGUI.Inform("Snow Tires can't\nbe bought yet"); return false; } if (((Object)__instance).name == "Bumper Bar" && Items.Bumper.Received == 0) { APGUI.Inform("Bumper Bar can't\nbe bought yet"); return false; } if (((Object)__instance).name == "Ice Chains" && Items.Chains.Received == 0) { APGUI.Inform("Ice Chains can't\nbe bought yet"); return false; } if (((Object)__instance.listener).name == "Lighter" && Items.Lighter.Received == 0) { APGUI.Inform("Lighter can't\nbe bought yet"); return false; } if (currentScene == 4 && ((Object)__instance.listener).name == "StationEntrance" && (APData.radio_towers == "1" || APData.radio_towers == "3") && Items.RadioTower.Received < 3) { APGUI.Inform("This door lacks radio signal"); return false; } if ((((Object)__instance.listener).name == "FishingRod" && Items.FishingRod.Received == 0) || !(((Object)__instance.listener).name == "CookingPot") || Items.CookingPot.Received == 0) { } return true; } [HarmonyPatch(typeof(InteractionPoint), "DoAction", new Type[] { })] [HarmonyPatch(typeof(InteractionPoint), "DoAction", new Type[] { typeof(int) })] private static void Postfix(InteractionPoint __instance, string __state) { if (!(__state == "turn on")) { return; } if (currentScene == 1) { if (radio1.activeSelf) { archipelago.SendLocation(60L); } if (radio2.activeSelf) { archipelago.SendLocation(61L); } } else if (currentScene == 5) { archipelago.SendLocation(62L); } else if (currentScene == 4) { archipelago.SendLocation(63L); } } [HarmonyPatch(typeof(sSaveSystem), "OnApplicationQuit")] private static void Postfix() { archipelago.Disconnect(); } [HarmonyPatch(typeof(sTeleporter), "Teleport")] private static void Prefix() { if (currentScene == 5) { try { ((Component)storeInteriors["tableAndUpgrade"]).gameObject.SetActive(true); } catch { } } } [HarmonyPatch(typeof(jobBoard), "DrawJobList")] private static void Postfix(jobBoard __instance) { if (!ArchipelagoClient.Authenticated) { return; } ReadOnlyCollection<long> allMissingLocations = archipelago.session.Locations.AllMissingLocations; List<Job> jobs = __instance.jobs; for (int num = jobs.Count - 1; num >= 0; num--) { Job val = jobs[num]; int num2 = 0; bool flag = false; int value5; if (val.isIntercity) { string text; if (((Object)val.to).name == "Mountain Town") { Locations.MountainTownIndex.TryGetValue(val.destinationIndex, out var value); text = value.Town; } else if (((Object)val.to).name == "Snowy Peaks") { Locations.SnowyPeaksIndex.TryGetValue(val.destinationIndex, out var value2); text = value2.Town; } else if (((Object)val.to).name == "Fishing Town") { Locations.FishingTownIndex.TryGetValue(val.destinationIndex, out var value3); text = value3.Town; } else { text = ""; } ((ScreenProgram)__instance).R.put(text, 25f, 24f + (6f + (float)(num * 4)) * 8f); if (Locations.Deliveries.TryGetValue(((Object)val.from.town).name + " to " + text + " Delivery", out var value4)) { if (allMissingLocations.Contains(value4) && (APData.perfect_deliveries == "0" || APData.perfect_deliveries == "1")) { num2++; flag = APData.IsHinted(value4, flag); } if (allMissingLocations.Contains(value4 + 10000) && (APData.perfect_deliveries == "1" || APData.perfect_deliveries == "2")) { num2++; flag = APData.IsHinted(value4 + 10000, flag); } } } else if (Locations.Deliveries.TryGetValue(((Object)val.from.town).name + " to " + ((Object)val.to.town).name + " Delivery", out value5)) { if (allMissingLocations.Contains(value5) && (APData.perfect_deliveries == "0" || APData.perfect_deliveries == "1")) { num2++; flag = APData.IsHinted(value5, flag); } if (allMissingLocations.Contains(value5 + 10000) && (APData.perfect_deliveries == "1" || APData.perfect_deliveries == "2")) { num2++; flag = APData.IsHinted(value5 + 10000, flag); } } if (Locations.Deliveries.TryGetValue(val.startingCityName + " to " + val.destCityName + " Delivery", out var value6)) { if (allMissingLocations.Contains(value6) && (APData.perfect_deliveries == "0" || APData.perfect_deliveries == "1")) { num2++; flag = APData.IsHinted(value6, flag); } if (allMissingLocations.Contains(value6 + 10000) && (APData.perfect_deliveries == "1" || APData.perfect_deliveries == "2")) { num2++; flag = APData.IsHinted(value6 + 10000, flag); } } if (Locations.PayloadDeliveries.TryGetValue(((Object)val.payloadPrefab).name, out var value7) && allMissingLocations.Contains(value7) && APData.payload_checks == "1") { num2++; flag = APData.IsHinted(value7, flag); } if (num2 != 0) { if (flag) { ((ScreenProgram)__instance).R.fput("!", 120f, 24f + (6f + (float)(num * 4)) * 8f, 0f, 13f, 0f, -1); } ((ScreenProgram)__instance).R.fput(num2.ToString(), 128f, 24f + (6f + (float)(num * 4)) * 8f, 0f, 13f, 0f, -1); } } } } [HarmonyPatch] public class ScenePatches { public static string currentScene; public static string lastScene; [HarmonyPatch(typeof(MenuScreenTransition), "Update")] private static void Postfix(MenuScreenTransition __instance) { //IL_0007: 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_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) Scene scene = __instance.screen.scene; currentScene = ((Scene)(ref scene)).name; if (currentScene != lastScene) { ManualLogSource bepinLogger = EasyDeliveryAP.BepinLogger; scene = __instance.screen.scene; bepinLogger.LogMessage((object)("Menu Screen: " + ((Scene)(ref scene)).name)); if (currentScene == "TitleScreen") { EasyDeliveryAP.save.data.handledIndex = 0; } if (lastScene == "TitleScreen") { APData.SaveConnectionOrConnect(); } } lastScene = currentScene; } } public class Testing { private static readonly ArchipelagoClient archipelago = EasyDeliveryAP.ArchipelagoClient; private static List<string> signs = new List<string>(); public static GameObject tiresUpgrade; public static GameObject bumperUpgrade; public static GameObject chainsUpgrade; [HarmonyPatch(typeof(sGoals), "CompleteGoal")] private static void Prefix(Goal __0, sGoals __instance) { ArchipelagoConsole.LogMessage("Goal completed: " + __0.name); } [HarmonyPatch(typeof(GenericItemCheckout), "MakePayment")] private static void Prefix(float __0, GenericItemCheckout __instance) { ArchipelagoConsole.LogMessage($"Buying {((Object)__instance.item).name} for {__0}$"); } [HarmonyPatch(typeof(DeliveryResults), "DoSequence")] private static void Prefix(DeliveryResults __instance) { ArchipelagoConsole.LogMessage($"Paying: {__instance.paying}"); } [HarmonyPatch(typeof(jobBoard), "GenerateJobBetter")] private static void Prefix(int __0, ref jobBoard __instance) { ArchipelagoConsole.LogMessage("Towns:"); Transform[] towns = __instance.navigation.towns; foreach (Transform val in towns) { ArchipelagoConsole.LogMessage(" " + ((Object)val).name); } foreach (ShopInfo shopNode in __instance.navigation.shopNodes) { ArchipelagoConsole.LogMessage("Shop: " + ((Object)shopNode).name + " Node: " + ((Object)shopNode.node).name); } foreach (sMapNode allDestinationNode in __instance.navigation.allDestinationNodes) { } TunnelNode[] tunnelNodes = __instance.tunnelNodes; foreach (TunnelNode val2 in tunnelNodes) { } for (int num = __instance.jobs.Count - 1; num >= 0; num--) { ArchipelagoConsole.LogMessage(((Object)__instance.jobs[num].to).name ?? ""); } } [HarmonyPatch(typeof(jobBoard), "GenerateJobBetter")] private static void Postfix(ref Job __result) { } [HarmonyPatch(typeof(sHUD), "ReceivePayment")] private static void Prefix(ref float __0) { ArchipelagoConsole.LogMessage($"Money Recieved: {__0}"); } [HarmonyPatch(typeof(UpgradeCheckout), "Update")] private static void Postfix(UpgradeCheckout __instance) { if (!((Object)(object)__instance.inventory.heldItem != (Object)null)) { } } [HarmonyPatch(typeof(ConditionalToggle), "Toggle")] private static void Postfix(ConditionalToggle __instance) { ArchipelagoConsole.LogMessage("Toggle: " + ((Object)__instance).name); } [HarmonyPatch(typeof(CreditsHUD), "FrameUpdate")] private static void Prefix(CreditsHUD __instance) { ArchipelagoConsole.LogMessage("Credits: " + ((Object)__instance).name); } [HarmonyPatch(typeof(EndingManager), "SetEnding")] private static void Postfix(Ending __0, EndingManager __instance) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) ArchipelagoConsole.LogMessage($"Ending: {__instance.currentEnding}"); } [HarmonyPatch(typeof(FishingHole), "Catch")] private static void Prefix(FishingHole __instance) { if (__instance.hooked) { ArchipelagoConsole.LogMessage("Fish Caught"); } } [HarmonyPatch(typeof(GachaPurchase), "MakePayment")] private static void Postfix(GachaPurchase __instance) { ArchipelagoConsole.LogMessage($"Gacha: {__instance.newItem}"); } [HarmonyPatch(typeof(GarbageCan), "ThrowOut")] private static void Prefix(int __0, GarbageCan __instance) { } [HarmonyPatch(typeof(GiveGoal), "Start")] private static void Prefix(GiveGoal __instance) { ArchipelagoConsole.LogMessage("GiveGoal"); ArchipelagoConsole.LogMessage($"Goal: {__instance.goalIndex}"); } [HarmonyPatch(typeof(GiveProgram), "Start")] private static void Prefix(GiveProgram __instance) { ArchipelagoConsole.LogMessage("GiveProgram"); ArchipelagoConsole.LogMessage("Program: " + __instance.programName); } [HarmonyPatch(typeof(HandheldRadio), "ButtonPressed")] private static void Prefix(HandheldRadio __instance) { ArchipelagoConsole.LogMessage("Hello"); } [HarmonyPatch(typeof(BigDoor), "Start")] private static void Prefix(BigDoor __instance) { ArchipelagoConsole.LogMessage($"Door: {__instance.doorOpenDuration}"); } [HarmonyPatch(typeof(sTeleporter), "Update")] private static void Prefix(sTeleporter __instance) { if (__instance.teleporting) { ArchipelagoConsole.LogMessage($"Teleporter: {((Object)__instance).name}\nLighter: {Items.Lighter.Received}"); } switch (OtherPatches.currentScene) { case 5: if (((Object)__instance).name == "StoreShop AutoShop" && Items.Tires.Enabled) { Items.Tires.Toggle = true; Items.Tires.Enabled = false; } else if (((Object)__instance).name == "ShopExit" && Items.Tires.Toggle) { Items.Tires.Toggle = false; Items.Tires.Enabled = true; } break; case 4: if (((Object)__instance).name == "StoreShop AutoShop" && Items.Bumper.Enabled) { Items.Bumper.Toggle = true; Items.Bumper.Enabled = false; } else if (((Object)__instance).name == "ShopExit" && Items.Bumper.Toggle) { Items.Bumper.Toggle = false; Items.Bumper.Enabled = true; } if (((Object)__instance).name == "StoreShop AutoShop" && Items.Chains.Enabled) { Items.Chains.Toggle = true; Items.Chains.Enabled = false; } else if (((Object)__instance).name == "ShopExit" && Items.Chains.Toggle) { Items.Chains.Toggle = false; Items.Chains.Enabled = true; } break; case 8: break; case 6: case 7: break; } } [HarmonyPatch(typeof(sSceneConnection), "Update")] private static bool Prefix(sSceneConnection __instance) { if (__instance.connecting) { ArchipelagoConsole.LogMessage($"Scene connect: {((Object)__instance).name} {__instance.nextScene}"); } if (__instance.nextScene != 3 || __instance.nextScene != 1) { return true; } return true; } [HarmonyPatch(typeof(RoadSign), "Update")] private static void Postfix(RoadSign __instance) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: 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_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) Vector3 val = ((Component)__instance.cam).transform.position - ((Component)__instance).transform.position; if (((Vector3)(ref val)).magnitude > 30f || Vector3.Dot(((Component)__instance.cam).transform.forward, ((Vector3)(ref val)).normalized) > 0f) { return; } string item = $"{((Component)__instance).gameObject.transform.position} Enter: {__instance.enterLabel} Exit: {__instance.exitLabel}"; if (signs.Contains(item)) { return; } signs.Add(item); ArchipelagoConsole.LogMessage($"Road sign: {((Object)__instance).name}\n{((Object)((Component)__instance).transform).name}\n {__instance.enterLabel}\n{__instance.exitLabel}\n{((Component)__instance).gameObject.transform.position}"); foreach (string sign in signs) { ArchipelagoConsole.LogMessage("{\"" + sign + "\", }, \\\\ " + __instance.enterLabel); } } [HarmonyPatch(typeof(Crashable), "Start")] private static void Prefix(Crashable __instance) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) ArchipelagoConsole.LogMessage($"Crashable: {((Object)__instance).name}, {((Component)__instance).transform.position}"); } [HarmonyPatch(typeof(InteractiveToggle), "ToggleOn")] private static void Prefix(InteractiveToggle __instance) { ArchipelagoConsole.LogMessage("Interactive toggle: " + ((Object)__instance).name); } [HarmonyPatch(typeof(PurchasableItem), "OnEnable")] private static void Prefix(PurchasableItem __instance) { ArchipelagoConsole.LogMessage("PurchasableItem: " + ((Object)__instance.pickup.listener).name); } [HarmonyPatch(typeof(PurchaseItem), "Start")] private static void Prefix(PurchaseItem __instance) { ArchipelagoConsole.LogMessage("Purchase Item: " + ((Object)__instance).name); } [HarmonyPatch(typeof(PurchaseUpgrade), "Start")] private static void Postfix(PurchaseUpgrade __instance) { ArchipelagoConsole.LogMessage("Purchase Upgrade: " + ((Object)__instance.pickup.interactPointsObject).name); switch (((Object)__instance.upgradeToggle).name) { case "TiresUpgrade": tiresUpgrade = __instance.pickup.interactPointsObject; break; case "BumperUpgrade": bumperUpgrade = __instance.pickup.interactPointsObject; break; case "IceChains": chainsUpgrade = __instance.pickup.interactPointsObject; break; } } [HarmonyPatch(typeof(InventoryWatcher), "Start")] private static void Prefix(InventoryWatcher __instance) { ArchipelagoConsole.LogMessage($"InventoryWatcher: {__instance.pairs[0].hasItem}"); foreach (itemObjectPair pair in __instance.pairs) { ArchipelagoConsole.LogMessage(((Object)pair.hasItem).name ?? ""); } } [HarmonyPatch(typeof(SnowTires), "Start")] private static void Postfix(SnowTires __instance) { ArchipelagoConsole.LogMessage($"Snow Tires: {__instance}"); } [HarmonyPatch(typeof(TunnelNode), "Start")] private static void Postfix(TunnelNode __instance) { ArchipelagoConsole.LogMessage("TunnelNode: " + ((Object)__instance).name); } [HarmonyPatch(typeof(ToggleMapNode), "SetState")] private static void Prefix(ToggleMapNode __instance) { ArchipelagoConsole.LogMessage("ToggleMapNode: " + ((Object)__instance.nodeToToggle).name); } } [HarmonyPatch] public class TunnelPatches { [HarmonyPatch(typeof(sSceneConnection), "Update")] private static bool Prefix(sSceneConnection __instance) { //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) string blocked_tunnels = APData.blocked_tunnels; if (blocked_tunnels == "0" || __instance.justConnected || __instance.nextScene == 1 || Utility.IsNullOrWhiteSpace(blocked_tunnels)) { return true; } if (__instance.nextScene == 5 && ((Items.TunnelSP.Received > 0 && blocked_tunnels == "1") || blocked_tunnels != "1")) { return true; } if (__instance.nextScene == 4 && ((Items.TunnelFT.Received > 0 && blocked_tunnels == "1") || blocked_tunnels != "1")) { return true; } if (__instance.nextScene == 6 && Items.TunnelFactory.Received > 0) { return true; } if (Vector3.Distance(((Component)__instance).gameObject.transform.position, ((Component)__instance.car).transform.position) < 25f) { APGUI.Warning("tunnel under construction"); } return false; } } [BepInPlugin("com.aeromaze.easyDeliveryAP", "EasyDeliveryAP", "0.3.0")] public class EasyDeliveryAP : BaseUnityPlugin { public const string PluginGUID = "com.aeromaze.easyDeliveryAP"; public const string PluginName = "EasyDeliveryAP"; public const string PluginVersion = "0.3.0"; public const string ModDisplayInfo = "EasyDeliveryAP v0.3.0"; private const string APDisplayInfo = "Archipelago v0.6.7"; public static ManualLogSource BepinLogger; public static ArchipelagoClient ArchipelagoClient; public static bool deathLink = false; internal static ModdedSaveSystem<APSaveFile> save = new ModdedSaveSystem<APSaveFile>("Archipelago"); public static ConfigEntry<bool> configConsole; public static ConfigEntry<bool> configDeathLink; public static ConfigEntry<bool> configAutoConnect; public static ConfigEntry<bool> configDebug; public static File TrackerFile; public static Vector2 trackerPosition; public static bool debug = false; private string itemId = ""; private string obj = ""; private bool upton = true; private string debugNode = ""; private void Awake() { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) BepinLogger = ((BaseUnityPlugin)this).Logger; ArchipelagoClient = new ArchipelagoClient(); ArchipelagoConsole.Awake(); new Harmony("com.aeromaze.easyDeliveryAP").PatchAll(); configDeathLink = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "DeathLink", false, "Turn on DeathLink"); configConsole = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShowConsole", false, "Show the ingame console"); configAutoConnect = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "AutoConnect", true, "Automatically connect to the previous connection when opening a save"); if (debug) { configDebug = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "EnableDebug", true, "Enable debug buttons"); } EasyAPI.AddConfig("Archipelago", ((BaseUnityPlugin)this).Config); TrackerFile = EasyAPI.InstantiateFile(); TrackerFile.name = "Tracker"; TrackerFile.type = (FileType)0; TrackerFile.icon = 3; TrackerFile.iconHover = 4; TrackerFile.data = "listener_" + TrackerFile.name; trackerPosition.x = 0.35f; trackerPosition.y = 3.15f; TrackerFile.position = trackerPosition; EasyAPI.AddListener<TrackerApp>(TrackerFile.name); EasyAPI.AddFile((DesktopLocation)0, TrackerFile); ((BaseUnityPlugin)this).Logger.LogMessage((object)"EasyDeliveryAP v0.3.0 loaded!"); Items.GPS.Enabled = true; } private void Update() { if (DeathLinkHandler.deathLinkEnabled != configDeathLink.Value && ArchipelagoClient.Authenticated) { ArchipelagoClient.DeathLinkHandler?.ToggleDeathLink(); } if (!ArchipelagoClient.Authenticated) { APGUI.Warning("Not Connected"); } debug = configDebug?.Value ?? debug; } private void OnGUI() { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: 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_0212: Unknown result type (might be due to invalid IL or missing references) //IL_024d: Unknown result type (mi
BepInEx/plugins/EasyDeliveryAP/Archipelago.MultiClient.Net.dll
Decompiled 12 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.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 © 2026")] [assembly: AssemblyDescription("A client library for use with .NET based prog-langs for interfacing with Archipelago hosts.")] [assembly: AssemblyFileVersion("6.7.1.0")] [assembly: AssemblyInformationalVersion("6.7.1+0c57591db30f2497b0b4fef87164aa2bbe2e51b2")] [assembly: AssemblyProduct("Archipelago.MultiClient.Net")] [assembly: AssemblyTitle("Archipelago.MultiClient.Net")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/ArchipelagoMW/Archipelago.MultiClient.Net")] [assembly: AssemblyVersion("6.7.1.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); } public class AttemptingStringEnumConverter : StringEnumConverter { public AttemptingStringEnumConverter() { } public AttemptingStringEnumConverter(Type namingStrategyType) : base(namingStrategyType) { } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { try { return ((StringEnumConverter)this).ReadJson(reader, objectType, existingValue, serializer); } catch (JsonSerializationException) { return objectType.IsValueType ? Activator.CreateInstance(objectType) : null; } } } 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; } IHintsHelper Hints { 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; } public IHintsHelper Hints { get; } internal ArchipelagoSession(IArchipelagoSocketHelper socket, IReceivedItemsHelper items, ILocationCheckHelper locations, IPlayerHelper players, IRoomStateHelper roomState, ConnectionInfoHelper connectionInfoHelper, IDataStorageHelper dataStorage, IMessageLogHelper messageLog, IHintsHelper createHints) { Socket = socket; Items = items; Locations = locations; Players = players; RoomState = roomState; connectionInfo = connectionInfoHelper; DataStorage = dataStorage; MessageLog = messageLog; Hints = createHints; 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); } } else { loginResultTask.TrySetResult(LoginResult.FromPacket(packet)); } } 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 roomStateHelper = new RoomStateHelper(socket, locationCheckHelper); DataStorageHelper dataStorageHelper = new DataStorageHelper(socket, connectionInfoHelper); MessageLogHelper messageLog = new MessageLogHelper(socket, itemInfoResolver, playerHelper, connectionInfoHelper); HintsHelper createHints = new HintsHelper(socket, playerHelper, locationCheckHelper, roomStateHelper, dataStorageHelper); return new ArchipelagoSession(socket, items, locationCheckHelper, playerHelper, roomStateHelper, connectionInfoHelper, dataStorageHelper, messageLog, createHints); } 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(AttemptingStringEnumConverter))] 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 CreateHintsPacket : ArchipelagoPacketBase { public override ArchipelagoPacketType PacketType => ArchipelagoPacketType.CreateHints; [JsonProperty("locations")] public long[] Locations { get; set; } [JsonProperty("player")] public int Player { get; set; } [JsonProperty("status")] public HintStatus Status { 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(AttemptingStringEnumConverter))] 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_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Invalid comparison between Unknown and I4 //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Invalid comparison between Unknown and I4 //IL_00d8: 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_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: 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(AttemptingStringEnumConverter), new object[] { typeof(SnakeCaseNamingStrategy) })] public JsonMessagePartType? Type { get; set; } [JsonProperty("color")] [JsonConverter(typeof(AttemptingStringEnumConverter), 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(AttemptingStringEnumConverter), 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_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: 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 == 8 && ((string)setReplyPacket.AdditionalArguments["Reference"]).TryParseNGuid(out var g) && operationSpecificCallbacks.TryGetValue(g, out var value)) { value(setReplyPacket.OriginalValue, setReplyPacket.Value, setReplyPacket.AdditionalArguments); operationSpecificCallbacks.Remove(g); } 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 key2 = Guid.NewGuid(); operationSpecificCallbacks[key2] = e.Callbacks; dictionary["Reference"] = JToken.op_Implicit(key2.ToString("N")); 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>());