using System; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using Archipelago.MultiClient.Net; using Archipelago.MultiClient.Net.Enums; using Archipelago.MultiClient.Net.Helpers; using Archipelago.MultiClient.Net.MessageLog.Messages; using Archipelago.MultiClient.Net.Models; using Aube; using Aube.Relays; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using GarfieldKartAPMod.Helpers; using HarmonyLib; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using TMPro; using UnityEngine; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: IgnoresAccessChecksTo("")] [assembly: AssemblyCompany("GarfieldKartAPMod")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+630d9750dd24f040202bb9aa902dfdf55c42b37e")] [assembly: AssemblyProduct("GarfieldKartAPMod")] [assembly: AssemblyTitle("GarfieldKartAPMod")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace GarfieldKartAPMod { public class ArchipelagoClient { private ArchipelagoSession session; private readonly Queue pendingNotifications = new Queue(); public bool IsConnected { get { ArchipelagoSession obj = session; return obj != null && obj.Socket.Connected; } } public event Action OnConnected; public event Action OnConnectionFailed; public event Action OnDisconnected; public void Connect(string hostname, int port, string slotName, string password = "") { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Expected O, but got Unknown //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Expected O, but got Unknown //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Expected O, but got Unknown //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Expected O, but got Unknown //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Expected O, but got Unknown try { Log.Message($"Attempting to connect to {hostname}:{port} as {slotName}"); session = ArchipelagoSessionFactory.CreateSession(hostname, port); session.Socket.ErrorReceived += new ErrorReceivedHandler(OnError); session.Socket.SocketClosed += new SocketClosedHandler(OnSocketClosed); LoginResult val = session.TryConnectAndLogin("Garfield Kart - Furious Racing", slotName, (ItemsHandlingFlags)7, new Version(0, 6, 6), (string[])null, (string)null, string.IsNullOrEmpty(password) ? null : password, true); if (val.Successful) { LoginSuccessful val2 = (LoginSuccessful)val; GarfieldKartAPMod.sessionSlotData = val2.SlotData; Log.Message($"Connected successfully! Slot: {val2.Slot}"); foreach (KeyValuePair slotDatum in val2.SlotData) { Log.Message($"Slot Data: {slotDatum.Key} = {slotDatum.Value}"); } session.MessageLog.OnMessageReceived += new MessageReceivedHandler(OnMessageReceived); ArchipelagoItemTracker.LoadFromServer(); this.OnConnected?.Invoke(); ArchipelagoItemTracker.LogAllReceivedItems(); ArchipelagoItemTracker.LogAllCheckedLocations(); } else { LoginFailure val3 = (LoginFailure)val; string text = string.Join(", ", val3.Errors); Log.Error("Connection failed: " + text); this.OnConnectionFailed?.Invoke(text); session = null; } } catch (Exception ex) { Log.Error($"Connection exception: {ex}"); this.OnConnectionFailed?.Invoke(ex.Message); session = null; } } public ArchipelagoSession GetSession() { return session; } public void Disconnect() { if (session != null) { session.Socket.DisconnectAsync(); session = null; Log.Message("Disconnected from Archipelago"); } } private void OnMessageReceived(LogMessage message) { pendingNotifications.Enqueue(((object)message).ToString()); } private void OnError(Exception ex, string message) { Log.Error("Socket error: " + message + " - " + ex.Message); } private void OnSocketClosed(string reason) { Log.Warning("Socket closed: " + reason); this.OnDisconnected?.Invoke(); } public void SendLocation(long locationId) { if (IsConnected) { ArchipelagoItemTracker.AddCheckedLocation(locationId); session.Locations.CompleteLocationChecks(new long[1] { locationId }); Log.Message($"Sent location check: {locationId}"); } } public string GetSlotDataValue(string key) { if (session == null || GarfieldKartAPMod.sessionSlotData == null) { return null; } if (GarfieldKartAPMod.sessionSlotData.TryGetValue("options", out var value)) { if (1 == 0) { } Dictionary dictionary2; if (!(value is Dictionary dictionary)) { JObject val = (JObject)((value is JObject) ? value : null); dictionary2 = ((val == null) ? null : ((JToken)val).ToObject>()); } else { dictionary2 = dictionary; } if (1 == 0) { } Dictionary dictionary3 = dictionary2; if (dictionary3 != null && dictionary3.TryGetValue(key, out var value2)) { return value2.ToString(); } } if (GarfieldKartAPMod.sessionSlotData.TryGetValue(key, out var value3)) { return value3.ToString(); } throw new SlotDataException("Invalid option requested from apworld: " + key + ". Did you generate on the wrong version?"); } public string GetSeed() { ArchipelagoSession obj = session; object result; if (obj == null) { result = null; } else { IRoomStateHelper roomState = obj.RoomState; result = ((roomState != null) ? roomState.Seed : null); } return (string)result; } public bool HasPendingNotifications() { return pendingNotifications.Count > 0; } public string DequeuePendingNotification() { return pendingNotifications.Dequeue(); } } public static class ArchipelagoConstants { public const long LOC_CATZ_IN_THE_HOOD_VICTORY = 1L; public const long LOC_CRAZY_DUNES_VICTORY = 2L; public const long LOC_PALEROCK_LAKE_VICTORY = 3L; public const long LOC_CITY_SLICKER_VICTORY = 4L; public const long LOC_COUNTRY_BUMPKIN_VICTORY = 5L; public const long LOC_SPOOKY_MANOR_VICTORY = 6L; public const long LOC_MALLY_MARKET_VICTORY = 7L; public const long LOC_VALLEY_OF_THE_KINGS_VICTORY = 8L; public const long LOC_MISTY_FOR_ME_VICTORY = 9L; public const long LOC_SNEAK_A_PEAK_VICTORY = 10L; public const long LOC_BLAZING_OASIS_VICTORY = 11L; public const long LOC_PASTACOSI_FACTORY_VICTORY = 12L; public const long LOC_MYSTERIOUS_TEMPLE_VICTORY = 13L; public const long LOC_PROHIBITED_SITE_VICTORY = 14L; public const long LOC_CASKOU_PARK_VICTORY = 15L; public const long LOC_LOOPY_LAGOON_VICTORY = 16L; public const long LOC_CATZ_IN_THE_HOOD_TIME_TRIAL_BRONZE = 21L; public const long LOC_CRAZY_DUNES_TIME_TRIAL_BRONZE = 22L; public const long LOC_PALEROCK_LAKE_TIME_TRIAL_BRONZE = 23L; public const long LOC_CITY_SLICKER_TIME_TRIAL_BRONZE = 24L; public const long LOC_COUNTRY_BUMPKIN_TIME_TRIAL_BRONZE = 25L; public const long LOC_SPOOKY_MANOR_TIME_TRIAL_BRONZE = 26L; public const long LOC_MALLY_MARKET_TIME_TRIAL_BRONZE = 27L; public const long LOC_VALLEY_OF_THE_KINGS_TIME_TRIAL_BRONZE = 28L; public const long LOC_MISTY_FOR_ME_TIME_TRIAL_BRONZE = 29L; public const long LOC_SNEAK_A_PEAK_TIME_TRIAL_BRONZE = 30L; public const long LOC_BLAZING_OASIS_TIME_TRIAL_BRONZE = 31L; public const long LOC_PASTACOSI_FACTORY_TIME_TRIAL_BRONZE = 32L; public const long LOC_MYSTERIOUS_TEMPLE_TIME_TRIAL_BRONZE = 33L; public const long LOC_PROHIBITED_SITE_TIME_TRIAL_BRONZE = 34L; public const long LOC_CASKOU_PARK_TIME_TRIAL_BRONZE = 35L; public const long LOC_LOOPY_LAGOON_TIME_TRIAL_BRONZE = 36L; public const long LOC_CATZ_IN_THE_HOOD_TIME_TRIAL_SILVER = 41L; public const long LOC_CRAZY_DUNES_TIME_TRIAL_SILVER = 42L; public const long LOC_PALEROCK_LAKE_TIME_TRIAL_SILVER = 43L; public const long LOC_CITY_SLICKER_TIME_TRIAL_SILVER = 44L; public const long LOC_COUNTRY_BUMPKIN_TIME_TRIAL_SILVER = 45L; public const long LOC_SPOOKY_MANOR_TIME_TRIAL_SILVER = 46L; public const long LOC_MALLY_MARKET_TIME_TRIAL_SILVER = 47L; public const long LOC_VALLEY_OF_THE_KINGS_TIME_TRIAL_SILVER = 48L; public const long LOC_MISTY_FOR_ME_TIME_TRIAL_SILVER = 49L; public const long LOC_SNEAK_A_PEAK_TIME_TRIAL_SILVER = 50L; public const long LOC_BLAZING_OASIS_TIME_TRIAL_SILVER = 51L; public const long LOC_PASTACOSI_FACTORY_TIME_TRIAL_SILVER = 52L; public const long LOC_MYSTERIOUS_TEMPLE_TIME_TRIAL_SILVER = 53L; public const long LOC_PROHIBITED_SITE_TIME_TRIAL_SILVER = 54L; public const long LOC_CASKOU_PARK_TIME_TRIAL_SILVER = 55L; public const long LOC_LOOPY_LAGOON_TIME_TRIAL_SILVER = 56L; public const long LOC_CATZ_IN_THE_HOOD_TIME_TRIAL_GOLD = 61L; public const long LOC_CRAZY_DUNES_TIME_TRIAL_GOLD = 62L; public const long LOC_PALEROCK_LAKE_TIME_TRIAL_GOLD = 63L; public const long LOC_CITY_SLICKER_TIME_TRIAL_GOLD = 64L; public const long LOC_COUNTRY_BUMPKIN_TIME_TRIAL_GOLD = 65L; public const long LOC_SPOOKY_MANOR_TIME_TRIAL_GOLD = 66L; public const long LOC_MALLY_MARKET_TIME_TRIAL_GOLD = 67L; public const long LOC_VALLEY_OF_THE_KINGS_TIME_TRIAL_GOLD = 68L; public const long LOC_MISTY_FOR_ME_TIME_TRIAL_GOLD = 69L; public const long LOC_SNEAK_A_PEAK_TIME_TRIAL_GOLD = 70L; public const long LOC_BLAZING_OASIS_TIME_TRIAL_GOLD = 71L; public const long LOC_PASTACOSI_FACTORY_TIME_TRIAL_GOLD = 72L; public const long LOC_MYSTERIOUS_TEMPLE_TIME_TRIAL_GOLD = 73L; public const long LOC_PROHIBITED_SITE_TIME_TRIAL_GOLD = 74L; public const long LOC_CASKOU_PARK_TIME_TRIAL_GOLD = 75L; public const long LOC_LOOPY_LAGOON_TIME_TRIAL_GOLD = 76L; public const long LOC_CATZ_IN_THE_HOOD_TIME_TRIAL_PLATINUM = 81L; public const long LOC_CRAZY_DUNES_TIME_TRIAL_PLATINUM = 82L; public const long LOC_PALEROCK_LAKE_TIME_TRIAL_PLATINUM = 83L; public const long LOC_CITY_SLICKER_TIME_TRIAL_PLATINUM = 84L; public const long LOC_COUNTRY_BUMPKIN_TIME_TRIAL_PLATINUM = 85L; public const long LOC_SPOOKY_MANOR_TIME_TRIAL_PLATINUM = 86L; public const long LOC_MALLY_MARKET_TIME_TRIAL_PLATINUM = 87L; public const long LOC_VALLEY_OF_THE_KINGS_TIME_TRIAL_PLATINUM = 88L; public const long LOC_MISTY_FOR_ME_TIME_TRIAL_PLATINUM = 89L; public const long LOC_SNEAK_A_PEAK_TIME_TRIAL_PLATINUM = 90L; public const long LOC_BLAZING_OASIS_TIME_TRIAL_PLATINUM = 91L; public const long LOC_PASTACOSI_FACTORY_TIME_TRIAL_PLATINUM = 92L; public const long LOC_MYSTERIOUS_TEMPLE_TIME_TRIAL_PLATINUM = 93L; public const long LOC_PROHIBITED_SITE_TIME_TRIAL_PLATINUM = 94L; public const long LOC_CASKOU_PARK_TIME_TRIAL_PLATINUM = 95L; public const long LOC_LOOPY_LAGOON_TIME_TRIAL_PLATINUM = 96L; public const long LOC_LASAGNA_CUP_VICTORY = 101L; public const long LOC_PIZZA_CUP_VICTORY = 102L; public const long LOC_BURGER_CUP_VICTORY = 103L; public const long LOC_ICE_CREAM_CUP_VICTORY = 104L; public const long LOC_CATZ_IN_THE_HOOD_PUZZLE_PIECE_1 = 201L; public const long LOC_CATZ_IN_THE_HOOD_PUZZLE_PIECE_2 = 202L; public const long LOC_CATZ_IN_THE_HOOD_PUZZLE_PIECE_3 = 203L; public const long LOC_CRAZY_DUNES_PUZZLE_PIECE_1 = 204L; public const long LOC_CRAZY_DUNES_PUZZLE_PIECE_2 = 205L; public const long LOC_CRAZY_DUNES_PUZZLE_PIECE_3 = 206L; public const long LOC_PALEROCK_LAKE_PUZZLE_PIECE_1 = 207L; public const long LOC_PALEROCK_LAKE_PUZZLE_PIECE_2 = 208L; public const long LOC_PALEROCK_LAKE_PUZZLE_PIECE_3 = 209L; public const long LOC_CITY_SLICKER_PUZZLE_PIECE_1 = 210L; public const long LOC_CITY_SLICKER_PUZZLE_PIECE_2 = 211L; public const long LOC_CITY_SLICKER_PUZZLE_PIECE_3 = 212L; public const long LOC_COUNTRY_BUMPKIN_PUZZLE_PIECE_1 = 213L; public const long LOC_COUNTRY_BUMPKIN_PUZZLE_PIECE_2 = 214L; public const long LOC_COUNTRY_BUMPKIN_PUZZLE_PIECE_3 = 215L; public const long LOC_SPOOKY_MANOR_PUZZLE_PIECE_1 = 216L; public const long LOC_SPOOKY_MANOR_PUZZLE_PIECE_2 = 217L; public const long LOC_SPOOKY_MANOR_PUZZLE_PIECE_3 = 218L; public const long LOC_MALLY_MARKET_PUZZLE_PIECE_1 = 219L; public const long LOC_MALLY_MARKET_PUZZLE_PIECE_2 = 220L; public const long LOC_MALLY_MARKET_PUZZLE_PIECE_3 = 221L; public const long LOC_VALLEY_OF_THE_KINGS_PUZZLE_PIECE_1 = 222L; public const long LOC_VALLEY_OF_THE_KINGS_PUZZLE_PIECE_2 = 223L; public const long LOC_VALLEY_OF_THE_KINGS_PUZZLE_PIECE_3 = 224L; public const long LOC_MISTY_FOR_ME_PUZZLE_PIECE_1 = 225L; public const long LOC_MISTY_FOR_ME_PUZZLE_PIECE_2 = 226L; public const long LOC_MISTY_FOR_ME_PUZZLE_PIECE_3 = 227L; public const long LOC_SNEAK_A_PEAK_PUZZLE_PIECE_1 = 228L; public const long LOC_SNEAK_A_PEAK_PUZZLE_PIECE_2 = 229L; public const long LOC_SNEAK_A_PEAK_PUZZLE_PIECE_3 = 230L; public const long LOC_BLAZING_OASIS_PUZZLE_PIECE_1 = 231L; public const long LOC_BLAZING_OASIS_PUZZLE_PIECE_2 = 232L; public const long LOC_BLAZING_OASIS_PUZZLE_PIECE_3 = 233L; public const long LOC_PASTACOSI_FACTORY_PUZZLE_PIECE_1 = 234L; public const long LOC_PASTACOSI_FACTORY_PUZZLE_PIECE_2 = 235L; public const long LOC_PASTACOSI_FACTORY_PUZZLE_PIECE_3 = 236L; public const long LOC_MYSTERIOUS_TEMPLE_PUZZLE_PIECE_1 = 237L; public const long LOC_MYSTERIOUS_TEMPLE_PUZZLE_PIECE_2 = 238L; public const long LOC_MYSTERIOUS_TEMPLE_PUZZLE_PIECE_3 = 239L; public const long LOC_PROHIBITED_SITE_PUZZLE_PIECE_1 = 240L; public const long LOC_PROHIBITED_SITE_PUZZLE_PIECE_2 = 241L; public const long LOC_PROHIBITED_SITE_PUZZLE_PIECE_3 = 242L; public const long LOC_CASKOU_PARK_PUZZLE_PIECE_1 = 243L; public const long LOC_CASKOU_PARK_PUZZLE_PIECE_2 = 244L; public const long LOC_CASKOU_PARK_PUZZLE_PIECE_3 = 245L; public const long LOC_LOOPY_LAGOON_PUZZLE_PIECE_1 = 246L; public const long LOC_LOOPY_LAGOON_PUZZLE_PIECE_2 = 247L; public const long LOC_LOOPY_LAGOON_PUZZLE_PIECE_3 = 248L; public const long LOC_CATZ_IN_THE_HOOD_LAP_SANITY = 500L; public const long LOC_CRAZY_DUNES_LAP_SANITY = 510L; public const long LOC_PALEROCK_LAKE_LAP_SANITY = 520L; public const long LOC_CITY_SLICKER_LAP_SANITY = 530L; public const long LOC_COUNTRY_BUMPKIN_LAP_SANITY = 540L; public const long LOC_SPOOKY_MANOR_LAP_SANITY = 550L; public const long LOC_MALLY_MARKET_LAP_SANITY = 560L; public const long LOC_VALLEY_OF_THE_KINGS_LAP_SANITY = 570L; public const long LOC_MISTY_FOR_ME_LAP_SANITY = 580L; public const long LOC_SNEAK_A_PEAK_LAP_SANITY = 590L; public const long LOC_BLAZING_OASIS_LAP_SANITY = 600L; public const long LOC_PASTACOSI_FACTORY_LAP_SANITY = 610L; public const long LOC_MYSTERIOUS_TEMPLE_LAP_SANITY = 620L; public const long LOC_PROHIBITED_SITE_LAP_SANITY = 630L; public const long LOC_CASKOU_PARK_LAP_SANITY = 640L; public const long LOC_LOOPY_LAGOON_LAP_SANITY = 650L; public const long LOC_LASAGNA_CUP_UNLOCK_SPOILER_1 = 301L; public const long LOC_PIZZA_CUP_UNLOCK_SPOILER_1 = 302L; public const long LOC_BURGER_CUP_UNLOCK_SPOILER_1 = 303L; public const long LOC_ICE_CREAM_CUP_UNLOCK_SPOILER_1 = 304L; public const long LOC_LASAGNA_CUP_UNLOCK_SPOILER_2 = 311L; public const long LOC_PIZZA_CUP_UNLOCK_SPOILER_2 = 312L; public const long LOC_BURGER_CUP_UNLOCK_SPOILER_2 = 313L; public const long LOC_ICE_CREAM_CUP_UNLOCK_SPOILER_2 = 314L; public const long LOC_LASAGNA_CUP_UNLOCK_BRONZE_SPOILER_1 = 321L; public const long LOC_PIZZA_CUP_UNLOCK_BRONZE_SPOILER_1 = 322L; public const long LOC_BURGER_CUP_UNLOCK_BRONZE_SPOILER_1 = 323L; public const long LOC_ICE_CREAM_CUP_UNLOCK_BRONZE_SPOILER_1 = 324L; public const long LOC_LASAGNA_CUP_UNLOCK_BRONZE_SPOILER_2 = 331L; public const long LOC_PIZZA_CUP_UNLOCK_BRONZE_SPOILER_2 = 332L; public const long LOC_BURGER_CUP_UNLOCK_BRONZE_SPOILER_2 = 333L; public const long LOC_ICE_CREAM_CUP_UNLOCK_BRONZE_SPOILER_2 = 334L; public const long LOC_LASAGNA_CUP_UNLOCK_SILVER_SPOILER_1 = 341L; public const long LOC_PIZZA_CUP_UNLOCK_SILVER_SPOILER_1 = 342L; public const long LOC_BURGER_CUP_UNLOCK_SILVER_SPOILER_1 = 343L; public const long LOC_ICE_CREAM_CUP_UNLOCK_SILVER_SPOILER_1 = 344L; public const long LOC_LASAGNA_CUP_UNLOCK_SILVER_SPOILER_2 = 351L; public const long LOC_PIZZA_CUP_UNLOCK_SILVER_SPOILER_2 = 352L; public const long LOC_BURGER_CUP_UNLOCK_SILVER_SPOILER_2 = 353L; public const long LOC_ICE_CREAM_CUP_UNLOCK_SILVER_SPOILER_2 = 354L; public const long LOC_LASAGNA_CUP_UNLOCK_GOLD_SPOILER_1 = 361L; public const long LOC_PIZZA_CUP_UNLOCK_GOLD_SPOILER_1 = 362L; public const long LOC_BURGER_CUP_UNLOCK_GOLD_SPOILER_1 = 363L; public const long LOC_ICE_CREAM_CUP_UNLOCK_GOLD_SPOILER_1 = 364L; public const long LOC_LASAGNA_CUP_UNLOCK_GOLD_SPOILER_2 = 371L; public const long LOC_PIZZA_CUP_UNLOCK_GOLD_SPOILER_2 = 372L; public const long LOC_BURGER_CUP_UNLOCK_GOLD_SPOILER_2 = 373L; public const long LOC_ICE_CREAM_CUP_UNLOCK_GOLD_SPOILER_2 = 374L; public const long LOC_CATZ_IN_THE_HOOD_HAT_UNLOCK = 401L; public const long LOC_CRAZY_DUNES_HAT_UNLOCK = 402L; public const long LOC_PALEROCK_LAKE_HAT_UNLOCK = 403L; public const long LOC_CITY_SLICKER_HAT_UNLOCK = 404L; public const long LOC_COUNTRY_BUMPKIN_HAT_UNLOCK = 405L; public const long LOC_SPOOKY_MANOR_HAT_UNLOCK = 406L; public const long LOC_MALLY_MARKET_HAT_UNLOCK = 407L; public const long LOC_VALLEY_OF_THE_KINGS_HAT_UNLOCK = 408L; public const long LOC_MISTY_FOR_ME_HAT_UNLOCK = 409L; public const long LOC_SNEAK_A_PEAK_HAT_UNLOCK = 410L; public const long LOC_BLAZING_OASIS_HAT_UNLOCK = 411L; public const long LOC_PASTACOSI_FACTORY_HAT_UNLOCK = 412L; public const long LOC_MYSTERIOUS_TEMPLE_HAT_UNLOCK = 413L; public const long LOC_PROHIBITED_SITE_HAT_UNLOCK = 414L; public const long LOC_CASKOU_PARK_HAT_UNLOCK = 415L; public const long LOC_LOOPY_LAGOON_HAT_UNLOCK = 416L; public const long LOC_CATZ_IN_THE_HOOD_BRONZE_HAT_UNLOCK = 421L; public const long LOC_CRAZY_DUNES_BRONZE_HAT_UNLOCK = 422L; public const long LOC_PALEROCK_LAKE_BRONZE_HAT_UNLOCK = 423L; public const long LOC_CITY_SLICKER_BRONZE_HAT_UNLOCK = 424L; public const long LOC_COUNTRY_BUMPKIN_BRONZE_HAT_UNLOCK = 425L; public const long LOC_SPOOKY_MANOR_BRONZE_HAT_UNLOCK = 426L; public const long LOC_MALLY_MARKET_BRONZE_HAT_UNLOCK = 427L; public const long LOC_VALLEY_OF_THE_KINGS_BRONZE_HAT_UNLOCK = 428L; public const long LOC_MISTY_FOR_ME_BRONZE_HAT_UNLOCK = 429L; public const long LOC_SNEAK_A_PEAK_BRONZE_HAT_UNLOCK = 430L; public const long LOC_BLAZING_OASIS_BRONZE_HAT_UNLOCK = 431L; public const long LOC_PASTACOSI_FACTORY_BRONZE_HAT_UNLOCK = 432L; public const long LOC_MYSTERIOUS_TEMPLE_BRONZE_HAT_UNLOCK = 433L; public const long LOC_PROHIBITED_SITE_BRONZE_HAT_UNLOCK = 434L; public const long LOC_CASKOU_PARK_BRONZE_HAT_UNLOCK = 435L; public const long LOC_LOOPY_LAGOON_BRONZE_HAT_UNLOCK = 436L; public const long LOC_CATZ_IN_THE_HOOD_SILVER_HAT_UNLOCK = 441L; public const long LOC_CRAZY_DUNES_SILVER_HAT_UNLOCK = 442L; public const long LOC_PALEROCK_LAKE_SILVER_HAT_UNLOCK = 443L; public const long LOC_CITY_SLICKER_SILVER_HAT_UNLOCK = 444L; public const long LOC_COUNTRY_BUMPKIN_SILVER_HAT_UNLOCK = 445L; public const long LOC_SPOOKY_MANOR_SILVER_HAT_UNLOCK = 446L; public const long LOC_MALLY_MARKET_SILVER_HAT_UNLOCK = 447L; public const long LOC_VALLEY_OF_THE_KINGS_SILVER_HAT_UNLOCK = 448L; public const long LOC_MISTY_FOR_ME_SILVER_HAT_UNLOCK = 449L; public const long LOC_SNEAK_A_PEAK_SILVER_HAT_UNLOCK = 450L; public const long LOC_BLAZING_OASIS_SILVER_HAT_UNLOCK = 451L; public const long LOC_PASTACOSI_FACTORY_SILVER_HAT_UNLOCK = 452L; public const long LOC_MYSTERIOUS_TEMPLE_SILVER_HAT_UNLOCK = 453L; public const long LOC_PROHIBITED_SITE_SILVER_HAT_UNLOCK = 454L; public const long LOC_CASKOU_PARK_SILVER_HAT_UNLOCK = 455L; public const long LOC_LOOPY_LAGOON_SILVER_HAT_UNLOCK = 456L; public const long LOC_CATZ_IN_THE_HOOD_GOLD_HAT_UNLOCK = 461L; public const long LOC_CRAZY_DUNES_GOLD_HAT_UNLOCK = 462L; public const long LOC_PALEROCK_LAKE_GOLD_HAT_UNLOCK = 463L; public const long LOC_CITY_SLICKER_GOLD_HAT_UNLOCK = 464L; public const long LOC_COUNTRY_BUMPKIN_GOLD_HAT_UNLOCK = 465L; public const long LOC_SPOOKY_MANOR_GOLD_HAT_UNLOCK = 466L; public const long LOC_MALLY_MARKET_GOLD_HAT_UNLOCK = 467L; public const long LOC_VALLEY_OF_THE_KINGS_GOLD_HAT_UNLOCK = 468L; public const long LOC_MISTY_FOR_ME_GOLD_HAT_UNLOCK = 469L; public const long LOC_SNEAK_A_PEAK_GOLD_HAT_UNLOCK = 470L; public const long LOC_BLAZING_OASIS_GOLD_HAT_UNLOCK = 471L; public const long LOC_PASTACOSI_FACTORY_GOLD_HAT_UNLOCK = 472L; public const long LOC_MYSTERIOUS_TEMPLE_GOLD_HAT_UNLOCK = 473L; public const long LOC_PROHIBITED_SITE_GOLD_HAT_UNLOCK = 474L; public const long LOC_CASKOU_PARK_GOLD_HAT_UNLOCK = 475L; public const long LOC_LOOPY_LAGOON_GOLD_HAT_UNLOCK = 476L; public const long LOC_WIN_RACE_AS_GARFIELD = 1001L; public const long LOC_WIN_RACE_AS_JON = 1002L; public const long LOC_WIN_RACE_AS_LIZ = 1003L; public const long LOC_WIN_RACE_AS_ODIE = 1004L; public const long LOC_WIN_RACE_AS_ARLENE = 1005L; public const long LOC_WIN_RACE_AS_NERMAL = 1006L; public const long LOC_WIN_RACE_AS_SQUEAK = 1007L; public const long LOC_WIN_RACE_AS_HARRY = 1008L; public const long LOC_WIN_RACE_WITH_FORMULA_ZZZZ = 1051L; public const long LOC_WIN_RACE_WITH_ABSTRACT_KART = 1052L; public const long LOC_WIN_RACE_WITH_MEDI_KART = 1053L; public const long LOC_WIN_RACE_WITH_WOOF_MOBILE = 1054L; public const long LOC_WIN_RACE_WITH_KISSY_KART = 1055L; public const long LOC_WIN_RACE_WITH_CUTIE_PIE_CAT = 1056L; public const long LOC_WIN_RACE_WITH_RAT_RACER = 1057L; public const long LOC_WIN_RACE_WITH_MUCK_MADNESS = 1058L; public const long LOC_FIND_ITEM_PIE = 1101L; public const long LOC_FIND_ITEM_HOMING_PIE = 1102L; public const long LOC_FIND_ITEM_DIAMOND = 1103L; public const long LOC_FIND_ITEM_MAGIC_WAND = 1104L; public const long LOC_FIND_ITEM_PERFUME = 1105L; public const long LOC_FIND_ITEM_LASAGNA = 1106L; public const long LOC_FIND_ITEM_UFO = 1107L; public const long LOC_FIND_ITEM_PILLOW = 1108L; public const long LOC_FIND_ITEM_SPRING = 1109L; public const long ITEM_PUZZLE_PIECE = 49L; public const long ITEM_PROGRESSIVE_COURSE_UNLOCK = 100L; public const long ITEM_COURSE_UNLOCK_CATZ_IN_THE_HOOD = 101L; public const long ITEM_COURSE_UNLOCK_CRAZY_DUNES = 102L; public const long ITEM_COURSE_UNLOCK_PALEROCK_LAKE = 103L; public const long ITEM_COURSE_UNLOCK_CITY_SLICKER = 104L; public const long ITEM_COURSE_UNLOCK_COUNTRY_BUMPKIN = 105L; public const long ITEM_COURSE_UNLOCK_SPOOKY_MANOR = 106L; public const long ITEM_COURSE_UNLOCK_MALLY_MARKET = 107L; public const long ITEM_COURSE_UNLOCK_VALLEY_OF_THE_KINGS = 108L; public const long ITEM_COURSE_UNLOCK_MISTY_FOR_ME = 109L; public const long ITEM_COURSE_UNLOCK_SNEAK_A_PEAK = 110L; public const long ITEM_COURSE_UNLOCK_BLAZING_OASIS = 111L; public const long ITEM_COURSE_UNLOCK_PASTACOSI_FACTORY = 112L; public const long ITEM_COURSE_UNLOCK_MYSTERIOUS_TEMPLE = 113L; public const long ITEM_COURSE_UNLOCK_PROHIBITED_SITE = 114L; public const long ITEM_COURSE_UNLOCK_CASKOU_PARK = 115L; public const long ITEM_COURSE_UNLOCK_LOOPY_LAGOON = 116L; public const long ITEM_PROGRESSIVE_TIME_TRIAL_UNLOCK = 150L; public const long ITEM_TIME_TRIAL_UNLOCK_CATZ_IN_THE_HOOD = 151L; public const long ITEM_TIME_TRIAL_UNLOCK_CRAZY_DUNES = 152L; public const long ITEM_TIME_TRIAL_UNLOCK_PALEROCK_LAKE = 153L; public const long ITEM_TIME_TRIAL_UNLOCK_CITY_SLICKER = 154L; public const long ITEM_TIME_TRIAL_UNLOCK_COUNTRY_BUMPKIN = 155L; public const long ITEM_TIME_TRIAL_UNLOCK_SPOOKY_MANOR = 156L; public const long ITEM_TIME_TRIAL_UNLOCK_MALLY_MARKET = 157L; public const long ITEM_TIME_TRIAL_UNLOCK_VALLEY_OF_THE_KINGS = 158L; public const long ITEM_TIME_TRIAL_UNLOCK_MISTY_FOR_ME = 159L; public const long ITEM_TIME_TRIAL_UNLOCK_SNEAK_A_PEAK = 160L; public const long ITEM_TIME_TRIAL_UNLOCK_BLAZING_OASIS = 161L; public const long ITEM_TIME_TRIAL_UNLOCK_PASTACOSI_FACTORY = 162L; public const long ITEM_TIME_TRIAL_UNLOCK_MYSTERIOUS_TEMPLE = 163L; public const long ITEM_TIME_TRIAL_UNLOCK_PROHIBITED_SITE = 164L; public const long ITEM_TIME_TRIAL_UNLOCK_CASKOU_PARK = 165L; public const long ITEM_TIME_TRIAL_UNLOCK_LOOPY_LAGOON = 166L; public const long ITEM_PROGRESSIVE_CUP_UNLOCK = 200L; public const long ITEM_CUP_UNLOCK_LASAGNA = 201L; public const long ITEM_CUP_UNLOCK_PIZZA = 202L; public const long ITEM_CUP_UNLOCK_BURGER = 203L; public const long ITEM_CUP_UNLOCK_ICE_CREAM = 204L; public const long ITEM_CHARACTER_GARFIELD = 301L; public const long ITEM_CHARACTER_JON = 302L; public const long ITEM_CHARACTER_LIZ = 303L; public const long ITEM_CHARACTER_ODIE = 304L; public const long ITEM_CHARACTER_ARLENE = 305L; public const long ITEM_CHARACTER_NERMAL = 306L; public const long ITEM_CHARACTER_SQUEAK = 307L; public const long ITEM_CHARACTER_HARRY = 308L; public const long ITEM_KART_FORMULA_ZZZZ = 351L; public const long ITEM_KART_ABSTRACT_KART = 352L; public const long ITEM_KART_MEDI_KART = 353L; public const long ITEM_KART_WOOF_MOBILE = 354L; public const long ITEM_KART_KISSY_KART = 355L; public const long ITEM_KART_CUTIE_PIE_CAT = 356L; public const long ITEM_KART_RAT_RACER = 357L; public const long ITEM_KART_MUCK_MADNESS = 358L; public const long ITEM_PROGRESSIVE_BEDDY_BYE_CAP = 401L; public const long ITEM_PROGRESSIVE_WHIZZY_WIZARD = 402L; public const long ITEM_PROGRESSIVE_TIC_TOQUE = 403L; public const long ITEM_PROGRESSIVE_ELASTO_HAT = 404L; public const long ITEM_PROGRESSIVE_CHEFS_SPECIAL = 405L; public const long ITEM_PROGRESSIVE_CUTIE_PIE_CROWN = 406L; public const long ITEM_PROGRESSIVE_VIKING_HELMET = 407L; public const long ITEM_PROGRESSIVE_STINK_O_RAMA = 408L; public const long ITEM_PROGRESSIVE_SPACE_BUBBLE = 409L; public const long ITEM_PROGRESSIVE_PIZZAIOLO_HAT = 410L; public const long ITEM_PROGRESSIVE_BUNNY_BAND = 411L; public const long ITEM_PROGRESSIVE_JOE_MONTAGNA = 412L; public const long ITEM_PROGRESSIVE_ARISTO_CATIC_BICORN = 413L; public const long ITEM_PROGRESSIVE_TOUTANKHAMEOW = 414L; public const long ITEM_PROGRESSIVE_APPRENTICE_SORCERER = 415L; public const long ITEM_PROGRESSIVE_MULE_HEAD = 416L; public const long ITEM_UNLOCK_BEDDY_BYE_CAP = 421L; public const long ITEM_UNLOCK_WHIZZY_WIZARD = 422L; public const long ITEM_UNLOCK_TIC_TOQUE = 423L; public const long ITEM_UNLOCK_ELASTO_HAT = 424L; public const long ITEM_UNLOCK_CHEFS_SPECIAL = 425L; public const long ITEM_UNLOCK_CUTIE_PIE_CROWN = 426L; public const long ITEM_UNLOCK_VIKING_HELMET = 427L; public const long ITEM_UNLOCK_STINK_O_RAMA = 428L; public const long ITEM_UNLOCK_SPACE_BUBBLE = 429L; public const long ITEM_UNLOCK_PIZZAIOLO_HAT = 430L; public const long ITEM_UNLOCK_BUNNY_BAND = 431L; public const long ITEM_UNLOCK_JOE_MONTAGNA = 432L; public const long ITEM_UNLOCK_ARISTO_CATIC_BICORN = 433L; public const long ITEM_UNLOCK_TOUTANKHAMEOW = 434L; public const long ITEM_UNLOCK_APPRENTICE_SORCERER = 435L; public const long ITEM_UNLOCK_MULE_HEAD = 436L; public const long ITEM_PROGRESSIVE_BOMBASTIC_SPOILER = 501L; public const long ITEM_PROGRESSIVE_WHACKY_SPOILER = 502L; public const long ITEM_PROGRESSIVE_SUPERFIT_SPOILER = 503L; public const long ITEM_PROGRESSIVE_CYCLOBONE_SPOILER = 504L; public const long ITEM_PROGRESSIVE_FOXY_SPOILER = 505L; public const long ITEM_PROGRESSIVE_SHIMMERING_SPOILER = 506L; public const long ITEM_PROGRESSIVE_HOLEY_MOLEY_SPOILER = 507L; public const long ITEM_PROGRESSIVE_STAINED_SPOILER = 508L; public const long ITEM_UNLOCK_BOMBASTIC_SPOILER = 521L; public const long ITEM_UNLOCK_WHACKY_SPOILER = 522L; public const long ITEM_UNLOCK_SUPERFIT_SPOILER = 523L; public const long ITEM_UNLOCK_CYCLOBONE_SPOILER = 524L; public const long ITEM_UNLOCK_FOXY_SPOILER = 525L; public const long ITEM_UNLOCK_SHIMMERING_SPOILER = 526L; public const long ITEM_UNLOCK_HOLEY_MOLEY_SPOILER = 527L; public const long ITEM_UNLOCK_STAINED_SPOILER = 528L; public const long ITEM_PIE = 901L; public const long ITEM_HOMING_PIE = 902L; public const long ITEM_DIAMOND = 903L; public const long ITEM_MAGIC_WAND = 904L; public const long ITEM_PERFUME = 905L; public const long ITEM_LASAGNA = 906L; public const long ITEM_UFO = 907L; public const long ITEM_PILLOW = 908L; public const long ITEM_SPRING = 909L; public const long ITEM_FILLER = 1000L; public const long ITEM_GIVE_ITEM_FILLER = 1001L; public const long ITEM_TRAP = 1500L; public const long ITEM_HANDLING_TRAP = 1501L; public const long GOAL_GRAND_PRIX = 0L; public const long GOAL_RACES = 1L; public const long GOAL_TIME_TRIALS = 2L; public const long GOAL_PUZZLE_PIECE = 3L; public const long OPTION_RANDOMIZE_RACES_CUPS = 0L; public const long OPTION_RANDOMIZE_RACES_RACES = 1L; public const long OPTION_RANDOMIZE_RACES_BOTH = 2L; public const long OPTION_RANDOMIZE_HATS_SPOILERS_OFF = 0L; public const long OPTION_RANDOMIZE_HATS_SPOILERS_PROG = 1L; public const long OPTION_RANDOMIZE_HATS_SPOILERS_COMBINE = 2L; public static string GetSceneNameFromTrackId(TrackId trackId) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Expected I4, but got Unknown if (1 == 0) { } string result = (int)trackId switch { 4 => "E2C1", 12 => "E4C1", 8 => "E3C1", 0 => "E1C1", 9 => "E3C2", 5 => "E2C2", 1 => "E1C2", 13 => "E4C2", 2 => "E1C3", 10 => "E3C3", 14 => "E4C3", 6 => "E2C3", 15 => "E4C4", 3 => "E1C4", 7 => "E2C4", 11 => "E3C4", _ => null, }; if (1 == 0) { } return result; } public static long GetRaceVictoryLoc(string startScene) { if (1 == 0) { } long result = startScene switch { "E2C1" => 1L, "E4C1" => 2L, "E3C1" => 3L, "E1C1" => 4L, "E3C2" => 5L, "E2C2" => 6L, "E1C2" => 7L, "E4C2" => 8L, "E1C3" => 9L, "E3C3" => 10L, "E4C3" => 11L, "E2C3" => 12L, "E4C4" => 13L, "E1C4" => 14L, "E2C4" => 15L, "E3C4" => 16L, _ => -1L, }; if (1 == 0) { } return result; } public static long GetPuzzlePieceLoc(string startScene, int puzzleIndex) { if (1 == 0) { } long result = startScene switch { "E2C1" => 201L + (long)puzzleIndex, "E4C1" => 204L + (long)puzzleIndex, "E3C1" => 207L + (long)puzzleIndex, "E1C1" => 210L + (long)puzzleIndex, "E3C2" => 213L + (long)puzzleIndex, "E2C2" => 216L + (long)puzzleIndex, "E1C2" => 219L + (long)puzzleIndex, "E4C2" => 222L + (long)puzzleIndex, "E1C3" => 225L + (long)puzzleIndex, "E3C3" => 228L + (long)puzzleIndex, "E4C3" => 231L + (long)puzzleIndex, "E2C3" => 234L + (long)puzzleIndex, "E4C4" => 237L + (long)puzzleIndex, "E1C4" => 240L + (long)puzzleIndex, "E2C4" => 243L + (long)puzzleIndex, "E3C4" => 246L + (long)puzzleIndex, _ => -1L, }; if (1 == 0) { } return result; } public static long GetLapSanityLoc(string startScene, int lapIndex) { if (1 == 0) { } long num = startScene switch { "E2C1" => 500L, "E4C1" => 510L, "E3C1" => 520L, "E1C1" => 530L, "E3C2" => 540L, "E2C2" => 550L, "E1C2" => 560L, "E4C2" => 570L, "E1C3" => 580L, "E3C3" => 590L, "E4C3" => 600L, "E2C3" => 610L, "E4C4" => 620L, "E1C4" => 630L, "E2C4" => 640L, "E3C4" => 650L, _ => -1L, }; if (1 == 0) { } long num2 = num; if (num2 == -1) { return -1L; } return num2 + lapIndex; } public static List GetTimeTrialLocs(string startScene, E_TimeTrialMedal medal) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Expected I4, but got Unknown int num = (int)medal; List list = new List(); if (num == 0) { return list; } switch (startScene) { case "E2C1": if (num >= 1) { list.Add(21L); } if (num >= 2) { list.Add(41L); } if (num >= 3) { list.Add(61L); } if (num >= 4) { list.Add(81L); } break; case "E4C1": if (num >= 1) { list.Add(22L); } if (num >= 2) { list.Add(42L); } if (num >= 3) { list.Add(62L); } if (num >= 4) { list.Add(82L); } break; case "E3C1": if (num >= 1) { list.Add(23L); } if (num >= 2) { list.Add(43L); } if (num >= 3) { list.Add(63L); } if (num >= 4) { list.Add(83L); } break; case "E1C1": if (num >= 1) { list.Add(24L); } if (num >= 2) { list.Add(44L); } if (num >= 3) { list.Add(64L); } if (num >= 4) { list.Add(84L); } break; case "E3C2": if (num >= 1) { list.Add(25L); } if (num >= 2) { list.Add(45L); } if (num >= 3) { list.Add(65L); } if (num >= 4) { list.Add(85L); } break; case "E2C2": if (num >= 1) { list.Add(26L); } if (num >= 2) { list.Add(46L); } if (num >= 3) { list.Add(66L); } if (num >= 4) { list.Add(86L); } break; case "E1C2": if (num >= 1) { list.Add(27L); } if (num >= 2) { list.Add(47L); } if (num >= 3) { list.Add(67L); } if (num >= 4) { list.Add(87L); } break; case "E4C2": if (num >= 1) { list.Add(28L); } if (num >= 2) { list.Add(48L); } if (num >= 3) { list.Add(68L); } if (num >= 4) { list.Add(88L); } break; case "E1C3": if (num >= 1) { list.Add(29L); } if (num >= 2) { list.Add(49L); } if (num >= 3) { list.Add(69L); } if (num >= 4) { list.Add(89L); } break; case "E3C3": if (num >= 1) { list.Add(30L); } if (num >= 2) { list.Add(50L); } if (num >= 3) { list.Add(70L); } if (num >= 4) { list.Add(90L); } break; case "E4C3": if (num >= 1) { list.Add(31L); } if (num >= 2) { list.Add(51L); } if (num >= 3) { list.Add(71L); } if (num >= 4) { list.Add(91L); } break; case "E2C3": if (num >= 1) { list.Add(32L); } if (num >= 2) { list.Add(52L); } if (num >= 3) { list.Add(72L); } if (num >= 4) { list.Add(92L); } break; case "E4C4": if (num >= 1) { list.Add(33L); } if (num >= 2) { list.Add(53L); } if (num >= 3) { list.Add(73L); } if (num >= 4) { list.Add(93L); } break; case "E1C4": if (num >= 1) { list.Add(34L); } if (num >= 2) { list.Add(54L); } if (num >= 3) { list.Add(74L); } if (num >= 4) { list.Add(94L); } break; case "E2C4": if (num >= 1) { list.Add(35L); } if (num >= 2) { list.Add(55L); } if (num >= 3) { list.Add(75L); } if (num >= 4) { list.Add(95L); } break; case "E3C4": if (num >= 1) { list.Add(36L); } if (num >= 2) { list.Add(56L); } if (num >= 3) { list.Add(76L); } if (num >= 4) { list.Add(96L); } break; } return list; } public static List GetHatLocs(string startScene, Difficulty difficulty) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Expected I4, but got Unknown int num = (int)difficulty; List list = new List(); switch (startScene) { case "E2C1": list.Add(401L); if (num >= 0) { list.Add(421L); } if (num >= 1) { list.Add(441L); } if (num >= 2) { list.Add(461L); } break; case "E4C1": list.Add(402L); if (num >= 0) { list.Add(422L); } if (num >= 1) { list.Add(442L); } if (num >= 2) { list.Add(462L); } break; case "E3C1": list.Add(403L); if (num >= 0) { list.Add(423L); } if (num >= 1) { list.Add(443L); } if (num >= 2) { list.Add(463L); } break; case "E1C1": list.Add(404L); if (num >= 0) { list.Add(424L); } if (num >= 1) { list.Add(444L); } if (num >= 2) { list.Add(464L); } break; case "E3C2": list.Add(405L); if (num >= 0) { list.Add(425L); } if (num >= 1) { list.Add(445L); } if (num >= 2) { list.Add(465L); } break; case "E2C2": list.Add(406L); if (num >= 0) { list.Add(426L); } if (num >= 1) { list.Add(446L); } if (num >= 2) { list.Add(466L); } break; case "E1C2": list.Add(407L); if (num >= 0) { list.Add(427L); } if (num >= 1) { list.Add(447L); } if (num >= 2) { list.Add(467L); } break; case "E4C2": list.Add(408L); if (num >= 0) { list.Add(428L); } if (num >= 1) { list.Add(448L); } if (num >= 2) { list.Add(468L); } break; case "E1C3": list.Add(409L); if (num >= 0) { list.Add(429L); } if (num >= 1) { list.Add(449L); } if (num >= 2) { list.Add(469L); } break; case "E3C3": list.Add(410L); if (num >= 0) { list.Add(430L); } if (num >= 1) { list.Add(450L); } if (num >= 2) { list.Add(470L); } break; case "E4C3": list.Add(411L); if (num >= 0) { list.Add(431L); } if (num >= 1) { list.Add(451L); } if (num >= 2) { list.Add(471L); } break; case "E2C3": list.Add(412L); if (num >= 0) { list.Add(432L); } if (num >= 1) { list.Add(452L); } if (num >= 2) { list.Add(472L); } break; case "E4C4": list.Add(413L); if (num >= 0) { list.Add(433L); } if (num >= 1) { list.Add(453L); } if (num >= 2) { list.Add(473L); } break; case "E1C4": list.Add(414L); if (num >= 0) { list.Add(434L); } if (num >= 1) { list.Add(454L); } if (num >= 2) { list.Add(474L); } break; case "E2C4": list.Add(415L); if (num >= 0) { list.Add(435L); } if (num >= 1) { list.Add(455L); } if (num >= 2) { list.Add(475L); } break; case "E3C4": list.Add(416L); if (num >= 0) { list.Add(436L); } if (num >= 1) { list.Add(456L); } if (num >= 2) { list.Add(476L); } break; } return list; } public static long GetHatItemId(string hat, bool progressive) { switch (hat) { case "EgyptPriestHatN": case "EgyptPriestHatR": case "EgyptPriestHatU": return progressive ? 403 : 423; case "SleepingHatN": case "SleepingHatR": case "SleepingHatU": return progressive ? 401 : 421; case "PharaonHatN": case "PharaonHatR": case "PharaonHatU": return progressive ? 414 : 434; case "BeautyHatN": case "BeautyHatR": case "BeautyHatU": return progressive ? 413 : 433; case "PiratHatN": case "PiratHatR": case "PiratHatU": return progressive ? 408 : 428; case "FootballHelmetN": case "FootballHelmetR": case "FootballHelmetU": return progressive ? 412 : 432; case "ChickenHatN": case "ChickenHatR": case "ChickenHatU": return progressive ? 404 : 424; case "SpaceHelmetN": case "SpaceHelmetR": case "SpaceHelmetU": return progressive ? 409 : 429; case "CrownHatN": case "CrownHatR": case "CrownHatU": return progressive ? 406 : 426; case "PizzaioloHatN": case "PizzaioloHatR": case "PizzaioloHatU": return progressive ? 410 : 430; case "VikingHelmetN": case "VikingHelmetR": case "VikingHelmetU": return progressive ? 407 : 427; case "MagicHatN": case "MagicHatR": case "MagicHatU": return progressive ? 402 : 422; case "WizardHatN": case "WizardHatR": case "WizardHatU": return progressive ? 415 : 435; case "DunkeyHatN": case "DunkeyHatR": case "DunkeyHatU": return progressive ? 416 : 436; case "PastryHatN": case "PastryHatR": case "PastryHatU": return progressive ? 405 : 425; case "RabbitHatN": case "RabbitHatR": case "RabbitHatU": return progressive ? 411 : 431; default: return -1L; } } public static List GetSpoilerLocs(int cupId, Difficulty difficulty) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Expected I4, but got Unknown int num = (int)difficulty; List list = new List(); switch (cupId) { case 0: list.Add(301L); list.Add(311L); if (num >= 0) { list.Add(321L); list.Add(331L); } if (num >= 1) { list.Add(341L); list.Add(351L); } if (num >= 2) { list.Add(361L); list.Add(371L); } break; case 1: list.Add(302L); list.Add(312L); if (num >= 0) { list.Add(322L); list.Add(332L); } if (num >= 1) { list.Add(342L); list.Add(352L); } if (num >= 2) { list.Add(362L); list.Add(372L); } break; case 2: list.Add(303L); list.Add(313L); if (num >= 0) { list.Add(323L); list.Add(333L); } if (num >= 1) { list.Add(343L); list.Add(353L); } if (num >= 2) { list.Add(363L); list.Add(373L); } break; case 3: list.Add(304L); list.Add(314L); if (num >= 0) { list.Add(324L); list.Add(334L); } if (num >= 1) { list.Add(344L); list.Add(354L); } if (num >= 2) { list.Add(364L); list.Add(374L); } break; } return list; } public static long GetSpoilerItemId(string custom, bool progressive) { switch (custom) { case "KGC_ManiabilityN": case "KGC_ManiabilityR": case "KGC_ManiabilityU": return progressive ? 415 : 435; case "KJC_SpeedN": case "KJC_SpeedR": case "KJC_SpeedU": return progressive ? 502 : 522; case "KLC_AccelerationN": case "KLC_AccelerationR": case "KLC_AccelerationU": return progressive ? 503 : 523; case "KOC_AccelerationN": case "KOC_AccelerationR": case "KOC_AccelerationU": return progressive ? 504 : 524; case "KAC_AccelerationN": case "KAC_AccelerationR": case "KAC_AccelerationU": return progressive ? 505 : 525; case "KNC_AccelerationN": case "KNC_AccelerationR": case "KNC_AccelerationU": return progressive ? 506 : 526; case "KSC_ManiabilityN": case "KSC_ManiabilityR": case "KSC_ManiabilityU": return progressive ? 507 : 527; case "KHC_SpeedN": case "KHC_SpeedR": case "KHC_SpeedU": return progressive ? 508 : 528; default: return -1L; } } } public class ArchipelagoItemTracker { private static readonly ConcurrentDictionary receivedItems = new ConcurrentDictionary(); private static readonly ConcurrentDictionary checkedLocations = new ConcurrentDictionary(); public static void Initialize() { Log.Message("Initializing Archipelago Item Tracker"); } public static void AddReceivedItem(long itemId) { receivedItems.AddOrUpdate(itemId, 1, (long _, int existing) => existing + 1); } public static bool HasItem(long itemId) { return receivedItems.ContainsKey(itemId); } public static int AmountOfItem(long itemId) { return CollectionExtensions.GetValueOrDefault((IReadOnlyDictionary)receivedItems, itemId, 0); } public static void AddCheckedLocation(long locationId) { checkedLocations.TryAdd(locationId, 0); } public static bool HasLocation(long locationId) { return checkedLocations.ContainsKey(locationId); } public static int GetCheckedLocationCount() { return checkedLocations.Count; } public static void Clear() { receivedItems.Clear(); checkedLocations.Clear(); Log.Message("[AP] Cleared all received items and checked locations"); } public static void LoadFromServer() { try { ArchipelagoSession session = GarfieldKartAPMod.APClient.GetSession(); if (session == null) { return; } Clear(); List list = session.Items.AllItemsReceived?.ToList(); if (list != null) { Log.Message($"[AP] Loading {list.Count} items from server"); foreach (ItemInfo item in list) { Log.Message($"[AP] Item: {item.ItemName} (ID: {item.ItemId})"); receivedItems.AddOrUpdate(item.ItemId, 1, (long _, int existing) => existing + 1); } } List list2 = session.Locations.AllLocationsChecked?.ToList(); if (list2 == null) { return; } Log.Message($"[AP] Loading {list2.Count} checked locations from server"); foreach (long item2 in list2) { Log.Message($"[AP] Location checked: {item2}"); checkedLocations.TryAdd(item2, 0); } } catch (Exception arg) { Log.Error($"[AP] LoadFromServer exception: {arg}"); } } public static void ResyncFromServer() { Log.Message("[AP] Resyncing Archipelago state from server"); LoadFromServer(); } public static int GetCupVictoryCount() { return checkedLocations.Keys.Count((long loc) => loc >= 101 && loc <= 104); } public static int GetRaceVictoryCount() { int num = 0; for (int i = 0; i < 16; i++) { if (HasLocation(1L + (long)i)) { num++; } } return num; } public static int GetTimeTrialVictoryCount() { try { ArchipelagoSession val = GarfieldKartAPMod.APClient?.GetSession(); if (val == null) { return 0; } string seed = val.RoomState.Seed; if (string.IsNullOrWhiteSpace(seed)) { return 0; } string path = Application.persistentDataPath + "/" + seed + "_timetrials.txt"; if (!File.Exists(path)) { return 0; } IEnumerable source = (from l in File.ReadAllLines(path) where !string.IsNullOrWhiteSpace(l) select l.Trim()).Distinct(); return source.Count(); } catch (Exception ex) { Log.Error("Failed to read time-trial file: " + ex.Message); return 0; } } public static List GetAvailableCups() { List list = new List(); for (int i = 0; i < 4; i++) { if (HasCup(i)) { list.Add(i); } } return list; } public static bool HasRace(int raceId) { int cupId = raceId / 4; bool flag = ArchipelagoHelper.IsRacesRandomized(); if (ArchipelagoHelper.IsCupsRandomized() && !flag) { return HasCup(cupId); } long itemId = 101L + (long)raceId; return HasItem(itemId); } public static bool HasCup(int cupId) { bool flag = ArchipelagoHelper.IsCupsRandomized(); if (ArchipelagoHelper.IsRacesRandomized() && !flag) { return HasAllRacesInCup(cupId); } if (flag) { if (ArchipelagoHelper.IsProgressiveCupsEnabled()) { return AmountOfItem(200L) >= cupId; } long itemId = 201L + (long)cupId; return HasItem(itemId); } return true; } public static bool CanAccessCup(int cupId) { if (!HasCup(cupId)) { return false; } return HasAllRacesInCup(cupId); } public static bool HasRaceInCup(int cupId) { int num = cupId * 4; for (int i = 0; i < 4; i++) { if (HasRace(num + i)) { return true; } } return false; } public static bool HasAllRacesInCup(int cupId) { int num = cupId * 4; for (int i = 0; i < 4; i++) { if (!HasRace(num + i)) { return false; } } return true; } public static int GetPuzzlePieceCount(string startScene) { long puzzlePieceLoc = ArchipelagoConstants.GetPuzzlePieceLoc(startScene, 0); if (puzzlePieceLoc == -1) { return 0; } int num = 0; for (int i = 0; i < 3; i++) { if (HasLocation(puzzlePieceLoc + i)) { num++; } } return num; } public static int GetOverallPuzzlePieceCount() { return AmountOfItem(49L); } public static int GetCheckedPuzzlePieceCount() { List list = new List { "E2C1", "E4C1", "E3C1", "E1C1", "E3C2", "E2C2", "E1C2", "E4C2", "E1C3", "E3C3", "E4C3", "E2C3", "E4C4", "E1C4", "E2C4", "E3C4" }; int num = 0; foreach (string item in list) { num += GetPuzzlePieceCount(item); } return num; } public static bool HasBonusAvailable(BonusCategory bonus) { //IL_0016: 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_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Expected I4, but got Unknown if (!ArchipelagoHelper.IsItemRandomizerEnabled()) { return true; } return (bonus - 1) switch { 0 => HasItem(901L), 1 => HasItem(902L), 3 => HasItem(906L), 2 => HasItem(909L), 4 => HasItem(903L), 5 => HasItem(907L), 6 => HasItem(908L), 7 => HasItem(905L), 8 => HasItem(904L), _ => true, }; } public static void LogAllReceivedItems() { int num = receivedItems.Sum((KeyValuePair kv) => kv.Value); Log.Message($"[AP Debug] === All Received Items ({num} total entries) ==="); foreach (KeyValuePair item in receivedItems.OrderBy((KeyValuePair kv) => kv.Key)) { Log.Message($"[AP Debug] Item ID: {item.Key} Count: {item.Value}"); } } public static void LogAllCheckedLocations() { Log.Message($"[AP Debug] === All Checked Locations ({checkedLocations.Count} total) ==="); foreach (long item in checkedLocations.Keys.OrderBy((long x) => x)) { Log.Message($"[AP Debug] Location ID: {item}"); } } } public class ConnectionUI : MonoBehaviour { private bool showUI = true; private bool m_paused = false; private string hostname = "localhost"; private string slotName = "Jeff-GK"; private string port = "38281"; private string password = ""; private string statusMessage = ""; private Rect windowRect = new Rect((float)(Screen.width / 2 - 300), (float)(Screen.height / 2 - 250), 800f, 700f); private ArchipelagoClient apClient; private bool originalCursorVisible; private CursorLockMode originalLockMode; private bool NeedsConnection => !(apClient?.IsConnected ?? false); public void Initialize(ArchipelagoClient client) { //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) apClient = client; apClient.OnConnected += delegate { statusMessage = "Connected successfully!"; }; apClient.OnConnectionFailed += delegate(string error) { statusMessage = "Failed: " + error; }; apClient.OnDisconnected += delegate { statusMessage = "Disconnected"; }; apClient.OnConnected += delegate { FileWriter fileWriter = Object.FindObjectOfType(); if (!((Object)(object)fileWriter == (Object)null)) { int.TryParse(port, out var result); fileWriter.WriteLastConnection(hostname, result, slotName, password); } }; (string, string, string, string) tuple = FileWriter.ReadLastConnection(); if (!string.IsNullOrEmpty(tuple.Item1)) { (hostname, _, _, _) = tuple; } if (!string.IsNullOrEmpty(tuple.Item2)) { port = tuple.Item2; } if (!string.IsNullOrEmpty(tuple.Item3)) { slotName = tuple.Item3; } if (!string.IsNullOrEmpty(tuple.Item4)) { password = tuple.Item4; } originalCursorVisible = Cursor.visible; originalLockMode = Cursor.lockState; Cursor.visible = true; Cursor.lockState = (CursorLockMode)0; } public void ToggleUI() { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) showUI = !showUI; if (showUI) { originalCursorVisible = Cursor.visible; originalLockMode = Cursor.lockState; Cursor.visible = true; Cursor.lockState = (CursorLockMode)0; } else { Cursor.visible = originalCursorVisible; Cursor.lockState = originalLockMode; } } private void Update() { bool needsConnection = NeedsConnection; if (needsConnection && !m_paused) { Time.timeScale = 0f; m_paused = true; showUI = true; Cursor.visible = true; Cursor.lockState = (CursorLockMode)0; } else if (!needsConnection && m_paused) { Time.timeScale = 1f; m_paused = false; } if (!needsConnection && Input.GetKeyDown((KeyCode)282)) { ToggleUI(); } } private void OnGUI() { //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_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Expected O, but got Unknown //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) if (showUI || NeedsConnection) { GUI.skin.label.fontSize = 24; GUI.skin.button.fontSize = 24; GUI.skin.textField.fontSize = 24; Color backgroundColor = GUI.backgroundColor; GUI.backgroundColor = new Color(1f, 0.5f, 0f); windowRect = GUI.Window(0, windowRect, new WindowFunction(DrawWindow), "Archipelago Connection"); GUI.backgroundColor = backgroundColor; } } private void DrawWindow(int windowID) { GUILayout.BeginVertical(Array.Empty()); GUILayout.Label("Press F1 to toggle this menu", Array.Empty()); GUILayout.Space(15f); GUILayout.Label("Hostname:", Array.Empty()); hostname = GUILayout.TextField(hostname, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(40f) }); GUILayout.Space(10f); GUILayout.Label("Port:", Array.Empty()); port = GUILayout.TextField(port, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(40f) }); GUILayout.Space(10f); GUILayout.Label("Slot Name:", Array.Empty()); slotName = GUILayout.TextField(slotName, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(40f) }); GUILayout.Space(10f); GUILayout.Label("Password (optional):", Array.Empty()); password = GUILayout.PasswordField(password, '*', (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(40f) }); GUILayout.Space(15f); ArchipelagoClient archipelagoClient = apClient; if (archipelagoClient != null && archipelagoClient.IsConnected) { if (GUILayout.Button("Disconnect", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(40f) })) { apClient.Disconnect(); } } else if (GUILayout.Button("Connect", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(40f) })) { int result; if (string.IsNullOrEmpty(slotName)) { statusMessage = "Please enter a slot name!"; } else if (int.TryParse(port, out result)) { statusMessage = "Connecting..."; apClient?.Connect(hostname, result, slotName, password); } else { statusMessage = "Invalid port number!"; } } GUILayout.Space(15f); if (!string.IsNullOrEmpty(statusMessage)) { GUILayout.Label("Status: " + statusMessage, Array.Empty()); } GUILayout.EndVertical(); GUI.DragWindow(); } } public class FileWriter : MonoBehaviour { private const string LastConnectionFileName = "last_connection.txt"; public void WriteTimeTrialData(string track) { if (GarfieldKartAPMod.APClient == null || !GarfieldKartAPMod.APClient.IsConnected) { return; } ArchipelagoSession session = GarfieldKartAPMod.APClient.GetSession(); if (session == null) { return; } string seed = session.RoomState.Seed; string text = Application.persistentDataPath + "/" + seed + "_timetrials.txt"; HashSet hashSet = new HashSet(); if (File.Exists(text)) { hashSet = new HashSet(File.ReadAllLines(text)); } if (!hashSet.Contains(track)) { using (StreamWriter streamWriter = new StreamWriter(text, append: true)) { streamWriter.WriteLine(track); } Debug.Log((object)("AP TimeTrial file written to: " + text)); } } public void WriteFillerData(string data) { if (GarfieldKartAPMod.APClient == null || !GarfieldKartAPMod.APClient.IsConnected) { return; } ArchipelagoSession session = GarfieldKartAPMod.APClient.GetSession(); if (session == null) { return; } string seed = session.RoomState.Seed; string text = Application.persistentDataPath + "/" + seed + "_filler.txt"; try { File.WriteAllText(text, data); Debug.Log((object)("AP Filler file written to: " + text)); } catch (Exception ex) { Debug.LogError((object)("Failed to write filler data: " + ex.Message)); } } public string ReadFillerData() { if (GarfieldKartAPMod.APClient == null || !GarfieldKartAPMod.APClient.IsConnected) { return string.Empty; } ArchipelagoSession session = GarfieldKartAPMod.APClient.GetSession(); if (session == null) { return string.Empty; } string seed = session.RoomState.Seed; string path = Application.persistentDataPath + "/" + seed + "_filler.txt"; if (!File.Exists(path)) { return string.Empty; } try { return File.ReadAllText(path); } catch (Exception ex) { Debug.LogError((object)("Failed to read filler data: " + ex.Message)); return string.Empty; } } public void WriteLastConnection(string host, int port, string slotName, string password) { try { string path = Application.persistentDataPath + "/last_connection.txt"; List contents = new List { host ?? "", port.ToString(), slotName ?? "", password ?? "" }; File.WriteAllLines(path, contents); } catch (Exception ex) { Debug.LogError((object)("Failed to write last connection info: " + ex.Message)); } } public static (string host, string port, string slotName, string password) ReadLastConnection() { try { string path = Application.persistentDataPath + "/last_connection.txt"; if (!File.Exists(path)) { return (null, null, null, null); } string[] array = File.ReadAllLines(path); string item = ((array.Length != 0) ? array[0] : null); string item2 = ((array.Length > 1) ? array[1] : null); string item3 = ((array.Length > 2) ? array[2] : null); string item4 = ((array.Length > 3) ? array[3] : null); return (item, item2, item3, item4); } catch (Exception ex) { Debug.LogError((object)("Failed to read last connection info: " + ex.Message)); return (null, null, null, null); } } } [BepInPlugin("Jeffdev.GarfieldKartAPMod", "GarfieldKartAPMod", "0.5.3")] public class GarfieldKartAPMod : BaseUnityPlugin { private const string PluginGuid = "Jeffdev.GarfieldKartAPMod"; private const string PluginAuthor = "Jeffdev"; private const string PluginName = "GarfieldKartAPMod"; private const string PluginVersion = "0.5.3"; public static ConfigEntry notificationTime; public static ConfigEntry lapCountOverride; private Harmony harmony; public static Dictionary sessionSlotData; private static GameObject uiObject; private static bool uiCreated; private static NotificationDisplay notificationDisplay; private FileWriter fileWriter; public static ArchipelagoClient APClient { get; private set; } public void Awake() { notificationTime = ((BaseUnityPlugin)this).Config.Bind("Archipelago", "Server Message On-Screen Time", 3, "How long to show archipelago server messages and checks on the screen, in seconds."); lapCountOverride = ((BaseUnityPlugin)this).Config.Bind("Archipelago", "Lap Count Override", 0, "Override the lap count for races. Set to 0 to use the lap count from Archipelago slot data."); InitializeLogging(); InitializeAssemblyResolution(); InitializeComponents(); ApplyPatches(); Log.Info("GarfieldKartAPMod loaded successfully!"); } private void InitializeLogging() { Log.Init(((BaseUnityPlugin)this).Logger); } private void InitializeAssemblyResolution() { ForceLoadNewtonsoftJson(); AppDomain.CurrentDomain.AssemblyResolve += OnAssemblyResolve; CheckSystemNumericsAvailability(); } private void ForceLoadNewtonsoftJson() { try { Type typeFromHandle = typeof(JsonConvert); Log.Message($"Loaded Newtonsoft.Json version: {typeFromHandle.Assembly.GetName().Version}"); } catch (Exception ex) { Log.Error("Failed to preload Newtonsoft.Json: " + ex.Message); } } private void CheckSystemNumericsAvailability() { try { Type type = Type.GetType("System.Numerics.BigInteger, System.Numerics"); ((BaseUnityPlugin)this).Logger.LogInfo((object)$"BigInteger available: {type != null}"); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("BigInteger check failed: " + ex.Message)); } } private void InitializeComponents() { UITextureSwapper.Initialize(); fileWriter = ((Component)this).gameObject.AddComponent(); APClient = new ArchipelagoClient(); APClient.OnConnected += OnArchipelagoConnected; APClient.OnDisconnected += OnArchipelagoDisconnected; } private void ApplyPatches() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown harmony = new Harmony("Jeffdev.GarfieldKartAPMod"); harmony.PatchAll(Assembly.GetExecutingAssembly()); } public void Update() { if (APClient != null && APClient.HasPendingNotifications()) { string message = APClient.DequeuePendingNotification(); notificationDisplay.ShowNotification(message); } } private void OnArchipelagoConnected() { Log.Message("Connected to Archipelago - loading items"); uiObject.GetComponent().ToggleUI(); PopupManager.OpenPopup("Connected to Archipelago!", (POPUP_TYPE)2, (POPUP_PRIORITY)0, (Relay)null, (Action)null, 0f, (string)null); } private void OnArchipelagoDisconnected() { Log.Message("Disconnected from Archipelago"); ArchipelagoItemTracker.Clear(); } private Assembly OnAssemblyResolve(object sender, ResolveEventArgs args) { AssemblyName assemblyName = new AssemblyName(args.Name); if (assemblyName.Name != "Newtonsoft.Json") { return null; } Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { if (!(assembly.GetName().Name != "Newtonsoft.Json")) { Log.Message($"Resolved Newtonsoft.Json to version {assembly.GetName().Version}"); return assembly; } } return null; } public static void CreateUI() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown if (!uiCreated) { Log.Message("Creating Archipelago UI..."); uiObject = new GameObject("ArchipelagoUI"); Object.DontDestroyOnLoad((Object)(object)uiObject); ConnectionUI connectionUI = uiObject.AddComponent(); connectionUI.Initialize(APClient); notificationDisplay = uiObject.AddComponent(); notificationDisplay.Initialize(); uiCreated = true; } } public void OnDestroy() { APClient?.Disconnect(); if ((Object)(object)uiObject != (Object)null) { Object.Destroy((Object)(object)uiObject); } Harmony obj = harmony; if (obj != null) { obj.UnpatchSelf(); } } } internal static class Log { private static ManualLogSource _logSource; internal static void Init(ManualLogSource logSource) { _logSource = logSource; } internal static void Debug(object data) { _logSource.LogDebug(data); } internal static void Error(object data) { _logSource.LogError(data); } internal static void Fatal(object data) { _logSource.LogFatal(data); } internal static void Info(object data) { _logSource.LogInfo(data); } internal static void Message(object data) { _logSource.LogMessage(data); } internal static void Warning(object data) { _logSource.LogWarning(data); } } public class NotificationDisplay : MonoBehaviour { [CompilerGenerated] private sealed class d__5 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public NotificationDisplay <>4__this; private string 5__1; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__5(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { 5__1 = null; <>1__state = -2; } private bool MoveNext() { //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>4__this.isDisplaying = true; break; case 1: <>1__state = -1; 5__1 = null; break; } if (<>4__this.notificationQueue.Count > 0) { 5__1 = <>4__this.notificationQueue.Dequeue(); ((TMP_Text)<>4__this.notificationText).text = 5__1; <>2__current = (object)new WaitForSeconds((float)GarfieldKartAPMod.notificationTime.Value); <>1__state = 1; return true; } ((TMP_Text)<>4__this.notificationText).text = ""; <>4__this.isDisplaying = false; return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private TextMeshProUGUI notificationText; private readonly Queue notificationQueue = new Queue(); private bool isDisplaying; public void Initialize() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) Canvas val = ((Component)this).gameObject.AddComponent(); val.renderMode = (RenderMode)0; val.sortingOrder = 1000; GameObject val2 = new GameObject("NotificationText"); val2.transform.SetParent(((Component)this).transform); notificationText = val2.AddComponent(); ((TMP_Text)notificationText).fontSize = 48f; ((TMP_Text)notificationText).alignment = (TextAlignmentOptions)258; ((TMP_Text)notificationText).autoSizeTextContainer = true; ((TMP_Text)notificationText).enableWordWrapping = true; ((Graphic)notificationText).color = Color.white; RectTransform component = val2.GetComponent(); component.anchorMin = new Vector2(0f, 1f); component.anchorMax = new Vector2(1f, 1f); component.pivot = new Vector2(0.5f, 1f); component.anchoredPosition = new Vector2(0f, -20f); component.sizeDelta = new Vector2(-40f, 100f); ((TMP_Text)notificationText).text = ""; } public void ShowNotification(string message) { notificationQueue.Enqueue(message); if (!isDisplaying) { ((MonoBehaviour)this).StartCoroutine(DisplayNextNotification()); } } [IteratorStateMachine(typeof(d__5))] private IEnumerator DisplayNextNotification() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__5(0) { <>4__this = this }; } } [Serializable] public class SlotDataException : ApplicationException { public SlotDataException() { } public SlotDataException(string message) : base(message) { } public SlotDataException(string message, Exception innerException) : base(message, innerException) { } } public static class UITextureSwapper { public static string spriteFolder = "Resources/Sprites"; private static Sprite baseArchipelagoSprite; public static Sprite puzzlePieceFilledSprite; public static Sprite puzzlePieceEmptySprite; private static bool initialized; private static bool hasSwappedThisMenu; public static void Initialize() { if (!initialized) { Log.Message("Initializing UI texture swapper..."); bool flag = true; if (TryLoadSprite("archipelago_logo.png", out baseArchipelagoSprite) && TryLoadSprite("garfkart_ap_puzzle_filled.png", out puzzlePieceFilledSprite) && TryLoadSprite("garfkart_ap_puzzle_empty.png", out puzzlePieceEmptySprite)) { initialized = true; } } } private static bool TryLoadSprite(string path, out Sprite targetSprite) { //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Expected O, but got Unknown //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Unknown result type (might be due to invalid IL or missing references) string @namespace = typeof(UITextureSwapper).Namespace; targetSprite = null; try { Assembly executingAssembly = Assembly.GetExecutingAssembly(); string[] manifestResourceNames = executingAssembly.GetManifestResourceNames(); Log.Message($"Found {manifestResourceNames.Length} embedded resources:"); string[] array = manifestResourceNames; foreach (string text in array) { Log.Message(" - " + text); } string text2 = null; string[] array2 = manifestResourceNames; foreach (string text3 in array2) { if (!(text3 != path) || text3.EndsWith("." + path)) { if (text2 != null) { throw new ApplicationException("Duplicate resource name found, unable to load the correct texture: " + text3); } text2 = text3; } } if (text2 == null) { Log.Warning("Couldn't find " + path + " in embedded resources, loading default sprite instead."); targetSprite = CreateDefaultSprite(); return false; } Log.Message("Loading embedded resource: " + text2); using Stream stream = executingAssembly.GetManifestResourceStream(text2); if (stream == null) { Log.Error("Failed to load " + path + " for unknown reasons :)"); targetSprite = CreateDefaultSprite(); return false; } byte[] array3 = new byte[stream.Length]; stream.Read(array3, 0, (int)stream.Length); Texture2D val = new Texture2D(2, 2); ImageConversion.LoadImage(val, array3); val.Apply(); targetSprite = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f); Log.Message($"Successfully loaded {path} ({((Texture)val).width}x{((Texture)val).height})"); return true; } catch (Exception ex) { Log.Error("Failed to load " + path + ": " + ex.Message + "\n" + ex.StackTrace); targetSprite = CreateDefaultSprite(); return false; } } private static Sprite CreateDefaultSprite() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(64, 64); Color[] array = (Color[])(object)new Color[4096]; for (int i = 0; i < array.Length; i++) { array[i] = Color.red; } val.SetPixels(array); val.Apply(); Log.Message("Created default red placeholder sprite"); return Sprite.Create(val, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f), 100f); } public static void ResetSwapFlag() { hasSwappedThisMenu = false; } public static void SwapPuzzlePieceIcons(GameObject menu) { if (hasSwappedThisMenu) { return; } if ((Object)(object)baseArchipelagoSprite == (Object)null) { Log.Error("Cannot swap - Archipelago sprite not loaded"); } else { if (!GarfieldKartAPMod.APClient.IsConnected) { return; } try { int num = 0; Image[] componentsInChildren = menu.GetComponentsInChildren(true); Image[] array = componentsInChildren; foreach (Image val in array) { if (!((Object)(object)val.sprite == (Object)null)) { string text = ((Object)val.sprite).name.ToLower(); string text2 = ((Object)((Component)val).gameObject).name.ToLower(); if (text.Contains("icnpuzzle") || text2.Contains("icnpuzzle") || text.Contains("icnpuzzlefull") || text2.Contains("icnpuzzlefull")) { val.sprite = baseArchipelagoSprite; num++; Log.Message("Swapped UI.Image on: " + ((Object)((Component)val).gameObject).name); } } } Log.Message($"Swapped {num} puzzle piece icons"); hasSwappedThisMenu = true; } catch (Exception ex) { Log.Error("Failed to swap puzzle icons: " + ex.Message); } } } } } namespace GarfieldKartAPMod.Helpers { public static class ArchipelagoGoalManager { public static long GetGoalId() { string slotDataValue = GarfieldKartAPMod.APClient.GetSlotDataValue("goal"); long.TryParse(slotDataValue, out var result); return result; } public static void CheckAndCompleteGoal() { if (!ArchipelagoHelper.IsConnectedAndEnabled) { return; } long goalId = GetGoalId(); long num = goalId; long num2 = num; if ((ulong)num2 <= 3uL) { switch (num2) { case 0L: CheckGrandPrixGoal(); return; case 3L: CheckPuzzlePieceGoal(); return; case 1L: CheckRacesGoal(); return; case 2L: CheckTimeTrialsGoal(); return; } } Log.Debug($"Unknown goal ID: {goalId}"); } private static void CheckGrandPrixGoal() { int cupVictoryCount = ArchipelagoItemTracker.GetCupVictoryCount(); if (cupVictoryCount == 4) { CompleteGoal(); } } private static void CheckPuzzlePieceGoal() { long num = ArchipelagoHelper.GetPuzzlePieceCount(); int overallPuzzlePieceCount = ArchipelagoItemTracker.GetOverallPuzzlePieceCount(); if (overallPuzzlePieceCount >= num) { CompleteGoal(); } } private static void CheckRacesGoal() { int raceVictoryCount = ArchipelagoItemTracker.GetRaceVictoryCount(); if (raceVictoryCount == 16) { CompleteGoal(); } } private static void CheckTimeTrialsGoal() { int timeTrialVictoryCount = ArchipelagoItemTracker.GetTimeTrialVictoryCount(); if (timeTrialVictoryCount == 16) { CompleteGoal(); } } private static void CompleteGoal() { GarfieldKartAPMod.APClient.GetSession().SetGoalAchieved(); } } public static class ArchipelagoHelper { public static bool IsConnectedAndEnabled => GarfieldKartAPMod.APClient?.IsConnected ?? false; private static bool IsTrue(string str) { if (str == "true" || str == "1") { return true; } return false; } public static bool IsPuzzleRandomizationEnabled() { string slotDataValue = GarfieldKartAPMod.APClient.GetSlotDataValue("randomize_puzzle_pieces"); return IsTrue(slotDataValue); } public static bool IsProgressiveCupsEnabled() { string slotDataValue = GarfieldKartAPMod.APClient.GetSlotDataValue("progressive_cups"); return IsTrue(slotDataValue); } public static bool IsCharRandomizerEnabled() { string slotDataValue = GarfieldKartAPMod.APClient.GetSlotDataValue("randomize_characters"); return IsTrue(slotDataValue); } public static bool IsKartRandomizerEnabled() { string slotDataValue = GarfieldKartAPMod.APClient.GetSlotDataValue("randomize_karts"); return IsTrue(slotDataValue); } public static bool IsHatRandomizerEnabled() { string slotDataValue = GarfieldKartAPMod.APClient.GetSlotDataValue("randomize_hats"); int num = int.Parse(slotDataValue); return (long)num != 0; } public static bool IsProgressiveHatEnabled() { string slotDataValue = GarfieldKartAPMod.APClient.GetSlotDataValue("randomize_hats"); int num = int.Parse(slotDataValue); return (long)num == 1; } public static bool IsSpoilerRandomizerEnabled() { string slotDataValue = GarfieldKartAPMod.APClient.GetSlotDataValue("randomize_spoilers"); int num = int.Parse(slotDataValue); return (long)num != 0; } public static bool IsProgressiveSpoilerEnabled() { string slotDataValue = GarfieldKartAPMod.APClient.GetSlotDataValue("randomize_spoilers"); int num = int.Parse(slotDataValue); return (long)num == 1; } public static bool IsItemRandomizerEnabled() { string slotDataValue = GarfieldKartAPMod.APClient.GetSlotDataValue("randomize_items"); return IsTrue(slotDataValue); } public static bool IsRacesRandomized() { string slotDataValue = GarfieldKartAPMod.APClient.GetSlotDataValue("randomize_races"); int.TryParse(slotDataValue, out var result); return (long)result == 1 || (long)result == 2; } public static bool IsCupsRandomized() { string slotDataValue = GarfieldKartAPMod.APClient.GetSlotDataValue("randomize_races"); int.TryParse(slotDataValue, out var result); return result == 0L || (long)result == 2; } public static bool IsRacesAndCupsRandomized() { string slotDataValue = GarfieldKartAPMod.APClient.GetSlotDataValue("randomize_races"); int.TryParse(slotDataValue, out var result); return (long)result == 2; } public static bool IsSpringsOnly() { string slotDataValue = GarfieldKartAPMod.APClient.GetSlotDataValue("springs_only"); return IsTrue(slotDataValue); } public static bool IsCPUItemsDisabled() { string slotDataValue = GarfieldKartAPMod.APClient.GetSlotDataValue("disable_cpu_items"); return IsTrue(slotDataValue); } public static string GetTimeTrialGoalGrade() { return GarfieldKartAPMod.APClient.GetSlotDataValue("time_trial_goal_grade"); } public static string GetCCRequirement() { return GarfieldKartAPMod.APClient.GetSlotDataValue("cc_requirement"); } public static int GetPuzzlePieceCount() { string slotDataValue = GarfieldKartAPMod.APClient.GetSlotDataValue("puzzle_piece_count"); if (int.TryParse(slotDataValue, out var result)) { return result; } throw new SlotDataException("Invalid puzzle piece goal value passed from slot data: " + slotDataValue); } public static bool IsLapSanityEnabled() { string slotDataValue = GarfieldKartAPMod.APClient.GetSlotDataValue("lap_sanity"); return IsTrue(slotDataValue); } internal static int GetLapCount() { if (GarfieldKartAPMod.lapCountOverride.Value > 0) { return GarfieldKartAPMod.lapCountOverride.Value; } string slotDataValue = GarfieldKartAPMod.APClient.GetSlotDataValue("lap_count"); if (slotDataValue == null) { return 3; } if (int.TryParse(slotDataValue, out var result)) { return result; } throw new SlotDataException("Invalid lap count value passed from slot data: " + slotDataValue); } } internal class Utils { private static readonly Random rng = new Random(); public static void Shuffle(List list) { int num = list.Count; while (num > 1) { num--; int num2 = rng.Next(num + 1); int index = num; int index2 = num2; T value = list[num2]; T value2 = list[num]; list[index] = value; list[index2] = value2; } } } } namespace GarfieldKartAPMod.Patches { public static class ButtonHelper { public static void DisableButtonsByIndices(object buttonsArray, params int[] indices) { try { Type type = buttonsArray.GetType(); PropertyInfo property = type.GetProperty("Length"); PropertyInfo property2 = type.GetProperty("Item", new Type[1] { typeof(int) }); if (property == null) { return; } int num = (int)property.GetValue(buttonsArray); foreach (int num2 in indices) { if (num2 < num && !(property2 == null)) { object? value = property2.GetValue(buttonsArray, new object[1] { num2 }); BetterButton val = (BetterButton)((value is BetterButton) ? value : null); if (!((Object)(object)val == (Object)null)) { ((Selectable)val).interactable = false; Log.Info($"Disabled button at index {num2}"); } } } } catch (Exception arg) { Log.Error($"Failed to disable buttons: {arg}"); } } public static void DisableLockedRaceButtons(object instance, object m_buttons, int currentCupId) { try { Type type = m_buttons.GetType(); PropertyInfo property = type.GetProperty("Length"); if (property == null) { return; } int num = (int)property.GetValue(m_buttons); PropertyInfo property2 = type.GetProperty("Item", new Type[1] { typeof(int) }); for (int i = 0; i < num; i++) { if (property2 != null) { object? value = property2.GetValue(m_buttons, new object[1] { i }); BetterButton val = (BetterButton)((value is BetterButton) ? value : null); if ((Object)(object)val == (Object)null) { continue; } if (i == 4) { ((Component)val).gameObject.SetActive(false); continue; } int raceId = 4 * currentCupId + i; if (!ArchipelagoItemTracker.HasRace(raceId)) { ((Selectable)val).interactable = false; continue; } ((Selectable)val).interactable = true; GkEventSystem.Current.SelectButton((Selectable)(object)val, 0); } MenuHDTrackSelection val2 = (MenuHDTrackSelection)((instance is MenuHDTrackSelection) ? instance : null); if (val2 != null) { val2.UpdateRacesButtons(currentCupId); } } } catch (Exception arg) { Log.Error($"Failed to disable race buttons: {arg}"); } } } [HarmonyPatch(typeof(MenuHDMain), "Enter")] public class MenuHDMain_Enter_Patch { private static void Postfix() { Log.Message("Main menu started, creating UI..."); GarfieldKartAPMod.CreateUI(); } } [HarmonyPatch(typeof(MenuHDGameMode), "Enter")] public class MenuHDGameMode_Enter_Patch { private static void Postfix(MenuHDGameMode __instance, object ___m_buttons) { if (ArchipelagoHelper.IsConnectedAndEnabled) { List availableCups = ArchipelagoItemTracker.GetAvailableCups(); if (availableCups.Count == 0) { ButtonHelper.DisableButtonsByIndices(___m_buttons, 1); } } } } [HarmonyPatch(typeof(MenuHDGameMode), "OnSubmitChampionShip")] public class MenuHDModeSelect_OnSubmitChampionShip_Patch { private static bool Prefix(MenuHDGameMode __instance) { if (!ArchipelagoHelper.IsConnectedAndEnabled) { return true; } List availableCups = ArchipelagoItemTracker.GetAvailableCups(); if (availableCups.Count != 0) { return true; } PopupManager.OpenPopup("You haven't unlocked any cups!", (POPUP_TYPE)3, (POPUP_PRIORITY)0, (Relay)null, (Action)null, 0f, (string)null); return false; } } [HarmonyPatch(typeof(MenuHDGameType), "Enter")] public class MenuHDGameType_Enter_Patch { private static void Prefix() { ArchipelagoItemTracker.ResyncFromServer(); } private static void Postfix(MenuHDGameType __instance, object ___m_buttons) { if (ArchipelagoHelper.IsConnectedAndEnabled) { ButtonHelper.DisableButtonsByIndices(___m_buttons, 1, 2); } } } [HarmonyPatch(typeof(MenuHDTrackSelection), "Enter")] public class MenuHDTrackSelection_Enter_Patch { private static void Postfix(MenuHDTrackSelection __instance, EnumArray ___m_tabs, object ___m_buttons, ref int ___m_currentChampionshipIndex) { Log.Message("Track Selection Menu opened"); ArchipelagoItemTracker.ResyncFromServer(); if (ArchipelagoHelper.IsConnectedAndEnabled) { if (ArchipelagoHelper.IsPuzzleRandomizationEnabled()) { UITextureSwapper.SwapPuzzlePieceIcons(((Component)__instance).gameObject); } int num = SetupCupTabs(___m_tabs, ___m_currentChampionshipIndex); ButtonHelper.DisableLockedRaceButtons(__instance, ___m_buttons, (num != -1) ? num : ___m_currentChampionshipIndex); } } private static int SetupCupTabs(EnumArray tabs, int currentChampionshipId) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Invalid comparison between Unknown and I4 //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Invalid comparison between Unknown and I4 //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Invalid comparison between Unknown and I4 int num = -1; E_GameModeType gameModeType = Singleton.Instance.GameModeType; for (int i = 0; i < tabs.Length; i++) { bool flag = false; bool flag2 = ArchipelagoItemTracker.HasRaceInCup(i); if ((int)gameModeType == 3 && ArchipelagoItemTracker.CanAccessCup(i)) { flag = true; } else if (((int)gameModeType == 2 || (int)gameModeType == 4) && flag2) { flag = true; } if (!flag) { ((Component)tabs[i]).gameObject.SetActive(false); continue; } if (num == -1) { GkEventSystem.Current.SelectTab((Toggle)(object)tabs[i], 0); num = i; } ((Component)tabs[i]).gameObject.SetActive(true); } return num; } } [HarmonyPatch(typeof(MenuHDTrackSelection), "OnSelectChampionship")] public class MenuHDTrackSelection_OnSelectChampionship_Patch { private static void Postfix(MenuHDTrackSelection __instance, object ___m_buttons, int iId) { ButtonHelper.DisableLockedRaceButtons(__instance, ___m_buttons, iId); } } [HarmonyPatch(typeof(MenuHDTrackSelection), "UpdateRacesButtons")] public class MenuHDTrackSelection_UpdateRacesButtons_Patch { private static bool Prefix(MenuHDTrackSelection __instance, int cup, List ___m_itemsButtons, int ___m_maxPuzzleNumber, int ___m_currentSelectedButton, bool ___m_hasFinishedEntering, TextMeshProUGUI ___m_textCupCircuit) { if (!ArchipelagoHelper.IsConnectedAndEnabled || !ArchipelagoHelper.IsPuzzleRandomizationEnabled()) { return true; } for (int i = 0; i < ___m_itemsButtons.Count - 1; i++) { ___m_itemsButtons[i].ChangeBackground(PlayerGameEntities.ChampionShipDataList[cup].Sprites[i]); string text = Singleton.Instance.ChampionShipData.Tracks[i]; int puzzlePieceCount = ArchipelagoItemTracker.GetPuzzlePieceCount(text); ___m_itemsButtons[i].UpdatePuzzleText(puzzlePieceCount); ___m_itemsButtons[i].UpdateTimeTrialText(text); } if (___m_currentSelectedButton != 4 && ___m_hasFinishedEntering) { MethodInfo methodInfo = AccessTools.Method(typeof(MenuHDTrackSelection), "UpdateTimeTrialValues", (Type[])null, (Type[])null); methodInfo.Invoke(__instance, new object[1] { ___m_currentSelectedButton }); } if (___m_currentSelectedButton < Singleton.Instance.ChampionShipData.TracksName.Length) { ((TMP_Text)___m_textCupCircuit).text = Singleton.Instance.ChampionShipData.ChampionShipName + " - " + Singleton.Instance.ChampionShipData.TracksName[___m_currentSelectedButton]; } return false; } } [HarmonyPatch(typeof(MenuHDTrackPresentation), "InitPuzzlePieces")] public class MenuHDTrackPresentation_InitPuzzlePieces_Patch { private static bool Prefix(Image[] puzzlePiecesImages, string trackName, bool isTimeTrial) { if (!ArchipelagoHelper.IsConnectedAndEnabled) { return true; } if (!ArchipelagoHelper.IsPuzzleRandomizationEnabled()) { return true; } if (GkNetMgr.Instance.IsConnected) { ((Component)((Component)puzzlePiecesImages[0]).transform.parent).gameObject.SetActive(false); return false; } ((Component)((Component)puzzlePiecesImages[0]).transform.parent).gameObject.SetActive(true); for (int i = 0; i < puzzlePiecesImages.Length; i++) { ((Component)puzzlePiecesImages[i]).gameObject.SetActive(!isTimeTrial); long puzzlePieceLoc = ArchipelagoConstants.GetPuzzlePieceLoc(trackName, i); bool flag = ArchipelagoItemTracker.HasLocation(puzzlePieceLoc); puzzlePiecesImages[i].sprite = (flag ? UITextureSwapper.puzzlePieceFilledSprite : UITextureSwapper.puzzlePieceEmptySprite); } return false; } } [HarmonyPatch(typeof(GkEventSystem), "OnSecondaryMove")] public class GkEventSystem_OnSecondaryMove_Patch { private static Exception Finalizer(Exception __exception) { if (!(__exception is InvalidCastException)) { return __exception; } Log.Debug("Suppressed InvalidCastException in OnSecondaryMove (navigating to disabled tab)"); return null; } } [HarmonyPatch(typeof(RcRace), "StartRace")] public class RcRace_StartRace_Patch { private static void Prefix(RcRace __instance) { if (ArchipelagoHelper.IsConnectedAndEnabled) { int lapCount = ArchipelagoHelper.GetLapCount(); __instance.SetRaceNbLap(lapCount); } } } [HarmonyPatch(typeof(RcVehicleRaceStats), "CrossStartLine")] public class RcVehicleRaceStats_CrossStartLine_Patch { private static void Prefix(int ___m_iNbLapCompleted, ref int __state) { __state = ___m_iNbLapCompleted; } private static void Postfix(RcVehicleRaceStats __instance, int ___m_iNbLapCompleted, RcVehicle ___m_pVehicle, int __state) { //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Invalid comparison between Unknown and I4 Log.Debug($"{__instance.GetRank()} RANK"); if (ArchipelagoHelper.IsConnectedAndEnabled && ArchipelagoHelper.IsLapSanityEnabled() && ___m_iNbLapCompleted >= __state + 1 && !___m_pVehicle.IsAutoPilot() && (int)___m_pVehicle.m_eControlType != 1 && __instance.GetRank() == 0) { string startScene = Singleton.Instance.StartScene; int num = ___m_iNbLapCompleted - 2; long lapSanityLoc = ArchipelagoConstants.GetLapSanityLoc(startScene, num); if (lapSanityLoc != -1) { GarfieldKartAPMod.APClient.SendLocation(lapSanityLoc); Log.Message($"Sent lap sanity check for {startScene}, lap {num + 1}"); } } } } public static class DrivingCaracStatsRando { private static readonly string[] CharacterNames = new string[8] { "Garfield", "Jon", "Liz", "Odie", "Arlene", "Nermal", "Squeak", "Harry" }; private static readonly string[] KartNames = new string[8] { "Formula Zzzz", "Abstract-Kart", "Medi-Kart", "Woof-Mobile", "Kissy-Kart", "Cutie-Pie Cat", "Rat-Racer", "Muck-Madness" }; private const float StatMin = -25f; private const float StatMax = 25f; public static void ApplyAll() { //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) Log.Info($"[StatsRando] ApplyAll called. Connected={ArchipelagoHelper.IsConnectedAndEnabled}"); if (!ArchipelagoHelper.IsConnectedAndEnabled || GarfieldKartAPMod.sessionSlotData == null || !GarfieldKartAPMod.sessionSlotData.TryGetValue("randomized_stats", out var value)) { return; } JObject val = (JObject)(((value is JObject) ? value : null) ?? ((value is Dictionary dictionary) ? JObject.FromObject((object)dictionary) : null)); if (val == null) { return; } JToken obj = val["karts"]; JObject val2 = (JObject)(object)((obj is JObject) ? obj : null); JToken obj2 = val["characters"]; JObject val3 = (JObject)(object)((obj2 is JObject) ? obj2 : null); foreach (CharacterCarac character in PlayerGameEntities.CharacterList) { string name = GetName(((DrivingCarac)character).Owner, CharacterNames); JToken obj3 = ((val3 != null) ? val3[name] : null); JObject val4 = (JObject)(object)((obj3 is JObject) ? obj3 : null); if (val4 != null) { ApplyStats((DrivingCarac)(object)character, val4); } } foreach (KartCarac kart in PlayerGameEntities.KartList) { string name2 = GetName(((DrivingCarac)kart).Owner, KartNames); JToken obj4 = ((val2 != null) ? val2[name2] : null); JObject val5 = (JObject)(object)((obj4 is JObject) ? obj4 : null); if (val5 != null) { ApplyStats((DrivingCarac)(object)kart, val5); } } } private static string GetName(ECharacter owner, string[] names) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Expected I4, but got Unknown int num = (int)owner; return (num >= 0 && num < names.Length) ? names[num] : ((object)(ECharacter)(ref owner)).ToString(); } private static void ApplyStats(DrivingCarac instance, JObject stats) { if (stats["Speed"] != null) { instance.Speed = Mathf.Clamp(Extensions.Value((IEnumerable)stats["Speed"]), -25f, 25f); } if (stats["Acceleration"] != null) { instance.Acceleration = Mathf.Clamp(Extensions.Value((IEnumerable)stats["Acceleration"]), -25f, 25f); } if (stats["Maniability"] != null) { instance.Maniability = Mathf.Clamp(Extensions.Value((IEnumerable)stats["Maniability"]), -25f, 25f); } Log.Info($"[StatsRando] {((Object)instance).name}: spd={instance.Speed:F2} acc={instance.Acceleration:F2} man={instance.Maniability:F2}"); } } [HarmonyPatch(typeof(KartBonusMgr), "SetItem")] public class KartBonusMgr_SetItem_Patch { private static bool Prefix(KartBonusMgr __instance, Kart ___m_kart, ref BonusCategory bonus, ref int iQuantity, int byPassSlot = -1, bool isFromCheat = false) { if (!ArchipelagoHelper.IsConnectedAndEnabled) { return true; } if (!___m_kart.Driver.IsHuman) { if (GarfieldKartAPMod.APClient.GetSlotDataValue("item_mania") == "1") { iQuantity = 3; } return !ArchipelagoHelper.IsCPUItemsDisabled(); } if (ArchipelagoHelper.IsSpringsOnly()) { bonus = (BonusCategory)3; } return ArchipelagoItemTracker.HasBonusAvailable(bonus); } private static void Postfix(KartBonusMgr __instance, Kart ___m_kart, BonusCategory bonus) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Expected I4, but got Unknown if (ArchipelagoHelper.IsConnectedAndEnabled && ___m_kart.Driver.IsHuman && ArchipelagoItemTracker.HasBonusAvailable(bonus)) { switch (bonus - 1) { case 0: GarfieldKartAPMod.APClient.SendLocation(1101L); break; case 1: GarfieldKartAPMod.APClient.SendLocation(1102L); break; case 3: GarfieldKartAPMod.APClient.SendLocation(1106L); break; case 2: GarfieldKartAPMod.APClient.SendLocation(1109L); break; case 4: GarfieldKartAPMod.APClient.SendLocation(1103L); break; case 8: GarfieldKartAPMod.APClient.SendLocation(1104L); break; case 6: GarfieldKartAPMod.APClient.SendLocation(1108L); break; case 7: GarfieldKartAPMod.APClient.SendLocation(1105L); break; case 5: GarfieldKartAPMod.APClient.SendLocation(1107L); break; } } } } [HarmonyPatch(typeof(GkRacingAI), "ActivateBonus")] public class GkRacingAI_ActivateBonus_Patch { [CompilerGenerated] private sealed class d__1 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public GkRacingAI ai; public Kart pKart; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__1(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Invalid comparison between Unknown and I4 switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForSeconds(2f); <>1__state = 1; return true; case 1: <>1__state = -1; if ((int)pKart.GetBonusMgr().GetItem(0) > 0) { ai.ActivateBonus(pKart, Random.value < 0.5f); } return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private static void Postfix(GkRacingAI __instance, Kart pKart) { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Invalid comparison between Unknown and I4 if (ArchipelagoHelper.IsConnectedAndEnabled && !(GarfieldKartAPMod.APClient.GetSlotDataValue("item_mania") != "1") && pKart.Driver.IsAi && (int)pKart.GetBonusMgr().GetItem(0) > 0) { ((MonoBehaviour)pKart).StartCoroutine(FireNextItem(__instance, pKart)); } } [IteratorStateMachine(typeof(d__1))] private static IEnumerator FireNextItem(GkRacingAI ai, Kart pKart) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__1(0) { ai = ai, pKart = pKart }; } } [HarmonyPatch(typeof(RacePuzzlePiece), "DoTrigger")] public class RacePuzzlePiece_DoTrigger_Patch { private static void Postfix(RacePuzzlePiece __instance, RcVehicle pVehicle) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Invalid comparison between Unknown and I4 if (ArchipelagoHelper.IsConnectedAndEnabled && Object.op_Implicit((Object)(object)pVehicle) && (int)pVehicle.GetControlType() <= 0) { long puzzlePieceLoc = ArchipelagoConstants.GetPuzzlePieceLoc(Singleton.Instance.StartScene, __instance.Index); GarfieldKartAPMod.APClient.SendLocation(puzzlePieceLoc); Log.Message($"Sending Puzzle Piece {Singleton.Instance.StartScene}_{__instance.Index}"); } } } [HarmonyPatch(typeof(RacePuzzlePiece), "Awake")] public class RacePuzzlePiece_Awake_Patch { private static void Postfix(RacePuzzlePiece __instance) { if (!ArchipelagoHelper.IsConnectedAndEnabled || !ArchipelagoHelper.IsPuzzleRandomizationEnabled()) { return; } ((Component)__instance).GetComponent().materials[0] = null; long puzzlePieceLoc = ArchipelagoConstants.GetPuzzlePieceLoc(Singleton.Instance.StartScene, __instance.Index); if (ArchipelagoItemTracker.HasLocation(puzzlePieceLoc)) { Material[] materials = ((Component)__instance).GetComponent().materials; if (materials.Length == 1) { materials[0] = __instance.TransparentMaterial; } ((Component)__instance).GetComponent().materials = materials; } } } [HarmonyPatch(typeof(HUDPositionHD), "TakePuzzlePiece")] public class HUDPositionHD_TakePuzzlePiece_Patch { private static bool Prefix(HUDPositionHD __instance, int iIndex, List ___m_puzzlesAnimation, List ___m_puzzleImages, int ___m_iLogPuzzle) { if ((iIndex < 0 || iIndex >= 3) ? true : false) { return false; } bool flag = true; for (int i = 0; i < 2; i++) { if (i != iIndex) { long puzzlePieceLoc = ArchipelagoConstants.GetPuzzlePieceLoc(Singleton.Instance.StartScene, i); if (!ArchipelagoItemTracker.HasLocation(puzzlePieceLoc)) { flag = false; break; } } } if (flag) { foreach (Animation item in ___m_puzzlesAnimation) { item.Play("PuzzlePiece_Turn"); } } else if ((Object)(object)___m_puzzlesAnimation[iIndex] != (Object)null) { ___m_puzzlesAnimation[iIndex].Play("PuzzlePiece_Turn"); } if ((Object)(object)___m_puzzleImages[iIndex] == (Object)null) { return false; } ___m_puzzleImages[iIndex].sprite = UITextureSwapper.puzzlePieceFilledSprite; if (LogManager.Instance != null) { ___m_iLogPuzzle++; } return false; } } [HarmonyPatch(typeof(GameSaveManager), "IsPuzzlePieceUnlocked")] public class GameSaveManager_IsPuzzlePieceUnlocked_Patch { private static bool Prefix(GameSaveManager __instance, string piece, Dictionary ___m_puzzlePieces, ref bool __result) { if (!ArchipelagoHelper.IsConnectedAndEnabled || !ArchipelagoHelper.IsPuzzleRandomizationEnabled()) { return true; } string[] array = piece.Split(new char[1] { '_' }); int.TryParse(array[1], out var result); __result = ArchipelagoItemTracker.HasLocation(ArchipelagoConstants.GetPuzzlePieceLoc(array[0], result)); return false; } } [HarmonyPatch(typeof(HD_TrackSelection_Item), "UpdatePuzzleText")] public class HD_TrackSelection_Item_UpdatePuzzleText_Patch { private static bool Prefix(HD_TrackSelection_Item __instance, int value, TextMeshProUGUI ___m_puzzleText, GameObject ___m_boardPuzzle, GameObject ___m_boardPuzzleFull, int ___m_maxPuzzleValue) { if (!ArchipelagoHelper.IsConnectedAndEnabled || !ArchipelagoHelper.IsPuzzleRandomizationEnabled()) { return true; } ((TMP_Text)___m_puzzleText).text = $"{value}/{___m_maxPuzzleValue}"; if (value == ___m_maxPuzzleValue) { if (___m_boardPuzzle.activeSelf) { ___m_boardPuzzle.SetActive(false); } ___m_boardPuzzleFull.SetActive(true); } else { if (___m_boardPuzzleFull.activeSelf) { ___m_boardPuzzleFull.SetActive(false); } ___m_boardPuzzle.SetActive(true); } return false; } } [HarmonyPatch(typeof(KartSelectionNavigation), "Enter")] public class KartSelectionNavigation_Enter_Patch { private static bool Prefix(KartSelectionNavigation __instance, EnumArray ___m_items) { if (!ArchipelagoHelper.IsConnectedAndEnabled) { return true; } DrivingCaracStatsRando.ApplyAll(); UpdateCharacterUnlocks(__instance, ___m_items); UpdateKartUnlocks(__instance, ___m_items); return true; } private static void UpdateCharacterUnlocks(KartSelectionNavigation instance, EnumArray items) { //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Expected O, but got Unknown //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Invalid comparison between Unknown and I4 if (items == null) { return; } MethodInfo method = ((object)items).GetType().GetMethod("get_Item", BindingFlags.Instance | BindingFlags.Public, null, new Type[1] { typeof(int) }, null); if (!(method == null)) { KartSelectionItem[] array = (KartSelectionItem[])method.Invoke(items, new object[1] { 0 }); KartSelectionItem[] array2 = array; foreach (KartSelectionItem val in array2) { CharacterCarac val2 = (CharacterCarac)val.IconCarac; UnlockableItemSate characterState = Singleton.Instance.GetCharacterState(((DrivingCarac)val2).Owner); bool flag = characterState - 3 <= 1; bool flag2 = flag; val.SetLock(!flag2); } } } private static void UpdateKartUnlocks(KartSelectionNavigation instance, EnumArray items) { //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Expected O, but got Unknown //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Invalid comparison between Unknown and I4 //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Invalid comparison between Unknown and I4 if (items == null) { return; } MethodInfo method = ((object)items).GetType().GetMethod("get_Item", BindingFlags.Instance | BindingFlags.Public, null, new Type[1] { typeof(int) }, null); if (!(method == null)) { KartSelectionItem[] array = (KartSelectionItem[])method.Invoke(items, new object[1] { 1 }); KartSelectionItem[] array2 = array; foreach (KartSelectionItem val in array2) { KartCarac val2 = (KartCarac)val.IconCarac; UnlockableItemSate kartState = Singleton.Instance.GetKartState(((DrivingCarac)val2).Owner); bool flag = (int)kartState == 4 || (int)kartState == 3; val.SetLock(!flag); } } } } [HarmonyPatch(typeof(GameSaveManager), "GetCharacterState")] public class GameSaveManager_GetCharacterState_Patch { private static bool Prefix(GameSaveManager __instance, ECharacter character, ref UnlockableItemSate __result) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) bool flag = ArchipelagoHelper.IsCharRandomizerEnabled(); Log.Info($"{flag} CHARACTER RANDO CHECK"); if (!ArchipelagoHelper.IsConnectedAndEnabled) { return true; } long num = 301 + (long)character; Log.Info($"{character}, {num}"); __result = (UnlockableItemSate)((ArchipelagoItemTracker.HasItem(num) || !flag) ? 4 : 2); return false; } } [HarmonyPatch(typeof(GameSaveManager), "GetKartState")] public class GameSaveManager_GetKartState_Patch { private static bool Prefix(GameSaveManager __instance, ECharacter kart, ref UnlockableItemSate __result) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) bool flag = ArchipelagoHelper.IsKartRandomizerEnabled(); Log.Info($"{flag} KART RANDO CHECK"); if (!ArchipelagoHelper.IsConnectedAndEnabled) { return true; } long itemId = 351 + (long)kart; __result = (UnlockableItemSate)((ArchipelagoItemTracker.HasItem(itemId) || !flag) ? 4 : 2); return false; } } [HarmonyPatch(typeof(GameSaveManager), "GetHatState")] public class GameSaveManager_GetHatState_Patch { private static bool Prefix(GameSaveManager __instance, string hat, ref UnlockableItemSate __result) { bool flag = ArchipelagoHelper.IsHatRandomizerEnabled(); bool flag2 = ArchipelagoHelper.IsProgressiveHatEnabled(); char c = hat[hat.Length - 1]; int num = 1; switch (c) { case 'N': num = 1; break; case 'R': num = 2; break; case 'U': num = 3; break; } long hatItemId = ArchipelagoConstants.GetHatItemId(hat, flag2); if (!flag || !ArchipelagoHelper.IsConnectedAndEnabled) { return true; } if ((ArchipelagoItemTracker.HasItem(hatItemId) && !flag2) || (flag2 && ArchipelagoItemTracker.AmountOfItem(hatItemId) >= num)) { __result = (UnlockableItemSate)4; } else { __result = (UnlockableItemSate)2; } return false; } } [HarmonyPatch(typeof(GameSaveManager), "GetCustomState")] public class GameSaveManager_GetCustomState_Patch { private static bool Prefix(GameSaveManager __instance, string custom, ref UnlockableItemSate __result) { bool flag = ArchipelagoHelper.IsSpoilerRandomizerEnabled(); bool flag2 = ArchipelagoHelper.IsProgressiveSpoilerEnabled(); char c = custom[custom.Length - 1]; int num = 1; switch (c) { case 'N': num = 1; break; case 'R': num = 2; break; case 'U': num = 3; break; } if (!flag || !ArchipelagoHelper.IsConnectedAndEnabled) { return true; } long spoilerItemId = ArchipelagoConstants.GetSpoilerItemId(custom, flag2); if (ArchipelagoItemTracker.HasItem(spoilerItemId) && !flag2) { __result = (UnlockableItemSate)4; } else if (flag2 && ArchipelagoItemTracker.AmountOfItem(spoilerItemId) >= num) { __result = (UnlockableItemSate)4; } else { __result = (UnlockableItemSate)2; } return false; } } [HarmonyPatch(typeof(Localization), "Get")] public class Localization_Get_Patch { private static void Postfix(string key, ref string __result) { if (ArchipelagoHelper.IsConnectedAndEnabled) { switch (key) { case "MENU_GARAGE_UNLOCK_SINGLE_RACE": __result = "Receive the Archipelago item for this hat to utilize it!"; break; case "MENU_GARAGE_UNLOCK_GRAND_PRIX": __result = "Receive the Archipelago item for this spoiler to utilize it!"; break; case "MENU_GARAGE_UNLOCK_TIME_TRIAL": __result = ""; break; case "MENU_GARAGE_UNLOCK_OR": __result = ""; break; } } } } [HarmonyPatch(typeof(RewardManager), "EarnReward")] public class RewardManager_EarnReward_Patch { private static void Postfix(RewardManager __instance, string track, int rank = 0, E_TimeTrialMedal medal = 0, float diffTime = 0f, int nbFirstPlace = 0, int cup = 0) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Invalid comparison between Unknown and I4 //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Invalid comparison between Unknown and I4 //IL_01e0: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Invalid comparison between Unknown and I4 //IL_01e4: Unknown result type (might be due to invalid IL or missing references) //IL_01e6: Invalid comparison between Unknown and I4 //IL_0339: Unknown result type (might be due to invalid IL or missing references) //IL_033b: Invalid comparison between Unknown and I4 //IL_01f6: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_022b: Unknown result type (might be due to invalid IL or missing references) //IL_022d: Invalid comparison between Unknown and I4 //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_034e: Unknown result type (might be due to invalid IL or missing references) //IL_023d: Unknown result type (might be due to invalid IL or missing references) //IL_023f: Invalid comparison between Unknown and I4 //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Invalid comparison between Unknown and I4 //IL_024f: Unknown result type (might be due to invalid IL or missing references) //IL_0251: Invalid comparison between Unknown and I4 //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Invalid comparison between Unknown and I4 //IL_0261: Unknown result type (might be due to invalid IL or missing references) //IL_0263: Invalid comparison between Unknown and I4 //IL_02e5: Unknown result type (might be due to invalid IL or missing references) //IL_02e7: Unknown result type (might be due to invalid IL or missing references) //IL_02e8: Unknown result type (might be due to invalid IL or missing references) //IL_02eb: Unknown result type (might be due to invalid IL or missing references) if (!ArchipelagoHelper.IsConnectedAndEnabled) { return; } E_GameModeType gameModeType = Singleton.Instance.GameModeType; Difficulty difficulty = Singleton.Instance.Difficulty; PlayerConfig playerConfig = Singleton.Instance.GetPlayerConfig(0); ECharacter character = playerConfig.Character; ECharacter kart = playerConfig.Kart; if (((int)gameModeType == 2 || (int)gameModeType == 3) && rank == 0) { string text = "any"; if (ArchipelagoGoalManager.GetGoalId() == 0L || ArchipelagoGoalManager.GetGoalId() == 1) { text = ArchipelagoHelper.GetCCRequirement(); } if (text != "any" && ((text == "easy" && (int)difficulty != 0) || (text == "normal" && (int)difficulty != 1) || (text == "hard" && (int)difficulty != 2))) { Log.Message("Skipping cup victory location send due to CC requirement (" + text + ")"); return; } GarfieldKartAPMod.APClient.SendLocation(ArchipelagoConstants.GetRaceVictoryLoc(track)); GarfieldKartAPMod.APClient.SendLocation((long)character + 1001); GarfieldKartAPMod.APClient.SendLocation((long)kart + 1051); if (ArchipelagoHelper.IsLapSanityEnabled()) { int lapCount = ArchipelagoHelper.GetLapCount(); int num = lapCount - 1; long lapSanityLoc = ArchipelagoConstants.GetLapSanityLoc(track, num); if (lapSanityLoc != -1) { GarfieldKartAPMod.APClient.SendLocation(lapSanityLoc); Log.Message($"Sent final lap sanity check for {track}, lap {num + 1}"); } } ArchipelagoGoalManager.CheckAndCompleteGoal(); List hatLocs = ArchipelagoConstants.GetHatLocs(track, difficulty); foreach (long item in hatLocs) { GarfieldKartAPMod.APClient.SendLocation(item); } } if ((int)gameModeType == 4 && (int)medal > 0) { List timeTrialLocs = ArchipelagoConstants.GetTimeTrialLocs(track, medal); string text2 = "bronze"; if (ArchipelagoGoalManager.GetGoalId() == 2) { text2 = ArchipelagoHelper.GetTimeTrialGoalGrade(); } if ((text2 == "bronze" && (int)medal != 1) || (text2 == "silver" && (int)medal != 2) || (text2 == "gold" && (int)medal != 3) || (text2 == "platinum" && (int)medal != 4)) { Log.Message("Skipping cup victory location send due to CC requirement (" + text2 + ")"); return; } foreach (long item2 in timeTrialLocs) { GarfieldKartAPMod.APClient.SendLocation(item2); } Object.FindObjectOfType()?.WriteTimeTrialData(track); Difficulty difficulty2 = (Difficulty)(difficulty - 1); List hatLocs2 = ArchipelagoConstants.GetHatLocs(track, difficulty2); foreach (long item3 in hatLocs2) { GarfieldKartAPMod.APClient.SendLocation(item3); } ArchipelagoGoalManager.CheckAndCompleteGoal(); } if ((int)gameModeType != 3 || nbFirstPlace != 4) { return; } List spoilerLocs = ArchipelagoConstants.GetSpoilerLocs(cup, difficulty); foreach (long item4 in spoilerLocs) { GarfieldKartAPMod.APClient.SendLocation(item4); } } } [HarmonyPatch(typeof(RewardManager), "EndChampionShip")] public class RewardManager_EndChampionShip_Patch { private static void Postfix(RewardManager __instance, int pFinalRank, int pNbFirstPlace, bool save) { if (ArchipelagoHelper.IsConnectedAndEnabled && pFinalRank == 0) { SendCupVictoryLocation(); ArchipelagoGoalManager.CheckAndCompleteGoal(); } } private static void SendCupVictoryLocation() { //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_005f: 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_0073: Invalid comparison between Unknown and I4 //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Invalid comparison between Unknown and I4 string championShipNameId = Singleton.Instance.ChampionShipData.ChampionShipNameId; string text = "any"; if (ArchipelagoGoalManager.GetGoalId() == 0L || ArchipelagoGoalManager.GetGoalId() == 1) { text = ArchipelagoHelper.GetCCRequirement(); } if (text != "any") { Difficulty difficulty = Singleton.Instance.Difficulty; if ((text == "easy" && (int)difficulty != 0) || (text == "normal" && (int)difficulty != 1) || (text == "hard" && (int)difficulty != 2)) { Log.Message("Skipping cup victory location send due to CC requirement (" + text + ")"); return; } } switch (championShipNameId) { case "CHAMPIONSHIP_NAME_1": GarfieldKartAPMod.APClient.SendLocation(101L); break; case "CHAMPIONSHIP_NAME_2": GarfieldKartAPMod.APClient.SendLocation(102L); break; case "CHAMPIONSHIP_NAME_3": GarfieldKartAPMod.APClient.SendLocation(103L); break; case "CHAMPIONSHIP_NAME_4": GarfieldKartAPMod.APClient.SendLocation(104L); break; } } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { internal IgnoresAccessChecksToAttribute(string assemblyName) { } } }