Decompiled source of HotLavaArchipelago v0.0.4

Archipelago.MultiClient.Net.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net.WebSockets;
using System.Numerics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Archipelago.MultiClient.Net.Colors;
using Archipelago.MultiClient.Net.ConcurrentCollection;
using Archipelago.MultiClient.Net.Converters;
using Archipelago.MultiClient.Net.DataPackage;
using Archipelago.MultiClient.Net.Enums;
using Archipelago.MultiClient.Net.Exceptions;
using Archipelago.MultiClient.Net.Extensions;
using Archipelago.MultiClient.Net.Helpers;
using Archipelago.MultiClient.Net.MessageLog.Messages;
using Archipelago.MultiClient.Net.MessageLog.Parts;
using Archipelago.MultiClient.Net.Models;
using Archipelago.MultiClient.Net.Packets;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Serialization;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: ComVisible(false)]
[assembly: Guid("35a803ad-85ed-42e9-b1e3-c6b72096f0c1")]
[assembly: InternalsVisibleTo("Archipelago.MultiClient.Net.Tests")]
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]
[assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")]
[assembly: AssemblyCompany("Jarno Westhof, Hussein Farran, Zach Parks")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("Copyright © 2025")]
[assembly: AssemblyDescription("A client library for use with .NET based prog-langs for interfacing with Archipelago hosts.")]
[assembly: AssemblyFileVersion("6.7.0.0")]
[assembly: AssemblyInformationalVersion("6.7.0+c807746b6f1774cf1afe12af819acb078b55a333")]
[assembly: AssemblyProduct("Archipelago.MultiClient.Net")]
[assembly: AssemblyTitle("Archipelago.MultiClient.Net")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/ArchipelagoMW/Archipelago.MultiClient.Net")]
[assembly: AssemblyVersion("6.7.0.0")]
internal interface IConcurrentHashSet<T>
{
	bool TryAdd(T item);

	bool Contains(T item);

	void UnionWith(T[] otherSet);

	T[] ToArray();

	ReadOnlyCollection<T> AsToReadOnlyCollection();

	ReadOnlyCollection<T> AsToReadOnlyCollectionExcept(IConcurrentHashSet<T> otherSet);
}
public class AttemptingStringEnumConverter : StringEnumConverter
{
	public AttemptingStringEnumConverter()
	{
	}

	public AttemptingStringEnumConverter(Type namingStrategyType)
		: base(namingStrategyType)
	{
	}

	public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
	{
		try
		{
			return ((StringEnumConverter)this).ReadJson(reader, objectType, existingValue, serializer);
		}
		catch (JsonSerializationException)
		{
			return objectType.IsValueType ? Activator.CreateInstance(objectType) : null;
		}
	}
}
namespace Archipelago.MultiClient.Net
{
	[Serializable]
	public abstract class ArchipelagoPacketBase
	{
		[JsonIgnore]
		internal JObject jobject;

		[JsonProperty("cmd")]
		[JsonConverter(typeof(StringEnumConverter))]
		public abstract ArchipelagoPacketType PacketType { get; }

		public JObject ToJObject()
		{
			return jobject;
		}
	}
	public interface IArchipelagoSession : IArchipelagoSessionActions
	{
		IArchipelagoSocketHelper Socket { get; }

		IReceivedItemsHelper Items { get; }

		ILocationCheckHelper Locations { get; }

		IPlayerHelper Players { get; }

		IDataStorageHelper DataStorage { get; }

		IConnectionInfoProvider ConnectionInfo { get; }

		IRoomStateHelper RoomState { get; }

		IMessageLogHelper MessageLog { get; }

		IHintsHelper Hints { get; }

		Task<RoomInfoPacket> ConnectAsync();

		Task<LoginResult> LoginAsync(string game, string name, ItemsHandlingFlags itemsHandlingFlags, Version version = null, string[] tags = null, string uuid = null, string password = null, bool requestSlotData = true);

		LoginResult TryConnectAndLogin(string game, string name, ItemsHandlingFlags itemsHandlingFlags, Version version = null, string[] tags = null, string uuid = null, string password = null, bool requestSlotData = true);
	}
	public class ArchipelagoSession : IArchipelagoSession, IArchipelagoSessionActions
	{
		private const int ArchipelagoConnectionTimeoutInSeconds = 4;

		private ConnectionInfoHelper connectionInfo;

		private TaskCompletionSource<LoginResult> loginResultTask = new TaskCompletionSource<LoginResult>();

		private TaskCompletionSource<RoomInfoPacket> roomInfoPacketTask = new TaskCompletionSource<RoomInfoPacket>();

		public IArchipelagoSocketHelper Socket { get; }

		public IReceivedItemsHelper Items { get; }

		public ILocationCheckHelper Locations { get; }

		public IPlayerHelper Players { get; }

		public IDataStorageHelper DataStorage { get; }

		public IConnectionInfoProvider ConnectionInfo => connectionInfo;

		public IRoomStateHelper RoomState { get; }

		public IMessageLogHelper MessageLog { get; }

		public IHintsHelper Hints { get; }

		internal ArchipelagoSession(IArchipelagoSocketHelper socket, IReceivedItemsHelper items, ILocationCheckHelper locations, IPlayerHelper players, IRoomStateHelper roomState, ConnectionInfoHelper connectionInfoHelper, IDataStorageHelper dataStorage, IMessageLogHelper messageLog, IHintsHelper createHints)
		{
			Socket = socket;
			Items = items;
			Locations = locations;
			Players = players;
			RoomState = roomState;
			connectionInfo = connectionInfoHelper;
			DataStorage = dataStorage;
			MessageLog = messageLog;
			Hints = createHints;
			socket.PacketReceived += Socket_PacketReceived;
		}

		private void Socket_PacketReceived(ArchipelagoPacketBase packet)
		{
			if (!(packet is ConnectedPacket) && !(packet is ConnectionRefusedPacket))
			{
				if (packet is RoomInfoPacket result)
				{
					roomInfoPacketTask.TrySetResult(result);
				}
			}
			else
			{
				loginResultTask.TrySetResult(LoginResult.FromPacket(packet));
			}
		}

		public Task<RoomInfoPacket> ConnectAsync()
		{
			roomInfoPacketTask = new TaskCompletionSource<RoomInfoPacket>();
			Task.Factory.StartNew(delegate
			{
				try
				{
					Task task = Socket.ConnectAsync();
					task.Wait(TimeSpan.FromSeconds(4.0));
					if (!task.IsCompleted)
					{
						roomInfoPacketTask.TrySetCanceled();
					}
				}
				catch (AggregateException)
				{
					roomInfoPacketTask.TrySetCanceled();
				}
			});
			return roomInfoPacketTask.Task;
		}

		public Task<LoginResult> LoginAsync(string game, string name, ItemsHandlingFlags itemsHandlingFlags, Version version = null, string[] tags = null, string uuid = null, string password = null, bool requestSlotData = true)
		{
			loginResultTask = new TaskCompletionSource<LoginResult>();
			if (!roomInfoPacketTask.Task.IsCompleted)
			{
				loginResultTask.TrySetResult(new LoginFailure("You are not connected, run ConnectAsync() first"));
				return loginResultTask.Task;
			}
			connectionInfo.SetConnectionParameters(game, tags, itemsHandlingFlags, uuid);
			try
			{
				Socket.SendPacket(BuildConnectPacket(name, password, version, requestSlotData));
			}
			catch (ArchipelagoSocketClosedException)
			{
				loginResultTask.TrySetResult(new LoginFailure("You are not connected, run ConnectAsync() first"));
				return loginResultTask.Task;
			}
			SetResultAfterTimeout(loginResultTask, 4, new LoginFailure("Connection timed out."));
			return loginResultTask.Task;
		}

		private static void SetResultAfterTimeout<T>(TaskCompletionSource<T> task, int timeoutInSeconds, T result)
		{
			new CancellationTokenSource(TimeSpan.FromSeconds(timeoutInSeconds)).Token.Register(delegate
			{
				task.TrySetResult(result);
			});
		}

		public LoginResult TryConnectAndLogin(string game, string name, ItemsHandlingFlags itemsHandlingFlags, Version version = null, string[] tags = null, string uuid = null, string password = null, bool requestSlotData = true)
		{
			Task<RoomInfoPacket> task = ConnectAsync();
			try
			{
				task.Wait(TimeSpan.FromSeconds(4.0));
			}
			catch (AggregateException ex)
			{
				if (ex.GetBaseException() is OperationCanceledException)
				{
					return new LoginFailure("Connection timed out.");
				}
				return new LoginFailure(ex.GetBaseException().Message);
			}
			if (!task.IsCompleted)
			{
				return new LoginFailure("Connection timed out.");
			}
			return LoginAsync(game, name, itemsHandlingFlags, version, tags, uuid, password, requestSlotData).Result;
		}

		private ConnectPacket BuildConnectPacket(string name, string password, Version version, bool requestSlotData)
		{
			return new ConnectPacket
			{
				Game = ConnectionInfo.Game,
				Name = name,
				Password = password,
				Tags = ConnectionInfo.Tags,
				Uuid = ConnectionInfo.Uuid,
				Version = ((version != null) ? new NetworkVersion(version) : new NetworkVersion(0, 6, 0)),
				ItemsHandling = ConnectionInfo.ItemsHandlingFlags,
				RequestSlotData = requestSlotData
			};
		}

		public void Say(string message)
		{
			Socket.SendPacket(new SayPacket
			{
				Text = message
			});
		}

		public void SetClientState(ArchipelagoClientState state)
		{
			Socket.SendPacket(new StatusUpdatePacket
			{
				Status = state
			});
		}

		public void SetGoalAchieved()
		{
			SetClientState(ArchipelagoClientState.ClientGoal);
		}
	}
	public interface IArchipelagoSessionActions
	{
		void Say(string message);

		void SetClientState(ArchipelagoClientState state);

		void SetGoalAchieved();
	}
	public static class ArchipelagoSessionFactory
	{
		public static ArchipelagoSession CreateSession(Uri uri)
		{
			ArchipelagoSocketHelper socket = new ArchipelagoSocketHelper(uri);
			DataPackageCache cache = new DataPackageCache(socket);
			ConnectionInfoHelper connectionInfoHelper = new ConnectionInfoHelper(socket);
			PlayerHelper playerHelper = new PlayerHelper(socket, connectionInfoHelper);
			ItemInfoResolver itemInfoResolver = new ItemInfoResolver(cache, connectionInfoHelper);
			LocationCheckHelper locationCheckHelper = new LocationCheckHelper(socket, itemInfoResolver, connectionInfoHelper, playerHelper);
			ReceivedItemsHelper items = new ReceivedItemsHelper(socket, locationCheckHelper, itemInfoResolver, connectionInfoHelper, playerHelper);
			RoomStateHelper roomStateHelper = new RoomStateHelper(socket, locationCheckHelper);
			DataStorageHelper dataStorageHelper = new DataStorageHelper(socket, connectionInfoHelper);
			MessageLogHelper messageLog = new MessageLogHelper(socket, itemInfoResolver, playerHelper, connectionInfoHelper);
			HintsHelper createHints = new HintsHelper(socket, playerHelper, locationCheckHelper, roomStateHelper, dataStorageHelper);
			return new ArchipelagoSession(socket, items, locationCheckHelper, playerHelper, roomStateHelper, connectionInfoHelper, dataStorageHelper, messageLog, createHints);
		}

		public static ArchipelagoSession CreateSession(string hostname, int port = 38281)
		{
			return CreateSession(ParseUri(hostname, port));
		}

		internal static Uri ParseUri(string hostname, int port)
		{
			string text = hostname;
			if (!text.StartsWith("ws://") && !text.StartsWith("wss://"))
			{
				text = "unspecified://" + text;
			}
			if (!text.Substring(text.IndexOf("://", StringComparison.Ordinal) + 3).Contains(":"))
			{
				text += $":{port}";
			}
			if (text.EndsWith(":"))
			{
				text += port;
			}
			return new Uri(text);
		}
	}
	public abstract class LoginResult
	{
		public abstract bool Successful { get; }

		public static LoginResult FromPacket(ArchipelagoPacketBase packet)
		{
			if (!(packet is ConnectedPacket connectedPacket))
			{
				if (packet is ConnectionRefusedPacket connectionRefusedPacket)
				{
					return new LoginFailure(connectionRefusedPacket);
				}
				throw new ArgumentOutOfRangeException("packet", "packet is not a connection result packet");
			}
			return new LoginSuccessful(connectedPacket);
		}
	}
	public class LoginSuccessful : LoginResult
	{
		public override bool Successful => true;

		public int Team { get; }

		public int Slot { get; }

		public Dictionary<string, object> SlotData { get; }

		public LoginSuccessful(ConnectedPacket connectedPacket)
		{
			Team = connectedPacket.Team;
			Slot = connectedPacket.Slot;
			SlotData = connectedPacket.SlotData;
		}
	}
	public class LoginFailure : LoginResult
	{
		public override bool Successful => false;

		public ConnectionRefusedError[] ErrorCodes { get; }

		public string[] Errors { get; }

		public LoginFailure(ConnectionRefusedPacket connectionRefusedPacket)
		{
			if (connectionRefusedPacket.Errors != null)
			{
				ErrorCodes = connectionRefusedPacket.Errors.ToArray();
				Errors = ErrorCodes.Select(GetErrorMessage).ToArray();
			}
			else
			{
				ErrorCodes = new ConnectionRefusedError[0];
				Errors = new string[0];
			}
		}

		public LoginFailure(string message)
		{
			ErrorCodes = new ConnectionRefusedError[0];
			Errors = new string[1] { message };
		}

		private static string GetErrorMessage(ConnectionRefusedError errorCode)
		{
			return errorCode switch
			{
				ConnectionRefusedError.InvalidSlot => "The slot name did not match any slot on the server.", 
				ConnectionRefusedError.InvalidGame => "The slot is set to a different game on the server.", 
				ConnectionRefusedError.SlotAlreadyTaken => "The slot already has a connection with a different uuid established.", 
				ConnectionRefusedError.IncompatibleVersion => "The client and server version mismatch.", 
				ConnectionRefusedError.InvalidPassword => "The password is invalid.", 
				ConnectionRefusedError.InvalidItemsHandling => "The item handling flags provided are invalid.", 
				_ => $"Unknown error: {errorCode}.", 
			};
		}
	}
	internal class TwoWayLookup<TA, TB> : IEnumerable<KeyValuePair<TB, TA>>, IEnumerable
	{
		private readonly Dictionary<TA, TB> aToB = new Dictionary<TA, TB>();

		private readonly Dictionary<TB, TA> bToA = new Dictionary<TB, TA>();

		public TA this[TB b] => bToA[b];

		public TB this[TA a] => aToB[a];

		public void Add(TA a, TB b)
		{
			aToB[a] = b;
			bToA[b] = a;
		}

		public void Add(TB b, TA a)
		{
			Add(a, b);
		}

		public bool TryGetValue(TA a, out TB b)
		{
			return aToB.TryGetValue(a, out b);
		}

		public bool TryGetValue(TB b, out TA a)
		{
			return bToA.TryGetValue(b, out a);
		}

		public IEnumerator<KeyValuePair<TB, TA>> GetEnumerator()
		{
			return bToA.GetEnumerator();
		}

		IEnumerator IEnumerable.GetEnumerator()
		{
			return GetEnumerator();
		}
	}
}
namespace Archipelago.MultiClient.Net.Packets
{
	public class BouncedPacket : BouncePacket
	{
		public override ArchipelagoPacketType PacketType => ArchipelagoPacketType.Bounced;
	}
	public class BouncePacket : ArchipelagoPacketBase
	{
		public override ArchipelagoPacketType PacketType => ArchipelagoPacketType.Bounce;

		[JsonProperty("games")]
		public List<string> Games { get; set; } = new List<string>();


		[JsonProperty("slots")]
		public List<int> Slots { get; set; } = new List<int>();


		[JsonProperty("tags")]
		public List<string> Tags { get; set; } = new List<string>();


		[JsonProperty("data")]
		public Dictionary<string, JToken> Data { get; set; }
	}
	public class ConnectedPacket : ArchipelagoPacketBase
	{
		public override ArchipelagoPacketType PacketType => ArchipelagoPacketType.Connected;

		[JsonProperty("team")]
		public int Team { get; set; }

		[JsonProperty("slot")]
		public int Slot { get; set; }

		[JsonProperty("players")]
		public NetworkPlayer[] Players { get; set; }

		[JsonProperty("missing_locations")]
		public long[] MissingChecks { get; set; }

		[JsonProperty("checked_locations")]
		public long[] LocationsChecked { get; set; }

		[JsonProperty("slot_data")]
		public Dictionary<string, object> SlotData { get; set; }

		[JsonProperty("slot_info")]
		public Dictionary<int, NetworkSlot> SlotInfo { get; set; }

		[JsonProperty("hint_points")]
		public int? HintPoints { get; set; }
	}
	public class ConnectionRefusedPacket : ArchipelagoPacketBase
	{
		public override ArchipelagoPacketType PacketType => ArchipelagoPacketType.ConnectionRefused;

		[JsonProperty("errors", ItemConverterType = typeof(AttemptingStringEnumConverter))]
		public ConnectionRefusedError[] Errors { get; set; }
	}
	public class ConnectPacket : ArchipelagoPacketBase
	{
		public override ArchipelagoPacketType PacketType => ArchipelagoPacketType.Connect;

		[JsonProperty("password")]
		public string Password { get; set; }

		[JsonProperty("game")]
		public string Game { get; set; }

		[JsonProperty("name")]
		public string Name { get; set; }

		[JsonProperty("uuid")]
		public string Uuid { get; set; }

		[JsonProperty("version")]
		public NetworkVersion Version { get; set; }

		[JsonProperty("tags")]
		public string[] Tags { get; set; }

		[JsonProperty("items_handling")]
		public ItemsHandlingFlags ItemsHandling { get; set; }

		[JsonProperty("slot_data")]
		public bool RequestSlotData { get; set; }
	}
	public class ConnectUpdatePacket : ArchipelagoPacketBase
	{
		public override ArchipelagoPacketType PacketType => ArchipelagoPacketType.ConnectUpdate;

		[JsonProperty("tags")]
		public string[] Tags { get; set; }

		[JsonProperty("items_handling")]
		public ItemsHandlingFlags? ItemsHandling { get; set; }
	}
	public class CreateHintsPacket : ArchipelagoPacketBase
	{
		public override ArchipelagoPacketType PacketType => ArchipelagoPacketType.CreateHints;

		[JsonProperty("locations")]
		public long[] Locations { get; set; }

		[JsonProperty("player")]
		public int Player { get; set; }

		[JsonProperty("status")]
		public HintStatus Status { get; set; }
	}
	public class DataPackagePacket : ArchipelagoPacketBase
	{
		public override ArchipelagoPacketType PacketType => ArchipelagoPacketType.DataPackage;

		[JsonProperty("data")]
		public Archipelago.MultiClient.Net.Models.DataPackage DataPackage { get; set; }
	}
	public class GetDataPackagePacket : ArchipelagoPacketBase
	{
		public override ArchipelagoPacketType PacketType => ArchipelagoPacketType.GetDataPackage;

		[JsonProperty("games")]
		public string[] Games { get; set; }
	}
	public class GetPacket : ArchipelagoPacketBase
	{
		public override ArchipelagoPacketType PacketType => ArchipelagoPacketType.Get;

		[JsonProperty("keys")]
		public string[] Keys { get; set; }
	}
	public class InvalidPacketPacket : ArchipelagoPacketBase
	{
		public override ArchipelagoPacketType PacketType => ArchipelagoPacketType.InvalidPacket;

		[JsonProperty("type")]
		public InvalidPacketErrorType ErrorType { get; set; }

		[JsonProperty("text")]
		public string ErrorText { get; set; }

		[JsonProperty("original_cmd")]
		public ArchipelagoPacketType OriginalCmd { get; set; }
	}
	public class LocationChecksPacket : ArchipelagoPacketBase
	{
		public override ArchipelagoPacketType PacketType => ArchipelagoPacketType.LocationChecks;

		[JsonProperty("locations")]
		public long[] Locations { get; set; }
	}
	public class LocationInfoPacket : ArchipelagoPacketBase
	{
		public override ArchipelagoPacketType PacketType => ArchipelagoPacketType.LocationInfo;

		[JsonProperty("locations")]
		public NetworkItem[] Locations { get; set; }
	}
	public class LocationScoutsPacket : ArchipelagoPacketBase
	{
		public override ArchipelagoPacketType PacketType => ArchipelagoPacketType.LocationScouts;

		[JsonProperty("locations")]
		public long[] Locations { get; set; }

		[JsonProperty("create_as_hint")]
		public int CreateAsHint { get; set; }
	}
	public class PrintJsonPacket : ArchipelagoPacketBase
	{
		public override ArchipelagoPacketType PacketType => ArchipelagoPacketType.PrintJSON;

		[JsonProperty("data")]
		public JsonMessagePart[] Data { get; set; }

		[JsonProperty("type")]
		[JsonConverter(typeof(AttemptingStringEnumConverter))]
		public JsonMessageType? MessageType { get; set; }
	}
	public class ItemPrintJsonPacket : PrintJsonPacket
	{
		[JsonProperty("receiving")]
		public int ReceivingPlayer { get; set; }

		[JsonProperty("item")]
		public NetworkItem Item { get; set; }
	}
	public class ItemCheatPrintJsonPacket : PrintJsonPacket
	{
		[JsonProperty("receiving")]
		public int ReceivingPlayer { get; set; }

		[JsonProperty("item")]
		public NetworkItem Item { get; set; }

		[JsonProperty("team")]
		public int Team { get; set; }
	}
	public class HintPrintJsonPacket : PrintJsonPacket
	{
		[JsonProperty("receiving")]
		public int ReceivingPlayer { get; set; }

		[JsonProperty("item")]
		public NetworkItem Item { get; set; }

		[JsonProperty("found")]
		public bool? Found { get; set; }
	}
	public class JoinPrintJsonPacket : PrintJsonPacket
	{
		[JsonProperty("team")]
		public int Team { get; set; }

		[JsonProperty("slot")]
		public int Slot { get; set; }

		[JsonProperty("tags")]
		public string[] Tags { get; set; }
	}
	public class LeavePrintJsonPacket : PrintJsonPacket
	{
		[JsonProperty("team")]
		public int Team { get; set; }

		[JsonProperty("slot")]
		public int Slot { get; set; }
	}
	public class ChatPrintJsonPacket : PrintJsonPacket
	{
		[JsonProperty("team")]
		public int Team { get; set; }

		[JsonProperty("slot")]
		public int Slot { get; set; }

		[JsonProperty("message")]
		public string Message { get; set; }
	}
	public class ServerChatPrintJsonPacket : PrintJsonPacket
	{
		[JsonProperty("message")]
		public string Message { get; set; }
	}
	public class TutorialPrintJsonPacket : PrintJsonPacket
	{
	}
	public class TagsChangedPrintJsonPacket : PrintJsonPacket
	{
		[JsonProperty("team")]
		public int Team { get; set; }

		[JsonProperty("slot")]
		public int Slot { get; set; }

		[JsonProperty("tags")]
		public string[] Tags { get; set; }
	}
	public class CommandResultPrintJsonPacket : PrintJsonPacket
	{
	}
	public class AdminCommandResultPrintJsonPacket : PrintJsonPacket
	{
	}
	public class GoalPrintJsonPacket : PrintJsonPacket
	{
		[JsonProperty("team")]
		public int Team { get; set; }

		[JsonProperty("slot")]
		public int Slot { get; set; }
	}
	public class ReleasePrintJsonPacket : PrintJsonPacket
	{
		[JsonProperty("team")]
		public int Team { get; set; }

		[JsonProperty("slot")]
		public int Slot { get; set; }
	}
	public class CollectPrintJsonPacket : PrintJsonPacket
	{
		[JsonProperty("team")]
		public int Team { get; set; }

		[JsonProperty("slot")]
		public int Slot { get; set; }
	}
	public class CountdownPrintJsonPacket : PrintJsonPacket
	{
		[JsonProperty("countdown")]
		public int RemainingSeconds { get; set; }
	}
	public class ReceivedItemsPacket : ArchipelagoPacketBase
	{
		public override ArchipelagoPacketType PacketType => ArchipelagoPacketType.ReceivedItems;

		[JsonProperty("index")]
		public int Index { get; set; }

		[JsonProperty("items")]
		public NetworkItem[] Items { get; set; }
	}
	public class RetrievedPacket : ArchipelagoPacketBase
	{
		public override ArchipelagoPacketType PacketType => ArchipelagoPacketType.Retrieved;

		[JsonProperty("keys")]
		public Dictionary<string, JToken> Data { get; set; }
	}
	public class RoomInfoPacket : ArchipelagoPacketBase
	{
		public override ArchipelagoPacketType PacketType => ArchipelagoPacketType.RoomInfo;

		[JsonProperty("version")]
		public NetworkVersion Version { get; set; }

		[JsonProperty("generator_version")]
		public NetworkVersion GeneratorVersion { get; set; }

		[JsonProperty("tags")]
		public string[] Tags { get; set; }

		[JsonProperty("password")]
		public bool Password { get; set; }

		[JsonProperty("permissions")]
		public Dictionary<string, Permissions> Permissions { get; set; }

		[JsonProperty("hint_cost")]
		public int HintCostPercentage { get; set; }

		[JsonProperty("location_check_points")]
		public int LocationCheckPoints { get; set; }

		[JsonProperty("players")]
		public NetworkPlayer[] Players { get; set; }

		[JsonProperty("games")]
		public string[] Games { get; set; }

		[JsonProperty("datapackage_checksums")]
		public Dictionary<string, string> DataPackageChecksums { get; set; }

		[JsonProperty("seed_name")]
		public string SeedName { get; set; }

		[JsonProperty("time")]
		public double Timestamp { get; set; }
	}
	public class RoomUpdatePacket : ArchipelagoPacketBase
	{
		public override ArchipelagoPacketType PacketType => ArchipelagoPacketType.RoomUpdate;

		[JsonProperty("tags")]
		public string[] Tags { get; set; }

		[JsonProperty("password")]
		public bool? Password { get; set; }

		[JsonProperty("permissions")]
		public Dictionary<string, Permissions> Permissions { get; set; } = new Dictionary<string, Permissions>();


		[JsonProperty("hint_cost")]
		public int? HintCostPercentage { get; set; }

		[JsonProperty("location_check_points")]
		public int? LocationCheckPoints { get; set; }

		[JsonProperty("players")]
		public NetworkPlayer[] Players { get; set; }

		[JsonProperty("hint_points")]
		public int? HintPoints { get; set; }

		[JsonProperty("checked_locations")]
		public long[] CheckedLocations { get; set; }
	}
	public class SayPacket : ArchipelagoPacketBase
	{
		public override ArchipelagoPacketType PacketType => ArchipelagoPacketType.Say;

		[JsonProperty("text")]
		public string Text { get; set; }
	}
	public class SetNotifyPacket : ArchipelagoPacketBase
	{
		public override ArchipelagoPacketType PacketType => ArchipelagoPacketType.SetNotify;

		[JsonProperty("keys")]
		public string[] Keys { get; set; }
	}
	public class SetPacket : ArchipelagoPacketBase
	{
		public override ArchipelagoPacketType PacketType => ArchipelagoPacketType.Set;

		[JsonProperty("key")]
		public string Key { get; set; }

		[JsonProperty("default")]
		public JToken DefaultValue { get; set; }

		[JsonProperty("operations")]
		public OperationSpecification[] Operations { get; set; }

		[JsonProperty("want_reply")]
		public bool WantReply { get; set; }

		[JsonExtensionData]
		public Dictionary<string, JToken> AdditionalArguments { get; set; }

		[OnDeserialized]
		internal void OnDeserializedMethod(StreamingContext context)
		{
			AdditionalArguments?.Remove("cmd");
		}
	}
	public class SetReplyPacket : SetPacket
	{
		public override ArchipelagoPacketType PacketType => ArchipelagoPacketType.SetReply;

		[JsonProperty("value")]
		public JToken Value { get; set; }

		[JsonProperty("original_value")]
		public JToken OriginalValue { get; set; }
	}
	public class StatusUpdatePacket : ArchipelagoPacketBase
	{
		public override ArchipelagoPacketType PacketType => ArchipelagoPacketType.StatusUpdate;

		[JsonProperty("status")]
		public ArchipelagoClientState Status { get; set; }
	}
	public class SyncPacket : ArchipelagoPacketBase
	{
		public override ArchipelagoPacketType PacketType => ArchipelagoPacketType.Sync;
	}
	internal class UnknownPacket : ArchipelagoPacketBase
	{
		public override ArchipelagoPacketType PacketType => ArchipelagoPacketType.Unknown;
	}
	public class UpdateHintPacket : ArchipelagoPacketBase
	{
		public override ArchipelagoPacketType PacketType => ArchipelagoPacketType.UpdateHint;

		[JsonProperty("player")]
		public int Player { get; set; }

		[JsonProperty("location")]
		public long Location { get; set; }

		[JsonProperty("status")]
		public HintStatus Status { get; set; }
	}
}
namespace Archipelago.MultiClient.Net.Models
{
	public struct Color : IEquatable<Color>
	{
		public static Color Red = new Color(byte.MaxValue, 0, 0);

		public static Color Green = new Color(0, 128, 0);

		public static Color Yellow = new Color(byte.MaxValue, byte.MaxValue, 0);

		public static Color Blue = new Color(0, 0, byte.MaxValue);

		public static Color Magenta = new Color(byte.MaxValue, 0, byte.MaxValue);

		public static Color Cyan = new Color(0, byte.MaxValue, byte.MaxValue);

		public static Color Black = new Color(0, 0, 0);

		public static Color White = new Color(byte.MaxValue, byte.MaxValue, byte.MaxValue);

		public static Color SlateBlue = new Color(106, 90, 205);

		public static Color Salmon = new Color(250, 128, 114);

		public static Color Plum = new Color(221, 160, 221);

		public byte R { get; set; }

		public byte G { get; set; }

		public byte B { get; set; }

		public Color(byte r, byte g, byte b)
		{
			R = r;
			G = g;
			B = b;
		}

		public override bool Equals(object obj)
		{
			if (obj is Color color && R == color.R && G == color.G)
			{
				return B == color.B;
			}
			return false;
		}

		public bool Equals(Color other)
		{
			if (R == other.R && G == other.G)
			{
				return B == other.B;
			}
			return false;
		}

		public override int GetHashCode()
		{
			return ((-1520100960 * -1521134295 + R.GetHashCode()) * -1521134295 + G.GetHashCode()) * -1521134295 + B.GetHashCode();
		}

		public static bool operator ==(Color left, Color right)
		{
			return left.Equals(right);
		}

		public static bool operator !=(Color left, Color right)
		{
			return !(left == right);
		}
	}
	public class DataPackage
	{
		[JsonProperty("games")]
		public Dictionary<string, GameData> Games { get; set; } = new Dictionary<string, GameData>();

	}
	public class DataStorageElement
	{
		internal DataStorageElementContext Context;

		internal List<OperationSpecification> Operations = new List<OperationSpecification>(0);

		internal DataStorageHelper.DataStorageUpdatedHandler Callbacks;

		internal Dictionary<string, JToken> AdditionalArguments = new Dictionary<string, JToken>(0);

		private JToken cachedValue;

		public event DataStorageHelper.DataStorageUpdatedHandler OnValueChanged
		{
			add
			{
				Context.AddHandler(Context.Key, value);
			}
			remove
			{
				Context.RemoveHandler(Context.Key, value);
			}
		}

		internal DataStorageElement(DataStorageElementContext context)
		{
			Context = context;
		}

		internal DataStorageElement(OperationType operationType, JToken value)
		{
			Operations = new List<OperationSpecification>(1)
			{
				new OperationSpecification
				{
					OperationType = operationType,
					Value = value
				}
			};
		}

		internal DataStorageElement(DataStorageElement source, OperationType operationType, JToken value)
			: this(source.Context)
		{
			Operations = source.Operations.ToList();
			Callbacks = source.Callbacks;
			AdditionalArguments = source.AdditionalArguments;
			Operations.Add(new OperationSpecification
			{
				OperationType = operationType,
				Value = value
			});
		}

		internal DataStorageElement(DataStorageElement source, Callback callback)
			: this(source.Context)
		{
			Operations = source.Operations.ToList();
			Callbacks = source.Callbacks;
			AdditionalArguments = source.AdditionalArguments;
			Callbacks = (DataStorageHelper.DataStorageUpdatedHandler)Delegate.Combine(Callbacks, callback.Method);
		}

		internal DataStorageElement(DataStorageElement source, AdditionalArgument additionalArgument)
			: this(source.Context)
		{
			Operations = source.Operations.ToList();
			Callbacks = source.Callbacks;
			AdditionalArguments = source.AdditionalArguments;
			AdditionalArguments[additionalArgument.Key] = additionalArgument.Value;
		}

		public static DataStorageElement operator ++(DataStorageElement a)
		{
			return new DataStorageElement(a, OperationType.Add, JToken.op_Implicit(1));
		}

		public static DataStorageElement operator --(DataStorageElement a)
		{
			return new DataStorageElement(a, OperationType.Add, JToken.op_Implicit(-1));
		}

		public static DataStorageElement operator +(DataStorageElement a, int b)
		{
			return new DataStorageElement(a, OperationType.Add, JToken.op_Implicit(b));
		}

		public static DataStorageElement operator +(DataStorageElement a, long b)
		{
			return new DataStorageElement(a, OperationType.Add, JToken.op_Implicit(b));
		}

		public static DataStorageElement operator +(DataStorageElement a, float b)
		{
			return new DataStorageElement(a, OperationType.Add, JToken.op_Implicit(b));
		}

		public static DataStorageElement operator +(DataStorageElement a, double b)
		{
			return new DataStorageElement(a, OperationType.Add, JToken.op_Implicit(b));
		}

		public static DataStorageElement operator +(DataStorageElement a, decimal b)
		{
			return new DataStorageElement(a, OperationType.Add, JToken.op_Implicit(b));
		}

		public static DataStorageElement operator +(DataStorageElement a, string b)
		{
			return new DataStorageElement(a, OperationType.Add, JToken.op_Implicit(b));
		}

		public static DataStorageElement operator +(DataStorageElement a, JToken b)
		{
			return new DataStorageElement(a, OperationType.Add, b);
		}

		public static DataStorageElement operator +(DataStorageElement a, IEnumerable b)
		{
			return new DataStorageElement(a, OperationType.Add, (JToken)(object)JArray.FromObject((object)b));
		}

		public static DataStorageElement operator +(DataStorageElement a, OperationSpecification s)
		{
			return new DataStorageElement(a, s.OperationType, s.Value);
		}

		public static DataStorageElement operator +(DataStorageElement a, Callback c)
		{
			return new DataStorageElement(a, c);
		}

		public static DataStorageElement operator +(DataStorageElement a, AdditionalArgument arg)
		{
			return new DataStorageElement(a, arg);
		}

		public static DataStorageElement operator *(DataStorageElement a, int b)
		{
			return new DataStorageElement(a, OperationType.Mul, JToken.op_Implicit(b));
		}

		public static DataStorageElement operator *(DataStorageElement a, long b)
		{
			return new DataStorageElement(a, OperationType.Mul, JToken.op_Implicit(b));
		}

		public static DataStorageElement operator *(DataStorageElement a, float b)
		{
			return new DataStorageElement(a, OperationType.Mul, JToken.op_Implicit(b));
		}

		public static DataStorageElement operator *(DataStorageElement a, double b)
		{
			return new DataStorageElement(a, OperationType.Mul, JToken.op_Implicit(b));
		}

		public static DataStorageElement operator *(DataStorageElement a, decimal b)
		{
			return new DataStorageElement(a, OperationType.Mul, JToken.op_Implicit(b));
		}

		public static DataStorageElement operator %(DataStorageElement a, int b)
		{
			return new DataStorageElement(a, OperationType.Mod, JToken.op_Implicit(b));
		}

		public static DataStorageElement operator %(DataStorageElement a, long b)
		{
			return new DataStorageElement(a, OperationType.Mod, JToken.op_Implicit(b));
		}

		public static DataStorageElement operator %(DataStorageElement a, float b)
		{
			return new DataStorageElement(a, OperationType.Mod, JToken.op_Implicit(b));
		}

		public static DataStorageElement operator %(DataStorageElement a, double b)
		{
			return new DataStorageElement(a, OperationType.Mod, JToken.op_Implicit(b));
		}

		public static DataStorageElement operator %(DataStorageElement a, decimal b)
		{
			return new DataStorageElement(a, OperationType.Mod, JToken.op_Implicit(b));
		}

		public static DataStorageElement operator ^(DataStorageElement a, int b)
		{
			return new DataStorageElement(a, OperationType.Pow, JToken.op_Implicit(b));
		}

		public static DataStorageElement operator ^(DataStorageElement a, long b)
		{
			return new DataStorageElement(a, OperationType.Pow, JToken.op_Implicit(b));
		}

		public static DataStorageElement operator ^(DataStorageElement a, float b)
		{
			return new DataStorageElement(a, OperationType.Pow, JToken.op_Implicit(b));
		}

		public static DataStorageElement operator ^(DataStorageElement a, double b)
		{
			return new DataStorageElement(a, OperationType.Pow, JToken.op_Implicit(b));
		}

		public static DataStorageElement operator ^(DataStorageElement a, decimal b)
		{
			return new DataStorageElement(a, OperationType.Pow, JToken.op_Implicit(b));
		}

		public static DataStorageElement operator -(DataStorageElement a, int b)
		{
			return new DataStorageElement(a, OperationType.Add, JToken.FromObject((object)(-b)));
		}

		public static DataStorageElement operator -(DataStorageElement a, long b)
		{
			return new DataStorageElement(a, OperationType.Add, JToken.FromObject((object)(-b)));
		}

		public static DataStorageElement operator -(DataStorageElement a, float b)
		{
			return new DataStorageElement(a, OperationType.Add, JToken.FromObject((object)(0f - b)));
		}

		public static DataStorageElement operator -(DataStorageElement a, double b)
		{
			return new DataStorageElement(a, OperationType.Add, JToken.FromObject((object)(0.0 - b)));
		}

		public static DataStorageElement operator -(DataStorageElement a, decimal b)
		{
			return new DataStorageElement(a, OperationType.Add, JToken.FromObject((object)(-b)));
		}

		public static DataStorageElement operator /(DataStorageElement a, int b)
		{
			return new DataStorageElement(a, OperationType.Mul, JToken.FromObject((object)(1m / (decimal)b)));
		}

		public static DataStorageElement operator /(DataStorageElement a, long b)
		{
			return new DataStorageElement(a, OperationType.Mul, JToken.FromObject((object)(1m / (decimal)b)));
		}

		public static DataStorageElement operator /(DataStorageElement a, float b)
		{
			return new DataStorageElement(a, OperationType.Mul, JToken.FromObject((object)(1.0 / (double)b)));
		}

		public static DataStorageElement operator /(DataStorageElement a, double b)
		{
			return new DataStorageElement(a, OperationType.Mul, JToken.FromObject((object)(1.0 / b)));
		}

		public static DataStorageElement operator /(DataStorageElement a, decimal b)
		{
			return new DataStorageElement(a, OperationType.Mul, JToken.FromObject((object)(1m / b)));
		}

		public static implicit operator DataStorageElement(bool b)
		{
			return new DataStorageElement(OperationType.Replace, JToken.op_Implicit(b));
		}

		public static implicit operator DataStorageElement(int i)
		{
			return new DataStorageElement(OperationType.Replace, JToken.op_Implicit(i));
		}

		public static implicit operator DataStorageElement(long l)
		{
			return new DataStorageElement(OperationType.Replace, JToken.op_Implicit(l));
		}

		public static implicit operator DataStorageElement(decimal m)
		{
			return new DataStorageElement(OperationType.Replace, JToken.op_Implicit(m));
		}

		public static implicit operator DataStorageElement(double d)
		{
			return new DataStorageElement(OperationType.Replace, JToken.op_Implicit(d));
		}

		public static implicit operator DataStorageElement(float f)
		{
			return new DataStorageElement(OperationType.Replace, JToken.op_Implicit(f));
		}

		public static implicit operator DataStorageElement(string s)
		{
			if (s != null)
			{
				return new DataStorageElement(OperationType.Replace, JToken.op_Implicit(s));
			}
			return new DataStorageElement(OperationType.Replace, (JToken)(object)JValue.CreateNull());
		}

		public static implicit operator DataStorageElement(JToken o)
		{
			return new DataStorageElement(OperationType.Replace, o);
		}

		public static implicit operator DataStorageElement(Array a)
		{
			return new DataStorageElement(OperationType.Replace, (JToken)(object)JArray.FromObject((object)a));
		}

		public static implicit operator DataStorageElement(List<bool> l)
		{
			return new DataStorageElement(OperationType.Replace, (JToken)(object)JArray.FromObject((object)l));
		}

		public static implicit operator DataStorageElement(List<int> l)
		{
			return new DataStorageElement(OperationType.Replace, (JToken)(object)JArray.FromObject((object)l));
		}

		public static implicit operator DataStorageElement(List<long> l)
		{
			return new DataStorageElement(OperationType.Replace, (JToken)(object)JArray.FromObject((object)l));
		}

		public static implicit operator DataStorageElement(List<decimal> l)
		{
			return new DataStorageElement(OperationType.Replace, (JToken)(object)JArray.FromObject((object)l));
		}

		public static implicit operator DataStorageElement(List<double> l)
		{
			return new DataStorageElement(OperationType.Replace, (JToken)(object)JArray.FromObject((object)l));
		}

		public static implicit operator DataStorageElement(List<float> l)
		{
			return new DataStorageElement(OperationType.Replace, (JToken)(object)JArray.FromObject((object)l));
		}

		public static implicit operator DataStorageElement(List<string> l)
		{
			return new DataStorageElement(OperationType.Replace, (JToken)(object)JArray.FromObject((object)l));
		}

		public static implicit operator DataStorageElement(List<object> l)
		{
			return new DataStorageElement(OperationType.Replace, (JToken)(object)JArray.FromObject((object)l));
		}

		public static implicit operator bool(DataStorageElement e)
		{
			return RetrieveAndReturnBoolValue<bool>(e);
		}

		public static implicit operator bool?(DataStorageElement e)
		{
			return RetrieveAndReturnBoolValue<bool?>(e);
		}

		public static implicit operator int(DataStorageElement e)
		{
			return RetrieveAndReturnDecimalValue<int>(e);
		}

		public static implicit operator int?(DataStorageElement e)
		{
			return RetrieveAndReturnDecimalValue<int?>(e);
		}

		public static implicit operator long(DataStorageElement e)
		{
			return RetrieveAndReturnDecimalValue<long>(e);
		}

		public static implicit operator long?(DataStorageElement e)
		{
			return RetrieveAndReturnDecimalValue<long?>(e);
		}

		public static implicit operator float(DataStorageElement e)
		{
			return RetrieveAndReturnDecimalValue<float>(e);
		}

		public static implicit operator float?(DataStorageElement e)
		{
			return RetrieveAndReturnDecimalValue<float?>(e);
		}

		public static implicit operator double(DataStorageElement e)
		{
			return RetrieveAndReturnDecimalValue<double>(e);
		}

		public static implicit operator double?(DataStorageElement e)
		{
			return RetrieveAndReturnDecimalValue<double?>(e);
		}

		public static implicit operator decimal(DataStorageElement e)
		{
			return RetrieveAndReturnDecimalValue<decimal>(e);
		}

		public static implicit operator decimal?(DataStorageElement e)
		{
			return RetrieveAndReturnDecimalValue<decimal?>(e);
		}

		public static implicit operator string(DataStorageElement e)
		{
			return RetrieveAndReturnStringValue(e);
		}

		public static implicit operator bool[](DataStorageElement e)
		{
			return RetrieveAndReturnArrayValue<bool[]>(e);
		}

		public static implicit operator int[](DataStorageElement e)
		{
			return RetrieveAndReturnArrayValue<int[]>(e);
		}

		public static implicit operator long[](DataStorageElement e)
		{
			return RetrieveAndReturnArrayValue<long[]>(e);
		}

		public static implicit operator decimal[](DataStorageElement e)
		{
			return RetrieveAndReturnArrayValue<decimal[]>(e);
		}

		public static implicit operator double[](DataStorageElement e)
		{
			return RetrieveAndReturnArrayValue<double[]>(e);
		}

		public static implicit operator float[](DataStorageElement e)
		{
			return RetrieveAndReturnArrayValue<float[]>(e);
		}

		public static implicit operator string[](DataStorageElement e)
		{
			return RetrieveAndReturnArrayValue<string[]>(e);
		}

		public static implicit operator object[](DataStorageElement e)
		{
			return RetrieveAndReturnArrayValue<object[]>(e);
		}

		public static implicit operator List<bool>(DataStorageElement e)
		{
			return RetrieveAndReturnArrayValue<List<bool>>(e);
		}

		public static implicit operator List<int>(DataStorageElement e)
		{
			return RetrieveAndReturnArrayValue<List<int>>(e);
		}

		public static implicit operator List<long>(DataStorageElement e)
		{
			return RetrieveAndReturnArrayValue<List<long>>(e);
		}

		public static implicit operator List<decimal>(DataStorageElement e)
		{
			return RetrieveAndReturnArrayValue<List<decimal>>(e);
		}

		public static implicit operator List<double>(DataStorageElement e)
		{
			return RetrieveAndReturnArrayValue<List<double>>(e);
		}

		public static implicit operator List<float>(DataStorageElement e)
		{
			return RetrieveAndReturnArrayValue<List<float>>(e);
		}

		public static implicit operator List<string>(DataStorageElement e)
		{
			return RetrieveAndReturnArrayValue<List<string>>(e);
		}

		public static implicit operator List<object>(DataStorageElement e)
		{
			return RetrieveAndReturnArrayValue<List<object>>(e);
		}

		public static implicit operator Array(DataStorageElement e)
		{
			return RetrieveAndReturnArrayValue<Array>(e);
		}

		public static implicit operator JArray(DataStorageElement e)
		{
			return RetrieveAndReturnArrayValue<JArray>(e);
		}

		public static implicit operator JToken(DataStorageElement e)
		{
			return e.Context.GetData(e.Context.Key);
		}

		public static DataStorageElement operator +(DataStorageElement a, BigInteger b)
		{
			return new DataStorageElement(a, OperationType.Add, JToken.Parse(b.ToString()));
		}

		public static DataStorageElement operator *(DataStorageElement a, BigInteger b)
		{
			return new DataStorageElement(a, OperationType.Mul, JToken.Parse(b.ToString()));
		}

		public static DataStorageElement operator %(DataStorageElement a, BigInteger b)
		{
			return new DataStorageElement(a, OperationType.Mod, JToken.Parse(b.ToString()));
		}

		public static DataStorageElement operator ^(DataStorageElement a, BigInteger b)
		{
			return new DataStorageElement(a, OperationType.Pow, JToken.Parse(b.ToString()));
		}

		public static DataStorageElement operator -(DataStorageElement a, BigInteger b)
		{
			return new DataStorageElement(a, OperationType.Add, JToken.Parse((-b).ToString()));
		}

		public static DataStorageElement operator /(DataStorageElement a, BigInteger b)
		{
			throw new InvalidOperationException("DataStorage[Key] / BigInterger is not supported, due to loss of precision when using integer division");
		}

		public static implicit operator DataStorageElement(BigInteger bi)
		{
			return new DataStorageElement(OperationType.Replace, JToken.Parse(bi.ToString()));
		}

		public static implicit operator BigInteger(DataStorageElement e)
		{
			return RetrieveAndReturnBigIntegerValue<BigInteger>(e);
		}

		public static implicit operator BigInteger?(DataStorageElement e)
		{
			return RetrieveAndReturnBigIntegerValue<BigInteger?>(e);
		}

		private static T RetrieveAndReturnBigIntegerValue<T>(DataStorageElement e)
		{
			if (e.cachedValue != null)
			{
				if (!BigInteger.TryParse(((object)e.cachedValue).ToString(), out var result))
				{
					return default(T);
				}
				return (T)Convert.ChangeType(result, IsNullable<T>() ? Nullable.GetUnderlyingType(typeof(T)) : typeof(T));
			}
			BigInteger result2;
			BigInteger? bigInteger = (BigInteger.TryParse(((object)e.Context.GetData(e.Context.Key)).ToString(), out result2) ? new BigInteger?(result2) : null);
			if (!bigInteger.HasValue && !IsNullable<T>())
			{
				bigInteger = Activator.CreateInstance<BigInteger>();
			}
			foreach (OperationSpecification operation in e.Operations)
			{
				if (operation.OperationType == OperationType.Floor || operation.OperationType == OperationType.Ceil)
				{
					continue;
				}
				if (!BigInteger.TryParse(((object)operation.Value).ToString(), NumberStyles.AllowLeadingSign, null, out var result3))
				{
					throw new InvalidOperationException($"DataStorage[Key] cannot be converted to BigInterger as its value its not an integer number, value: {operation.Value}");
				}
				switch (operation.OperationType)
				{
				case OperationType.Replace:
					bigInteger = result3;
					break;
				case OperationType.Add:
					bigInteger += result3;
					break;
				case OperationType.Mul:
					bigInteger *= result3;
					break;
				case OperationType.Mod:
					bigInteger %= result3;
					break;
				case OperationType.Pow:
					bigInteger = BigInteger.Pow(bigInteger.Value, (int)operation.Value);
					break;
				case OperationType.Max:
				{
					BigInteger value = result3;
					BigInteger? bigInteger2 = bigInteger;
					if (value > bigInteger2)
					{
						bigInteger = result3;
					}
					break;
				}
				case OperationType.Min:
				{
					BigInteger value = result3;
					BigInteger? bigInteger2 = bigInteger;
					if (value < bigInteger2)
					{
						bigInteger = result3;
					}
					break;
				}
				case OperationType.Xor:
					bigInteger ^= result3;
					break;
				case OperationType.Or:
					bigInteger |= result3;
					break;
				case OperationType.And:
					bigInteger &= result3;
					break;
				case OperationType.LeftShift:
					bigInteger <<= (int)operation.Value;
					break;
				case OperationType.RightShift:
					bigInteger >>= (int)operation.Value;
					break;
				}
			}
			e.cachedValue = JToken.Parse(bigInteger.ToString());
			if (!bigInteger.HasValue)
			{
				return default(T);
			}
			return (T)Convert.ChangeType(bigInteger.Value, IsNullable<T>() ? Nullable.GetUnderlyingType(typeof(T)) : typeof(T));
		}

		public void Initialize(JToken value)
		{
			Context.Initialize(Context.Key, value);
		}

		public void Initialize(IEnumerable value)
		{
			Context.Initialize(Context.Key, (JToken)(object)JArray.FromObject((object)value));
		}

		public Task<T> GetAsync<T>()
		{
			return GetAsync().ContinueWith((Task<JToken> r) => r.Result.ToObject<T>());
		}

		public Task<JToken> GetAsync()
		{
			return Context.GetAsync(Context.Key);
		}

		private static T RetrieveAndReturnArrayValue<T>(DataStorageElement e)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Invalid comparison between Unknown and I4
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Invalid comparison between Unknown and I4
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			if (e.cachedValue != null)
			{
				return ((JToken)(JArray)e.cachedValue).ToObject<T>();
			}
			JArray val = (JArray)(((object)e.Context.GetData(e.Context.Key).ToObject<JArray>()) ?? ((object)new JArray()));
			foreach (OperationSpecification operation in e.Operations)
			{
				switch (operation.OperationType)
				{
				case OperationType.Add:
					if ((int)operation.Value.Type != 2)
					{
						throw new InvalidOperationException($"Cannot perform operation {OperationType.Add} on Array value, with a non Array value: {operation.Value}");
					}
					((JContainer)val).Merge((object)operation.Value);
					break;
				case OperationType.Replace:
					if ((int)operation.Value.Type != 2)
					{
						throw new InvalidOperationException($"Cannot replace Array value, with a non Array value: {operation.Value}");
					}
					val = (JArray)(((object)operation.Value.ToObject<JArray>()) ?? ((object)new JArray()));
					break;
				default:
					throw new InvalidOperationException($"Cannot perform operation {operation.OperationType} on Array value");
				}
			}
			e.cachedValue = (JToken)(object)val;
			return ((JToken)val).ToObject<T>();
		}

		private static string RetrieveAndReturnStringValue(DataStorageElement e)
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Invalid comparison between Unknown and I4
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Invalid comparison between Unknown and I4
			if (e.cachedValue != null)
			{
				return (string)e.cachedValue;
			}
			JToken val = e.Context.GetData(e.Context.Key);
			string text = (((int)val.Type == 10) ? null : ((object)val).ToString());
			foreach (OperationSpecification operation in e.Operations)
			{
				switch (operation.OperationType)
				{
				case OperationType.Add:
					text += (string)operation.Value;
					break;
				case OperationType.Mul:
					if ((int)operation.Value.Type != 6)
					{
						throw new InvalidOperationException($"Cannot perform operation {OperationType.Mul} on string value, with a non interger value: {operation.Value}");
					}
					text = string.Concat(Enumerable.Repeat(text, (int)operation.Value));
					break;
				case OperationType.Replace:
					text = (string)operation.Value;
					break;
				default:
					throw new InvalidOperationException($"Cannot perform operation {operation.OperationType} on string value");
				}
			}
			if (text == null)
			{
				e.cachedValue = (JToken)(object)JValue.CreateNull();
			}
			else
			{
				e.cachedValue = JToken.op_Implicit(text);
			}
			return (string)e.cachedValue;
		}

		private static T RetrieveAndReturnBoolValue<T>(DataStorageElement e)
		{
			if (e.cachedValue != null)
			{
				return e.cachedValue.ToObject<T>();
			}
			bool? flag = e.Context.GetData(e.Context.Key).ToObject<bool?>() ?? ((bool?)Activator.CreateInstance(typeof(T)));
			foreach (OperationSpecification operation in e.Operations)
			{
				if (operation.OperationType == OperationType.Replace)
				{
					flag = (bool?)operation.Value;
					continue;
				}
				throw new InvalidOperationException($"Cannot perform operation {operation.OperationType} on boolean value");
			}
			e.cachedValue = JToken.op_Implicit(flag);
			if (!flag.HasValue)
			{
				return default(T);
			}
			return (T)Convert.ChangeType(flag.Value, IsNullable<T>() ? Nullable.GetUnderlyingType(typeof(T)) : typeof(T));
		}

		private static T RetrieveAndReturnDecimalValue<T>(DataStorageElement e)
		{
			if (e.cachedValue != null)
			{
				return e.cachedValue.ToObject<T>();
			}
			decimal? num = e.Context.GetData(e.Context.Key).ToObject<decimal?>();
			if (!num.HasValue && !IsNullable<T>())
			{
				num = Activator.CreateInstance<decimal>();
			}
			foreach (OperationSpecification operation in e.Operations)
			{
				switch (operation.OperationType)
				{
				case OperationType.Replace:
					num = (decimal)operation.Value;
					break;
				case OperationType.Add:
					num += (decimal?)(decimal)operation.Value;
					break;
				case OperationType.Mul:
					num *= (decimal?)(decimal)operation.Value;
					break;
				case OperationType.Mod:
					num %= (decimal?)(decimal)operation.Value;
					break;
				case OperationType.Pow:
					num = (decimal)Math.Pow((double)num.Value, (double)operation.Value);
					break;
				case OperationType.Max:
					num = Math.Max(num.Value, (decimal)operation.Value);
					break;
				case OperationType.Min:
					num = Math.Min(num.Value, (decimal)operation.Value);
					break;
				case OperationType.Xor:
					num = (long)num.Value ^ (long)operation.Value;
					break;
				case OperationType.Or:
					num = (long)num.Value | (long)operation.Value;
					break;
				case OperationType.And:
					num = (long)num.Value & (long)operation.Value;
					break;
				case OperationType.LeftShift:
					num = (long)num.Value << (int)operation.Value;
					break;
				case OperationType.RightShift:
					num = (long)num.Value >> (int)operation.Value;
					break;
				case OperationType.Floor:
					num = Math.Floor(num.Value);
					break;
				case OperationType.Ceil:
					num = Math.Ceiling(num.Value);
					break;
				}
			}
			e.cachedValue = JToken.op_Implicit(num);
			if (!num.HasValue)
			{
				return default(T);
			}
			return (T)Convert.ChangeType(num.Value, IsNullable<T>() ? Nullable.GetUnderlyingType(typeof(T)) : typeof(T));
		}

		private static bool IsNullable<T>()
		{
			if (typeof(T).IsGenericType)
			{
				return typeof(T).GetGenericTypeDefinition() == typeof(Nullable<>).GetGenericTypeDefinition();
			}
			return false;
		}

		public T To<T>()
		{
			if (Operations.Count != 0)
			{
				throw new InvalidOperationException("DataStorageElement.To<T>() cannot be used together with other operations on the DataStorageElement");
			}
			return Context.GetData(Context.Key).ToObject<T>();
		}

		public override string ToString()
		{
			return (Context?.ToString() ?? "(null)") + ", (" + ListOperations() + ")";
		}

		private string ListOperations()
		{
			if (Operations != null)
			{
				return string.Join(", ", Operations.Select((OperationSpecification o) => o.ToString()).ToArray());
			}
			return "none";
		}
	}
	internal class DataStorageElementContext
	{
		internal string Key { get; set; }

		internal Action<string, DataStorageHelper.DataStorageUpdatedHandler> AddHandler { get; set; }

		internal Action<string, DataStorageHelper.DataStorageUpdatedHandler> RemoveHandler { get; set; }

		internal Func<string, JToken> GetData { get; set; }

		internal Action<string, JToken> Initialize { get; set; }

		internal Func<string, Task<JToken>> GetAsync { get; set; }

		public override string ToString()
		{
			return "Key: " + Key;
		}
	}
	public class GameData
	{
		[JsonProperty("location_name_to_id")]
		public Dictionary<string, long> LocationLookup { get; set; } = new Dictionary<string, long>();


		[JsonProperty("item_name_to_id")]
		public Dictionary<string, long> ItemLookup { get; set; } = new Dictionary<string, long>();


		[Obsolete("use Checksum instead")]
		[JsonProperty("version")]
		public int Version { get; set; }

		[JsonProperty("checksum")]
		public string Checksum { get; set; }
	}
	public class Hint
	{
		[JsonProperty("receiving_player")]
		public int ReceivingPlayer { get; set; }

		[JsonProperty("finding_player")]
		public int FindingPlayer { get; set; }

		[JsonProperty("item")]
		public long ItemId { get; set; }

		[JsonProperty("location")]
		public long LocationId { get; set; }

		[JsonProperty("item_flags")]
		public ItemFlags ItemFlags { get; set; }

		[JsonProperty("found")]
		public bool Found { get; set; }

		[JsonProperty("entrance")]
		public string Entrance { get; set; }

		[JsonProperty("status")]
		public HintStatus Status { get; set; }
	}
	public class ItemInfo
	{
		private readonly IItemInfoResolver itemInfoResolver;

		public long ItemId { get; }

		public long LocationId { get; }

		public PlayerInfo Player { get; }

		public ItemFlags Flags { get; }

		public string ItemName => itemInfoResolver.GetItemName(ItemId, ItemGame);

		public string ItemDisplayName => ItemName ?? $"Item: {ItemId}";

		public string LocationName => itemInfoResolver.GetLocationName(LocationId, LocationGame);

		public string LocationDisplayName => LocationName ?? $"Location: {LocationId}";

		public string ItemGame { get; }

		public string LocationGame { get; }

		public ItemInfo(NetworkItem item, string receiverGame, string senderGame, IItemInfoResolver itemInfoResolver, PlayerInfo player)
		{
			this.itemInfoResolver = itemInfoResolver;
			ItemGame = receiverGame;
			LocationGame = senderGame;
			ItemId = item.Item;
			LocationId = item.Location;
			Flags = item.Flags;
			Player = player;
		}

		public SerializableItemInfo ToSerializable()
		{
			return new SerializableItemInfo
			{
				IsScout = (GetType() == typeof(ScoutedItemInfo)),
				ItemId = ItemId,
				LocationId = LocationId,
				PlayerSlot = Player,
				Player = Player,
				Flags = Flags,
				ItemGame = ItemGame,
				ItemName = ItemName,
				LocationGame = LocationGame,
				LocationName = LocationName
			};
		}
	}
	public class ScoutedItemInfo : ItemInfo
	{
		public new PlayerInfo Player => base.Player;

		public bool IsReceiverRelatedToActivePlayer { get; }

		public ScoutedItemInfo(NetworkItem item, string receiverGame, string senderGame, IItemInfoResolver itemInfoResolver, IPlayerHelper players, PlayerInfo player)
			: base(item, receiverGame, senderGame, itemInfoResolver, player)
		{
			IsReceiverRelatedToActivePlayer = (players.ActivePlayer ?? new PlayerInfo()).IsRelatedTo(player);
		}
	}
	public class JsonMessagePart
	{
		[JsonProperty("type")]
		[JsonConverter(typeof(AttemptingStringEnumConverter), new object[] { typeof(SnakeCaseNamingStrategy) })]
		public JsonMessagePartType? Type { get; set; }

		[JsonProperty("color")]
		[JsonConverter(typeof(AttemptingStringEnumConverter), new object[] { typeof(SnakeCaseNamingStrategy) })]
		public JsonMessagePartColor? Color { get; set; }

		[JsonProperty("text")]
		public string Text { get; set; }

		[JsonProperty("player")]
		public int? Player { get; set; }

		[JsonProperty("flags")]
		public ItemFlags? Flags { get; set; }

		[JsonProperty("hint_status")]
		public HintStatus? HintStatus { get; set; }
	}
	public struct NetworkItem
	{
		[JsonProperty("item")]
		public long Item { get; set; }

		[JsonProperty("location")]
		public long Location { get; set; }

		[JsonProperty("player")]
		public int Player { get; set; }

		[JsonProperty("flags")]
		public ItemFlags Flags { get; set; }
	}
	public struct NetworkPlayer
	{
		[JsonProperty("team")]
		public int Team { get; set; }

		[JsonProperty("slot")]
		public int Slot { get; set; }

		[JsonProperty("alias")]
		public string Alias { get; set; }

		[JsonProperty("name")]
		public string Name { get; set; }
	}
	public struct NetworkSlot
	{
		[JsonProperty("name")]
		public string Name { get; set; }

		[JsonProperty("game")]
		public string Game { get; set; }

		[JsonProperty("type")]
		public SlotType Type { get; set; }

		[JsonProperty("group_members")]
		public int[] GroupMembers { get; set; }
	}
	public class NetworkVersion
	{
		[JsonProperty("major")]
		public int Major { get; set; }

		[JsonProperty("minor")]
		public int Minor { get; set; }

		[JsonProperty("build")]
		public int Build { get; set; }

		[JsonProperty("class")]
		public string Class => "Version";

		public NetworkVersion()
		{
		}

		public NetworkVersion(int major, int minor, int build)
		{
			Major = major;
			Minor = minor;
			Build = build;
		}

		public NetworkVersion(Version version)
		{
			Major = version.Major;
			Minor = version.Minor;
			Build = version.Build;
		}

		public Version ToVersion()
		{
			return new Version(Major, Minor, Build);
		}
	}
	public class OperationSpecification
	{
		[JsonProperty("operation")]
		[JsonConverter(typeof(AttemptingStringEnumConverter), new object[] { typeof(SnakeCaseNamingStrategy) })]
		public OperationType OperationType;

		[JsonProperty("value")]
		public JToken Value { get; set; }

		public override string ToString()
		{
			return $"{OperationType}: {Value}";
		}
	}
	public static class Operation
	{
		public static OperationSpecification Min(int i)
		{
			return new OperationSpecification
			{
				OperationType = OperationType.Min,
				Value = JToken.op_Implicit(i)
			};
		}

		public static OperationSpecification Min(long i)
		{
			return new OperationSpecification
			{
				OperationType = OperationType.Min,
				Value = JToken.op_Implicit(i)
			};
		}

		public static OperationSpecification Min(float i)
		{
			return new OperationSpecification
			{
				OperationType = OperationType.Min,
				Value = JToken.op_Implicit(i)
			};
		}

		public static OperationSpecification Min(double i)
		{
			return new OperationSpecification
			{
				OperationType = OperationType.Min,
				Value = JToken.op_Implicit(i)
			};
		}

		public static OperationSpecification Min(decimal i)
		{
			return new OperationSpecification
			{
				OperationType = OperationType.Min,
				Value = JToken.op_Implicit(i)
			};
		}

		public static OperationSpecification Min(JToken i)
		{
			return new OperationSpecification
			{
				OperationType = OperationType.Min,
				Value = i
			};
		}

		public static OperationSpecification Min(BigInteger i)
		{
			return new OperationSpecification
			{
				OperationType = OperationType.Min,
				Value = JToken.Parse(i.ToString())
			};
		}

		public static OperationSpecification Max(int i)
		{
			return new OperationSpecification
			{
				OperationType = OperationType.Max,
				Value = JToken.op_Implicit(i)
			};
		}

		public static OperationSpecification Max(long i)
		{
			return new OperationSpecification
			{
				OperationType = OperationType.Max,
				Value = JToken.op_Implicit(i)
			};
		}

		public static OperationSpecification Max(float i)
		{
			return new OperationSpecification
			{
				OperationType = OperationType.Max,
				Value = JToken.op_Implicit(i)
			};
		}

		public static OperationSpecification Max(double i)
		{
			return new OperationSpecification
			{
				OperationType = OperationType.Max,
				Value = JToken.op_Implicit(i)
			};
		}

		public static OperationSpecification Max(decimal i)
		{
			return new OperationSpecification
			{
				OperationType = OperationType.Max,
				Value = JToken.op_Implicit(i)
			};
		}

		public static OperationSpecification Max(JToken i)
		{
			return new OperationSpecification
			{
				OperationType = OperationType.Max,
				Value = i
			};
		}

		public static OperationSpecification Max(BigInteger i)
		{
			return new OperationSpecification
			{
				OperationType = OperationType.Max,
				Value = JToken.Parse(i.ToString())
			};
		}

		public static OperationSpecification Remove(JToken value)
		{
			return new OperationSpecification
			{
				OperationType = OperationType.Remove,
				Value = value
			};
		}

		public static OperationSpecification Pop(int value)
		{
			return new OperationSpecification
			{
				OperationType = OperationType.Pop,
				Value = JToken.op_Implicit(value)
			};
		}

		public static OperationSpecification Pop(JToken value)
		{
			return new OperationSpecification
			{
				OperationType = OperationType.Pop,
				Value = value
			};
		}

		public static OperationSpecification Update(IDictionary dictionary)
		{
			return new OperationSpecification
			{
				OperationType = OperationType.Update,
				Value = (JToken)(object)JObject.FromObject((object)dictionary)
			};
		}

		public static OperationSpecification Floor()
		{
			return new OperationSpecification
			{
				OperationType = OperationType.Floor,
				Value = null
			};
		}

		public static OperationSpecification Ceiling()
		{
			return new OperationSpecification
			{
				OperationType = OperationType.Ceil,
				Value = null
			};
		}
	}
	public static class Bitwise
	{
		public static OperationSpecification Xor(long i)
		{
			return new OperationSpecification
			{
				OperationType = OperationType.Xor,
				Value = JToken.op_Implicit(i)
			};
		}

		public static OperationSpecification Xor(BigInteger i)
		{
			return new OperationSpecification
			{
				OperationType = OperationType.Xor,
				Value = JToken.Parse(i.ToString())
			};
		}

		public static OperationSpecification Or(long i)
		{
			return new OperationSpecification
			{
				OperationType = OperationType.Or,
				Value = JToken.op_Implicit(i)
			};
		}

		public static OperationSpecification Or(BigInteger i)
		{
			return new OperationSpecification
			{
				OperationType = OperationType.Or,
				Value = JToken.Parse(i.ToString())
			};
		}

		public static OperationSpecification And(long i)
		{
			return new OperationSpecification
			{
				OperationType = OperationType.And,
				Value = JToken.op_Implicit(i)
			};
		}

		public static OperationSpecification And(BigInteger i)
		{
			return new OperationSpecification
			{
				OperationType = OperationType.And,
				Value = JToken.Parse(i.ToString())
			};
		}

		public static OperationSpecification LeftShift(long i)
		{
			return new OperationSpecification
			{
				OperationType = OperationType.LeftShift,
				Value = JToken.op_Implicit(i)
			};
		}

		public static OperationSpecification RightShift(long i)
		{
			return new OperationSpecification
			{
				OperationType = OperationType.RightShift,
				Value = JToken.op_Implicit(i)
			};
		}
	}
	public class Callback
	{
		internal DataStorageHelper.DataStorageUpdatedHandler Method { get; set; }

		private Callback()
		{
		}

		public static Callback Add(DataStorageHelper.DataStorageUpdatedHandler callback)
		{
			return new Callback
			{
				Method = callback
			};
		}
	}
	public class AdditionalArgument
	{
		internal string Key { get; set; }

		internal JToken Value { get; set; }

		private AdditionalArgument()
		{
		}

		public static AdditionalArgument Add(string name, JToken value)
		{
			return new AdditionalArgument
			{
				Key = name,
				Value = value
			};
		}
	}
	public class MinimalSerializableItemInfo
	{
		public long ItemId { get; set; }

		public long LocationId { get; set; }

		public int PlayerSlot { get; set; }

		public ItemFlags Flags { get; set; }

		public string ItemGame { get; set; }

		public string LocationGame { get; set; }
	}
	public class SerializableItemInfo : MinimalSerializableItemInfo
	{
		public bool IsScout { get; set; }

		public PlayerInfo Player { get; set; }

		public string ItemName { get; set; }

		public string LocationName { get; set; }

		[JsonIgnore]
		public string ItemDisplayName => ItemName ?? $"Item: {base.ItemId}";

		[JsonIgnore]
		public string LocationDisplayName => LocationName ?? $"Location: {base.LocationId}";

		public string ToJson(bool full = false)
		{
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Expected O, but got Unknown
			MinimalSerializableItemInfo minimalSerializableItemInfo = this;
			if (!full)
			{
				minimalSerializableItemInfo = new MinimalSerializableItemInfo
				{
					ItemId = base.ItemId,
					LocationId = base.LocationId,
					PlayerSlot = base.PlayerSlot,
					Flags = base.Flags
				};
				if (IsScout)
				{
					minimalSerializableItemInfo.ItemGame = base.ItemGame;
				}
				else
				{
					minimalSerializableItemInfo.LocationGame = base.LocationGame;
				}
			}
			JsonSerializerSettings val = new JsonSerializerSettings
			{
				NullValueHandling = (NullValueHandling)1,
				Formatting = (Formatting)0
			};
			return JsonConvert.SerializeObject((object)minimalSerializableItemInfo, val);
		}

		public static SerializableItemInfo FromJson(string json, IArchipelagoSession session = null)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Expected O, but got Unknown
			ItemInfoStreamingContext additional = ((session != null) ? new ItemInfoStreamingContext
			{
				Items = session.Items,
				Locations = session.Locations,
				PlayerHelper = session.Players,
				ConnectionInfo = session.ConnectionInfo
			} : null);
			JsonSerializerSettings val = new JsonSerializerSettings
			{
				Context = new StreamingContext(StreamingContextStates.Other, additional)
			};
			return JsonConvert.DeserializeObject<SerializableItemInfo>(json, val);
		}

		[OnDeserialized]
		internal void OnDeserializedMethod(StreamingContext streamingContext)
		{
			if (base.ItemGame == null && base.LocationGame != null)
			{
				IsScout = false;
			}
			else if (base.ItemGame != null && base.LocationGame == null)
			{
				IsScout = true;
			}
			if (streamingContext.Context is ItemInfoStreamingContext itemInfoStreamingContext)
			{
				if (IsScout && base.LocationGame == null)
				{
					base.LocationGame = itemInfoStreamingContext.ConnectionInfo.Game;
				}
				else if (!IsScout && base.ItemGame == null)
				{
					base.ItemGame = itemInfoStreamingContext.ConnectionInfo.Game;
				}
				if (ItemName == null)
				{
					ItemName = itemInfoStreamingContext.Items.GetItemName(base.ItemId, base.ItemGame);
				}
				if (LocationName == null)
				{
					LocationName = itemInfoStreamingContext.Locations.GetLocationNameFromId(base.LocationId, base.LocationGame);
				}
				if (Player == null)
				{
					Player = itemInfoStreamingContext.PlayerHelper.GetPlayerInfo(base.PlayerSlot);
				}
			}
		}
	}
	internal class ItemInfoStreamingContext
	{
		public IReceivedItemsHelper Items { get; set; }

		public ILocationCheckHelper Locations { get; set; }

		public IPlayerHelper PlayerHelper { get; set; }

		public IConnectionInfoProvider ConnectionInfo { get; set; }
	}
}
namespace Archipelago.MultiClient.Net.MessageLog.Parts
{
	public class EntranceMessagePart : MessagePart
	{
		internal EntranceMessagePart(JsonMessagePart messagePart)
			: base(MessagePartType.Entrance, messagePart, Archipelago.MultiClient.Net.Colors.PaletteColor.Blue)
		{
			base.Text = messagePart.Text;
		}
	}
	public class HintStatusMessagePart : MessagePart
	{
		internal HintStatusMessagePart(JsonMessagePart messagePart)
			: base(MessagePartType.HintStatus, messagePart)
		{
			base.Text = messagePart.Text;
			if (messagePart.HintStatus.HasValue)
			{
				base.PaletteColor = ColorUtils.GetColor(messagePart.HintStatus.Value);
			}
		}
	}
	public class ItemMessagePart : MessagePart
	{
		public ItemFlags Flags { get; }

		public long ItemId { get; }

		public int Player { get; }

		internal ItemMessagePart(IPlayerHelper players, IItemInfoResolver items, JsonMessagePart part)
			: base(MessagePartType.Item, part)
		{
			Flags = part.Flags.GetValueOrDefault();
			base.PaletteColor = ColorUtils.GetColor(Flags);
			Player = part.Player.GetValueOrDefault();
			string game = (players.GetPlayerInfo(Player) ?? new PlayerInfo()).Game;
			JsonMessagePartType? type = part.Type;
			if (type.HasValue)
			{
				switch (type.GetValueOrDefault())
				{
				case JsonMessagePartType.ItemId:
					ItemId = long.Parse(part.Text);
					base.Text = items.GetItemName(ItemId, game) ?? $"Item: {ItemId}";
					break;
				case JsonMessagePartType.ItemName:
					ItemId = 0L;
					base.Text = part.Text;
					break;
				}
			}
		}
	}
	public class LocationMessagePart : MessagePart
	{
		public long LocationId { get; }

		public int Player { get; }

		internal LocationMessagePart(IPlayerHelper players, IItemInfoResolver itemInfoResolver, JsonMessagePart part)
			: base(MessagePartType.Location, part, Archipelago.MultiClient.Net.Colors.PaletteColor.Green)
		{
			Player = part.Player.GetValueOrDefault();
			string game = (players.GetPlayerInfo(Player) ?? new PlayerInfo()).Game;
			JsonMessagePartType? type = part.Type;
			if (type.HasValue)
			{
				switch (type.GetValueOrDefault())
				{
				case JsonMessagePartType.LocationId:
					LocationId = long.Parse(part.Text);
					base.Text = itemInfoResolver.GetLocationName(LocationId, game) ?? $"Location: {LocationId}";
					break;
				case JsonMessagePartType.LocationName:
					LocationId = itemInfoResolver.GetLocationId(part.Text, game);
					base.Text = part.Text;
					break;
				}
			}
		}
	}
	public class MessagePart
	{
		public string Text { get; internal set; }

		public MessagePartType Type { get; internal set; }

		public Color Color => GetColor(BuiltInPalettes.Dark);

		public PaletteColor? PaletteColor { get; protected set; }

		public bool IsBackgroundColor { get; internal set; }

		internal MessagePart(MessagePartType type, JsonMessagePart messagePart, PaletteColor? color = null)
		{
			Type = type;
			Text = messagePart.Text;
			if (color.HasValue)
			{
				PaletteColor = color.Value;
			}
			else if (messagePart.Color.HasValue)
			{
				PaletteColor = ColorUtils.GetColor(messagePart.Color.Value);
				IsBackgroundColor = messagePart.Color.Value >= JsonMessagePartColor.BlackBg;
			}
			else
			{
				PaletteColor = null;
			}
		}

		public T GetColor<T>(Palette<T> palette)
		{
			return palette[PaletteColor];
		}

		public override string ToString()
		{
			return Text;
		}
	}
	public enum MessagePartType
	{
		Text,
		Player,
		Item,
		Location,
		Entrance,
		HintStatus
	}
	public class PlayerMessagePart : MessagePart
	{
		public bool IsActivePlayer { get; }

		public int SlotId { get; }

		internal PlayerMessagePart(IPlayerHelper players, IConnectionInfoProvider connectionInfo, JsonMessagePart part)
			: base(MessagePartType.Player, part)
		{
			switch (part.Type)
			{
			case JsonMessagePartType.PlayerId:
				SlotId = int.Parse(part.Text);
				IsActivePlayer = SlotId == connectionInfo.Slot;
				base.Text = players.GetPlayerAlias(SlotId) ?? $"Player {SlotId}";
				break;
			case JsonMessagePartType.PlayerName:
				SlotId = 0;
				IsActivePlayer = false;
				base.Text = part.Text;
				break;
			}
			base.PaletteColor = (IsActivePlayer ? Archipelago.MultiClient.Net.Colors.PaletteColor.Magenta : Archipelago.MultiClient.Net.Colors.PaletteColor.Yellow);
		}
	}
}
namespace Archipelago.MultiClient.Net.MessageLog.Messages
{
	public class AdminCommandResultLogMessage : LogMessage
	{
		internal AdminCommandResultLogMessage(MessagePart[] parts)
			: base(parts)
		{
		}
	}
	public class ChatLogMessage : PlayerSpecificLogMessage
	{
		public string Message { get; }

		internal ChatLogMessage(MessagePart[] parts, IPlayerHelper players, int team, int slot, string message)
			: base(parts, players, team, slot)
		{
			Message = message;
		}
	}
	public class CollectLogMessage : PlayerSpecificLogMessage
	{
		internal CollectLogMessage(MessagePart[] parts, IPlayerHelper players, int team, int slot)
			: base(parts, players, team, slot)
		{
		}
	}
	public class CommandResultLogMessage : LogMessage
	{
		internal CommandResultLogMessage(MessagePart[] parts)
			: base(parts)
		{
		}
	}
	public class CountdownLogMessage : LogMessage
	{
		public int RemainingSeconds { get; }

		internal CountdownLogMessage(MessagePart[] parts, int remainingSeconds)
			: base(parts)
		{
			RemainingSeconds = remainingSeconds;
		}
	}
	public class GoalLogMessage : PlayerSpecificLogMessage
	{
		internal GoalLogMessage(MessagePart[] parts, IPlayerHelper players, int team, int slot)
			: base(parts, players, team, slot)
		{
		}
	}
	public class HintItemSendLogMessage : ItemSendLogMessage
	{
		public bool IsFound { get; }

		internal HintItemSendLogMessage(MessagePart[] parts, IPlayerHelper players, int receiver, int sender, NetworkItem item, bool found, IItemInfoResolver itemInfoResolver)
			: base(parts, players, receiver, sender, item, itemInfoResolver)
		{
			IsFound = found;
		}
	}
	public class ItemCheatLogMessage : ItemSendLogMessage
	{
		internal ItemCheatLogMessage(MessagePart[] parts, IPlayerHelper players, int team, int slot, NetworkItem item, IItemInfoResolver itemInfoResolver)
			: base(parts, players, slot, 0, item, team, itemInfoResolver)
		{
		}
	}
	public class ItemSendLogMessage : LogMessage
	{
		private PlayerInfo ActivePlayer { get; }

		public PlayerInfo Receiver { get; }

		public PlayerInfo Sender { get; }

		public bool IsReceiverTheActivePlayer => Receiver == ActivePlayer;

		public bool IsSenderTheActivePlayer => Sender == ActivePlayer;

		public bool IsRelatedToActivePlayer
		{
			get
			{
				if (!ActivePlayer.IsRelatedTo(Receiver))
				{
					return ActivePlayer.IsRelatedTo(Sender);
				}
				return true;
			}
		}

		public ItemInfo Item { get; }

		internal ItemSendLogMessage(MessagePart[] parts, IPlayerHelper players, int receiver, int sender, NetworkItem item, IItemInfoResolver itemInfoResolver)
			: this(parts, players, receiver, sender, item, players.ActivePlayer.Team, itemInfoResolver)
		{
		}

		internal ItemSendLogMessage(MessagePart[] parts, IPlayerHelper players, int receiver, int sender, NetworkItem item, int team, IItemInfoResolver itemInfoResolver)
			: base(parts)
		{
			ActivePlayer = players.ActivePlayer ?? new PlayerInfo();
			Receiver = players.GetPlayerInfo(team, receiver) ?? new PlayerInfo();
			Sender = players.GetPlayerInfo(team, sender) ?? new PlayerInfo();
			PlayerInfo player = players.GetPlayerInfo(team, item.Player) ?? new PlayerInfo();
			Item = new ItemInfo(item, Receiver.Game, Sender.Game, itemInfoResolver, player);
		}
	}
	public class JoinLogMessage : PlayerSpecificLogMessage
	{
		public string[] Tags { get; }

		internal JoinLogMessage(MessagePart[] parts, IPlayerHelper players, int team, int slot, string[] tags)
			: base(parts, players, team, slot)
		{
			Tags = tags;
		}
	}
	public class LeaveLogMessage : PlayerSpecificLogMessage
	{
		internal LeaveLogMessage(MessagePart[] parts, IPlayerHelper players, int team, int slot)
			: base(parts, players, team, slot)
		{
		}
	}
	public class LogMessage
	{
		public MessagePart[] Parts { get; }

		internal LogMessage(MessagePart[] parts)
		{
			Parts = parts;
		}

		public override string ToString()
		{
			if (Parts.Length == 1)
			{
				return Parts[0].Text;
			}
			StringBuilder stringBuilder = new StringBuilder();
			MessagePart[] parts = Parts;
			foreach (MessagePart messagePart in parts)
			{
				stringBuilder.Append(messagePart.Text);
			}
			return stringBuilder.ToString();
		}
	}
	public abstract class PlayerSpecificLogMessage : LogMessage
	{
		private PlayerInfo ActivePlayer { get; }

		public PlayerInfo Player { get; }

		public bool IsActivePlayer => Player == ActivePlayer;

		public bool IsRelatedToActivePlayer => ActivePlayer.IsRelatedTo(Player);

		internal PlayerSpecificLogMessage(MessagePart[] parts, IPlayerHelper players, int team, int slot)
			: base(parts)
		{
			ActivePlayer = players.ActivePlayer ?? new PlayerInfo();
			Player = players.GetPlayerInfo(team, slot) ?? new PlayerInfo();
		}
	}
	public class ReleaseLogMessage : PlayerSpecificLogMessage
	{
		internal ReleaseLogMessage(MessagePart[] parts, IPlayerHelper players, int team, int slot)
			: base(parts, players, team, slot)
		{
		}
	}
	public class ServerChatLogMessage : LogMessage
	{
		public string Message { get; }

		internal ServerChatLogMessage(MessagePart[] parts, string message)
			: base(parts)
		{
			Message = message;
		}
	}
	public class TagsChangedLogMessage : PlayerSpecificLogMessage
	{
		public string[] Tags { get; }

		internal TagsChangedLogMessage(MessagePart[] parts, IPlayerHelper players, int team, int slot, string[] tags)
			: base(parts, players, team, slot)
		{
			Tags = tags;
		}
	}
	public class TutorialLogMessage : LogMessage
	{
		internal TutorialLogMessage(MessagePart[] parts)
			: base(parts)
		{
		}
	}
}
namespace Archipelago.MultiClient.Net.Helpers
{
	public class ArchipelagoSocketHelper : BaseArchipelagoSocketHelper<ClientWebSocket>, IArchipelagoSocketHelper
	{
		public Uri Uri { get; }

		internal ArchipelagoSocketHelper(Uri hostUri)
			: base(CreateWebSocket(), 1024)
		{
			Uri = hostUri;
		}

		private static ClientWebSocket CreateWebSocket()
		{
			return new ClientWebSocket();
		}

		public async Task ConnectAsync()
		{
			await ConnectToProvidedUri(Uri);
			StartPolling();
		}

		private async Task ConnectToProvidedUri(Uri uri)
		{
			if (uri.Scheme != "unspecified")
			{
				try
				{
					await Socket.ConnectAsync(uri, CancellationToken.None);
					return;
				}
				catch (Exception e)
				{
					OnError(e);
					throw;
				}
			}
			List<Exception> errors = new List<Exception>(0);
			try
			{
				await Socket.ConnectAsync(uri.AsWss(), CancellationToken.None);
				if (Socket.State == WebSocketState.Open)
				{
					return;
				}
			}
			catch (Exception item)
			{
				errors.Add(item);
				Socket = CreateWebSocket();
			}
			try
			{
				await Socket.ConnectAsync(uri.AsWs(), CancellationToken.None);
			}
			catch (Exception item2)
			{
				errors.Add(item2);
				OnError(new AggregateException(errors));
				throw;
			}
		}
	}
	public class BaseArchipelagoSocketHelper<T> where T : WebSocket
	{
		private static readonly ArchipelagoPacketConverter Converter = new ArchipelagoPacketConverter();

		private readonly BlockingCollection<Tuple<ArchipelagoPacketBase, TaskCompletionSource<bool>>> sendQueue = new BlockingCollection<Tuple<ArchipelagoPacketBase, TaskCompletionSource<bool>>>();

		internal T Socket;

		private readonly int bufferSize;

		public bool Connected
		{
			get
			{
				if (Socket.State != WebSocketState.Open)
				{
					return Socket.State == WebSocketState.CloseReceived;
				}
				return true;
			}
		}

		public event ArchipelagoSocketHelperDelagates.PacketReceivedHandler PacketReceived;

		public event ArchipelagoSocketHelperDelagates.PacketsSentHandler PacketsSent;

		public event ArchipelagoSocketHelperDelagates.ErrorReceivedHandler ErrorReceived;

		public event ArchipelagoSocketHelperDelagates.SocketClosedHandler SocketClosed;

		public event ArchipelagoSocketHelperDelagates.SocketOpenedHandler SocketOpened;

		internal BaseArchipelagoSocketHelper(T socket, int bufferSize = 1024)
		{
			Socket = socket;
			this.bufferSize = bufferSize;
		}

		internal void StartPolling()
		{
			if (this.SocketOpened != null)
			{
				this.SocketOpened();
			}
			Task.Run((Func<Task?>)PollingLoop);
			Task.Run((Func<Task?>)SendLoop);
		}

		private async Task PollingLoop()
		{
			byte[] buffer = new byte[bufferSize];
			while (Socket.State == WebSocketState.Open)
			{
				string message = null;
				try
				{
					message = await ReadMessageAsync(buffer);
				}
				catch (Exception e)
				{
					OnError(e);
				}
				OnMessageReceived(message);
			}
		}

		private async Task SendLoop()
		{
			while (Socket.State == WebSocketState.Open)
			{
				try
				{
					await HandleSendBuffer();
				}
				catch (Exception e)
				{
					OnError(e);
				}
				await Task.Delay(20);
			}
		}

		private async Task<string> ReadMessageAsync(byte[] buffer)
		{
			using MemoryStream readStream = new MemoryStream(buffer.Length);
			WebSocketReceiveResult result;
			do
			{
				result = await Socket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
				if (result.MessageType == WebSocketMessageType.Close)
				{
					try
					{
						await Socket.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty, CancellationToken.None);
					}
					catch
					{
					}
					OnSocketClosed();
				}
				else
				{
					readStream.Write(buffer, 0, result.Count);
				}
			}
			while (!result.EndOfMessage);
			return Encoding.UTF8.GetString(readStream.ToArray());
		}

		public async Task DisconnectAsync()
		{
			await Socket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Closure requested by client", CancellationToken.None);
			OnSocketClosed();
		}

		public void SendPacket(ArchipelagoPacketBase packet)
		{
			SendMultiplePackets(new List<ArchipelagoPacketBase> { packet });
		}

		public void SendMultiplePackets(List<ArchipelagoPacketBase> packets)
		{
			SendMultiplePackets(packets.ToArray());
		}

		public void SendMultiplePackets(params ArchipelagoPacketBase[] packets)
		{
			SendMultiplePacketsAsync(packets).Wait();
		}

		public Task SendPacketAsync(ArchipelagoPacketBase packet)
		{
			return SendMultiplePacketsAsync(new List<ArchipelagoPacketBase> { packet });
		}

		public Task SendMultiplePacketsAsync(List<ArchipelagoPacketBase> packets)
		{
			return SendMultiplePacketsAsync(packets.ToArray());
		}

		public Task SendMultiplePacketsAsync(params ArchipelagoPacketBase[] packets)
		{
			TaskCompletionSource<bool> taskCompletionSource = new TaskCompletionSource<bool>();
			foreach (ArchipelagoPacketBase item in packets)
			{
				sendQueue.Add(new Tuple<ArchipelagoPacketBase, TaskCompletionSource<bool>>(item, taskCompletionSource));
			}
			return taskCompletionSource.Task;
		}

		private async Task HandleSendBuffer()
		{
			List<ArchipelagoPacketBase> list = new List<ArchipelagoPacketBase>();
			List<TaskCompletionSource<bool>> tasks = new List<TaskCompletionSource<bool>>();
			Tuple<ArchipelagoPacketBase, TaskCompletionSource<bool>> tuple = sendQueue.Take();
			list.Add(tuple.Item1);
			tasks.Add(tuple.Item2);
			Tuple<ArchipelagoPacketBase, TaskCompletionSource<bool>> item;
			while (sendQueue.TryTake(out item))
			{
				list.Add(item.Item1);
				tasks.Add(item.Item2);
			}
			if (!list.Any())
			{
				return;
			}
			if (Socket.State != WebSocketState.Open)
			{
				throw new ArchipelagoSocketClosedException();
			}
			ArchipelagoPacketBase[] packets = list.ToArray();
			string s = JsonConvert.SerializeObject((object)packets);
			byte[] messageBuffer = Encoding.UTF8.GetBytes(s);
			int messagesCount = (int)Math.Ceiling((double)messageBuffer.Length / (double)bufferSize);
			for (int i = 0; i < messagesCount; i++)
			{
				int num = bufferSize * i;
				int num2 = bufferSize;
				bool endOfMessage = i + 1 == messagesCount;
				if (num2 * (i + 1) > messageBuffer.Length)
				{
					num2 = messageBuffer.Length - num;
				}
				await Socket.SendAsync(new ArraySegment<byte>(messageBuffer, num, num2), WebSocketMessageType.Text, endOfMessage, CancellationToken.None);
			}
			foreach (TaskCompletionSource<bool> item2 in tasks)
			{
				item2.TrySetResult(result: true);
			}
			OnPacketSend(packets);
		}

		private void OnPacketSend(ArchipelagoPacketBase[] packets)
		{
			try
			{
				if (this.PacketsSent != null)
				{
					this.PacketsSent(packets);
				}
			}
			catch (Exception e)
			{
				OnError(e);
			}
		}

		private void OnSocketClosed()
		{
			try
			{
				if (this.SocketClosed != null)
				{
					this.SocketClosed("");
				}
			}
			catch (Exception e)
			{
				OnError(e);
			}
		}

		private void OnMessageReceived(string message)
		{
			try
			{
				if (string.IsNullOrEmpty(message) || this.PacketReceived == null)
				{
					return;
				}
				List<ArchipelagoPacketBase> list = null;
				try
				{
					list = JsonConvert.DeserializeObject<List<ArchipelagoPacketBase>>(message, (JsonConverter[])(object)new JsonConverter[1] { Converter });
				}
				catch (Exception e)
				{
					OnError(e);
				}
				if (list == null)
				{
					return;
				}
				foreach (ArchipelagoPacketBase item in list)
				{
					this.PacketReceived(item);
				}
			}
			catch (Exception e2)
			{
				OnError(e2);
			}
		}

		protected void OnError(Exception e)
		{
			try
			{
				if (this.ErrorReceived != null)
				{
					this.ErrorReceived(e, e.Message);
				}
			}
			catch (Exception ex)
			{
				Console.Out.WriteLine("Error occured during reporting of errorOuter Errror: " + e.Message + " " + e.StackTrace + "Inner Errror: " + ex.Message + " " + ex.StackTrace);
			}
		}
	}
	public interface IConnectionInfoProvider
	{
		string Game { get; }

		int Team { get; }

		int Slot { get; }

		string[] Tags { get; }

		ItemsHandlingFlags ItemsHandlingFlags { get; }

		string Uuid { get; }

		void UpdateConnectionOptions(string[] tags);

		void UpdateConnectionOptions(ItemsHandlingFlags itemsHandlingFlags);

		void UpdateConnectionOptions(string[] tags, ItemsHandlingFlags itemsHandlingFlags);
	}
	public class ConnectionInfoHelper : IConnectionInfoProvider
	{
		private readonly IArchipelagoSocketHelper socket;

		public string Game { get; private set; }

		public int Team { get; private set; }

		public int Slot { get; private set; }

		public string[] Tags { get; internal set; }

		public ItemsHandlingFlags ItemsHandlingFlags { get; internal set; }

		public string Uuid { get; private set; }

		internal ConnectionInfoHelper(IArchipelagoSocketHelper socket)
		{
			this.socket = socket;
			Reset();
			socket.PacketReceived += PacketReceived;
		}

		private void PacketReceived(ArchipelagoPacketBase packet)
		{
			if (!(packet is ConnectedPacket connectedPacket))
			{
				if (packet is ConnectionRefusedPacket)
				{
					Reset();
				}
				return;
			}
			Team = connectedPacket.Team;
			Slot = connectedPacket.Slot;
			if (connectedPacket.SlotInfo != null && connectedPacket.SlotInfo.ContainsKey(Slot))
			{
				Game = connectedPacket.SlotInfo[Slot].Game;
			}
		}

		internal void SetConnectionParameters(string game, string[] tags, ItemsHandlingFlags itemsHandlingFlags, string uuid)
		{
			Game = game;
			Tags = tags ?? new string[0];
			ItemsHandlingFlags = itemsHandlingFlags;
			Uuid = uuid ?? Guid.NewGuid().ToString();
		}

		private void Reset()
		{
			Game = null;
			Team = -1;
			Slot = -1;
			Tags = new string[0];
			ItemsHandlingFlags = ItemsHandlingFlags.NoItems;
			Uuid = null;
		}

		public void UpdateConnectionOptions(string[] tags)
		{
			UpdateConnectionOptions(tags, ItemsHandlingFlags);
		}

		public void UpdateConnectionOptions(ItemsHandlingFlags itemsHandlingFlags)
		{
			UpdateConnectionOptions(Tags, ItemsHandlingFlags);
		}

		public void UpdateConnectionOptions(string[] tags, ItemsHandlingFlags itemsHandlingFlags)
		{
			SetConnectionParameters(Game, tags, itemsHandlingFlags, Uuid);
			socket.SendPacket(new ConnectUpdatePacket
			{
				Tags = Tags,
				ItemsHandling = ItemsHandlingFlags
			});
		}
	}
	public interface IDataStorageHelper : IDataStorageWrapper
	{
		DataStorageElement this[Scope scope, string key] { get; set; }

		DataStorageElement this[string key] { get; set; }
	}
	public class DataStorageHelper : IDataStorageHelper, IDataStorageWrapper
	{
		public delegate void DataStorageUpdatedHandler(JToken originalValue, JToken newValue, Dictionary<string, JToken> additionalArguments);

		private readonly Dictionary<string, DataStorageUpdatedHandler> onValueChangedEventHandlers = new Dictionary<string, DataStorageUpdatedHandler>();

		private readonly Dictionary<Guid, DataStorageUpdatedHandler> operationSpecificCallbacks = new Dictionary<Guid, DataStorageUpdatedHandler>();

		private readonly Dictionary<string, TaskCompletionSource<JToken>> asyncRetrievalTasks = new Dictionary<string, TaskCompletionSource<JToken>>();

		private readonly IArchipelagoSocketHelper socket;

		private readonly IConnectionInfoProvider connectionInfoProvider;

		public DataStorageElement this[Scope scope, string key]
		{
			get
			{
				return this[AddScope(scope, key)];
			}
			set
			{
				this[AddScope(scope, key)] = value;
			}
		}

		public DataStorageElement this[string key]
		{
			get
			{
				return new DataStorageElement(GetContextForKey(key));
			}
			set
			{
				SetValue(key, value);
			}
		}

		internal DataStorageHelper(IArchipelagoSocketHelper socket, IConnectionInfoProvider connectionInfoProvider)
		{
			this.socket = socket;
			this.connectionInfoProvider = connectionInfoProvider;
			socket.PacketReceived += OnPacketReceived;
		}

		private void OnPacketReceived(ArchipelagoPacketBase packet)
		{
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Invalid comparison between Unknown and I4
			if (!(packet is RetrievedPacket retrievedPacket))
			{
				if (packet is SetReplyPacket setReplyPacket)
				{
					if (setReplyPacket.AdditionalArguments != null && setReplyPacket.AdditionalArguments.ContainsKey("Reference") && (int)setReplyPacket.AdditionalArguments["Reference"].Type == 8 && ((string)setReplyPacket.AdditionalArguments["Reference"]).TryParseNGuid(out var g) && operationSpecificCallbacks.TryGetValue(g, out var value))
					{
						value(setReplyPacket.OriginalValue, setReplyPacket.Value, setReplyPacket.AdditionalArguments);
						operationSpecificCallbacks.Remove(g);
					}
					if (onValueChangedEventHandlers.TryGetValue(setReplyPacket.Key, out var value2))
					{
						value2(setReplyPacket.OriginalValue, setReplyPacket.Value, setReplyPacket.AdditionalArguments);
					}
				}
				return;
			}
			foreach (KeyValuePair<string, JToken> datum in retrievedPacket.Data)
			{
				if (asyncRetrievalTasks.TryGetValue(datum.Key, out var value3))
				{
					value3.TrySetResult(datum.Value);
					asyncRetrievalTasks.Remove(datum.Key);
				}
			}
		}

		private Task<JToken> GetAsync(string key)
		{
			if (asyncRetrievalTasks.TryGetValue(key, out var value))
			{
				return value.Task;
			}
			TaskCompletionSource<JToken> taskCompletionSource = new TaskCompletionSource<JToken>();
			asyncRetrievalTasks[key] = taskCompletionSource;
			socket.SendPacketAsync(new GetPacket
			{
				Keys = new string[1] { key }
			});
			return taskCompletionSource.Task;
		}

		private void Initialize(string key, JToken value)
		{
			socket.SendPacketAsync(new SetPacket
			{
				Key = key,
				DefaultValue = value,
				Operations = new OperationSpecification[1]
				{
					new OperationSpecification
					{
						OperationType = OperationType.Default
					}
				}
			});
		}

		private JToken GetValue(string key)
		{
			Task<JToken> async = GetAsync(key);
			if (!async.Wait(TimeSpan.FromSeconds(2.0)))
			{
				throw new TimeoutException("Timed out retrieving data for key `" + key + "`. This may be due to an attempt to retrieve a value from the DataStorageHelper in a synchronous fashion from within a PacketReceived handler. When using the DataStorageHelper from within code which runs on the websocket thread then use the asynchronous getters. Ex: `DataStorageHelper[\"" + key + "\"].GetAsync().ContinueWith(x => {});`Be aware that DataStorageHelper calls tend to cause packet responses, so making a call from within a PacketReceived handler may cause an infinite loop.");
			}
			return async.Result;
		}

		private void SetValue(string key, DataStorageElement e)
		{
			if (key.StartsWith("_read_"))
			{
				throw new InvalidOperationException("DataStorage write operation on readonly key '" + key + "' is not allowed");
			}
			if (e == null)
			{
				e = new DataStorageElement(OperationType.Replace, (JToken)(object)JValue.CreateNull());
			}
			if (e.Context == null)
			{
				e.Context = GetContextForKey(key);
			}
			else if (e.Context.Key != key)
			{
				e.Operations.Insert(0, new OperationSpecification
				{
					OperationType = OperationType.Replace,
					Value = GetValue(e.Context.Key)
				});
			}
			Dictionary<string, JToken> dictionary = e.AdditionalArguments ?? new Dictionary<string, JToken>(0);
			if (e.Callbacks != null)
			{
				Guid key2 = Guid.NewGuid();
				operationSpecificCallbacks[key2] = e.Callbacks;
				dictionary["Reference"] = JToken.op_Implicit(key2.ToString("N"));
				socket.SendPacketAsync(new SetPacket
				{
					Key = key,
					Operations = e.Operations.ToArray(),
					WantReply = true,
					AdditionalArguments = dictionary
				});
			}
			else
			{
				socket.SendPacketAsync(new SetPacket
				{
					Key = key,
					Operations = e.Operations.ToArray(),
					AdditionalArguments = dictionary
				});
			}
		}

		private DataStorageElementContext GetContextForKey(string key)
		{
			return new DataStorageElementContext
			{
				Key = key,
				GetData = GetValue,
				GetAsync = GetAsync,
				Initialize = Initialize,
				AddHandler = AddHandler,
				RemoveHandler = RemoveHandler
			};
		}

		private void AddHandler(string key, DataStorageUpdatedHandler handler)
		{
			if (onValueChangedEventHandlers.ContainsKey(key))
			{
				Dictionary<string, DataStorageUpdatedHandler> dictionary = onValueChangedEventHandlers;
				dictionary[key] = (DataStorageUpdatedHandler)Delegate.Combine(dictionary[key], handler);
			}
			else
			{
				onValueChangedEventHandlers[key] = handler;
			}
			socket.SendPacketAsync(new SetNotifyPacket
			{
				Keys = new string[1] { key }
			});
		}

		private void RemoveHandler(string key, DataStorageUpdatedHandler handler)
		{
			if (onValueChangedEventHandlers.ContainsKey(key))
			{
				Dictionary<string, DataStorageUpdatedHandler> dictionary = onValueChangedEventHandlers;
				dictionary[key] = (DataStorageUpdatedHandler)Delegate.Remove(dictionary[key], handler);
				if (onValueChangedEventHandlers[key] == null)
				{
					onValueChangedEventHandlers.Remove(key);
				}
			}
		}

		private string AddScope(Scope scope, string key)
		{
			return scope switch
			{
				Scope.Global => key, 
				Scope.Game => $"{scope}:{connectionInfoProvider.Game}:{key}", 
				Scope.Team => $"{scope}:{connectionInfoProvider.Team}:{key}", 
				Scope.Slot => $"{scope}:{connectionInfoProvider.Slot}:{key}", 
				Scope.ReadOnly => "_read_" + key, 
				_ => throw new ArgumentOutOfRangeException("scope", scope, "Invalid scope for key " + key), 
			};
		}

		private DataStorageElement GetHintsElement(int? slot = null, int? team = null)
		{
			return this[Scope.ReadOnly, $"hints_{team ?? connectionInfoProvider.Team}_{slot ?? connectionInfoProvider.Slot}"];
		}

		private DataStorageElement GetSlotDataElement(int? slot = null)
		{
			return this[Scope.ReadOnly, $"slot_data_{slot ?? connectionInfoProvider.Slot}"];
		}

		private DataStorageElement GetItemNameGroupsElement(string game = null)
		{
			return this[Scope.ReadOnly, "item_name_groups_" + (game ?? connectionInfoProvider.Game)];
		}

		private DataStorageElement GetLocationNameGroupsElement(string game = null)
		{
			return this[Scope.ReadOnly, "location_name_groups_" + (game ?? connectionInfoProvider.Game)];
		}

		private DataStorageElement GetClientStatusElement(int? slot = null, int? team = null)
		{
			return this[Scope.ReadOnly, $"client_status_{team ?? connectionInfoProvider.Team}_{slot ?? connectionInfoProvider.Slot}"];
		}

		private DataStorageElement GetRaceModeElement()
		{
			return this[Scope.ReadOnly, "race_mode"];
		}

		public Hint[] GetHints(int? slot = null, int? team = null)
		{
			return GetHintsElement(slot, team).To<Hint[]>();
		}

		public Task<Hint[]> GetHintsAsync(int? slot = null, int? team = null)
		{
			return GetHintsElement(slot, team).GetAsync<Hint[]>();
		}

		public void TrackHints(Action<Hint[]> onHintsUpdated, bool retrieveCurrentlyUnlockedHints = true, int? slot = null, int? team = null)
		{
			GetHintsElement(slot, team).OnValueChanged += delegate(JToken _, JToken newValue, Dictionary<string, JToken> x)
			{
				onHintsUpdated(newValue.ToObject<Hint[]>());
			};
			if (retrieveCurrentlyUnlockedHints)
			{
				GetHintsAsync(slot, team).ContinueWith(delegate(Task<Hint[]> t)
				{
					onHintsUpdated(t.Result);
				});
			}
		}

		public Dictionary<string, object> GetSlotData(int? slot = null)
		{
			return GetSlotData<Dictionary<string, object>>(slot);
		}

		public T GetSlotData<T>(int? slot = null) where T : class
		{
			return GetSlotDataElement(slot).To<T>();
		}

		public Task<Dictionary<string, object>> GetSlotDataAsync(int? slot = null)
		{
			return GetSlotDataAsync<Dictionary<string, object>>(slot);
		}

		public Task<T> GetSlotDataAsync<T>(int? slot = null) where T : class
		{
			return GetSlotDataElement(slot).GetAsync<T>();
		}

		public Dictionary<string, string[]> GetItemNameGroups(string game = null)
		{
			return GetItemNameGroupsElement(game).To<Dictionary<string, string[]>>();
		}

		public Task<Dictionary<string, string[]>> GetItemNameGroupsAsync(string game = null)
		{
			return GetItemNameGroupsElement(game).GetAsync<Dictionary<string, string[]>>();
		}

		public Dictionary<string, string[]> GetLocationNameGroups(string game = null)
		{
			return GetLocationNameGroupsElement(game).To<Dictionary<string, string[]>>();
		}

		public Task<Dictionary<string, string[]>> GetLocationNameGroupsAsync(string game = null)
		{
			return GetLocationNameGroupsElement(game).GetAsync<Dictionary<string, string[]>>();
		}

		public ArchipelagoClientState GetClientStatus(int? slot = null, int? team = null)
		{
			return GetClientStatusElement(slot, team).To<ArchipelagoClientState?>().GetValueOrDefault();
		}

		public Task<ArchipelagoClientState> GetClientStatusAsync(int? slot = null, int? team = null)
		{
			return GetClientStatusElement(slot, team).GetAsync<ArchipelagoClientState?>().ContinueWith((Task<ArchipelagoClientState?> r) => r.Result.GetValueOrDefault());
		}

		public void TrackClientStatus(Action<ArchipelagoClientState> onStatusUpdated, bool retrieveCurrentClientStatus = true, int? slot = null, int? team = null)
		{
			GetClientStatusElement(slot, team).OnValueChanged += delegate(JToken _, JToken newValue, Dictionary<string, JToken> x)
			{
				onStatusUpdated(newValue.ToObject<ArchipelagoClientState>());
	

HotLavaArchipelagoPlugin.dll

Decompiled a day ago
using System;
using System.CodeDom.Compiler;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Threading.Tasks;
using Archipelago.MultiClient.Net;
using Archipelago.MultiClient.Net.BounceFeatures.DeathLink;
using Archipelago.MultiClient.Net.Enums;
using Archipelago.MultiClient.Net.Helpers;
using Archipelago.MultiClient.Net.MessageLog.Messages;
using Archipelago.MultiClient.Net.MessageLog.Parts;
using Archipelago.MultiClient.Net.Models;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using HotLavaArchipelagoPlugin.Archipelago;
using HotLavaArchipelagoPlugin.Archipelago.Data;
using HotLavaArchipelagoPlugin.Archipelago.Models.Items;
using HotLavaArchipelagoPlugin.Archipelago.Models.Items.Cosmetic;
using HotLavaArchipelagoPlugin.Archipelago.Models.Items.Filler;
using HotLavaArchipelagoPlugin.Archipelago.Models.Items.Progression;
using HotLavaArchipelagoPlugin.Archipelago.Models.Items.Traps;
using HotLavaArchipelagoPlugin.Archipelago.Models.Locations;
using HotLavaArchipelagoPlugin.Archipelago.Models.Options;
using HotLavaArchipelagoPlugin.Enums;
using HotLavaArchipelagoPlugin.Extensions;
using HotLavaArchipelagoPlugin.Factories;
using HotLavaArchipelagoPlugin.GameData;
using HotLavaArchipelagoPlugin.Gameplay.Modifiers;
using HotLavaArchipelagoPlugin.Helpers;
using HotLavaArchipelagoPlugin.Models.Game;
using HotLavaArchipelagoPlugin.Properties;
using Klei.HotLava;
using Klei.HotLava.Audio;
using Klei.HotLava.Character;
using Klei.HotLava.Character.Modifiers;
using Klei.HotLava.Character.Progression;
using Klei.HotLava.Enums;
using Klei.HotLava.Game;
using Klei.HotLava.Gameplay;
using Klei.HotLava.Inventory;
using Klei.HotLava.Online;
using Klei.HotLava.Profiles;
using Klei.HotLava.Rewards;
using Klei.HotLava.Settings;
using Klei.HotLava.UI;
using Klei.HotLava.Unlockables;
using Klei.L10n;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using STRINGS;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("HotLavaArchipelagoPlugin")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.0.3.0")]
[assembly: AssemblyInformationalVersion("0.0.3+9d45e0ac44d8fd716bd08e335980dea0d3876466")]
[assembly: AssemblyProduct("Hot Lava Archipelago Plugin")]
[assembly: AssemblyTitle("HotLavaArchipelagoPlugin")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.3.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
[CompilerGenerated]
internal sealed class <>z__ReadOnlyArray<T> : IEnumerable, ICollection, IList, IEnumerable<T>, IReadOnlyCollection<T>, IReadOnlyList<T>, ICollection<T>, IList<T>
{
	int ICollection.Count => _items.Length;

	bool ICollection.IsSynchronized => false;

	object ICollection.SyncRoot => this;

	object IList.this[int index]
	{
		get
		{
			return _items[index];
		}
		set
		{
			throw new NotSupportedException();
		}
	}

	bool IList.IsFixedSize => true;

	bool IList.IsReadOnly => true;

	int IReadOnlyCollection<T>.Count => _items.Length;

	T IReadOnlyList<T>.this[int index] => _items[index];

	int ICollection<T>.Count => _items.Length;

	bool ICollection<T>.IsReadOnly => true;

	T IList<T>.this[int index]
	{
		get
		{
			return _items[index];
		}
		set
		{
			throw new NotSupportedException();
		}
	}

	public <>z__ReadOnlyArray(T[] items)
	{
		_items = items;
	}

	IEnumerator IEnumerable.GetEnumerator()
	{
		return ((IEnumerable)_items).GetEnumerator();
	}

	void ICollection.CopyTo(Array array, int index)
	{
		((ICollection)_items).CopyTo(array, index);
	}

	int IList.Add(object value)
	{
		throw new NotSupportedException();
	}

	void IList.Clear()
	{
		throw new NotSupportedException();
	}

	bool IList.Contains(object value)
	{
		return ((IList)_items).Contains(value);
	}

	int IList.IndexOf(object value)
	{
		return ((IList)_items).IndexOf(value);
	}

	void IList.Insert(int index, object value)
	{
		throw new NotSupportedException();
	}

	void IList.Remove(object value)
	{
		throw new NotSupportedException();
	}

	void IList.RemoveAt(int index)
	{
		throw new NotSupportedException();
	}

	IEnumerator<T> IEnumerable<T>.GetEnumerator()
	{
		return ((IEnumerable<T>)_items).GetEnumerator();
	}

	void ICollection<T>.Add(T item)
	{
		throw new NotSupportedException();
	}

	void ICollection<T>.Clear()
	{
		throw new NotSupportedException();
	}

	bool ICollection<T>.Contains(T item)
	{
		return ((ICollection<T>)_items).Contains(item);
	}

	void ICollection<T>.CopyTo(T[] array, int arrayIndex)
	{
		((ICollection<T>)_items).CopyTo(array, arrayIndex);
	}

	bool ICollection<T>.Remove(T item)
	{
		throw new NotSupportedException();
	}

	int IList<T>.IndexOf(T item)
	{
		return ((IList<T>)_items).IndexOf(item);
	}

	void IList<T>.Insert(int index, T item)
	{
		throw new NotSupportedException();
	}

	void IList<T>.RemoveAt(int index)
	{
		throw new NotSupportedException();
	}
}
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[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;
		}
	}
}
internal sealed class ConfigurationManagerAttributes
{
	public delegate void CustomHotkeyDrawerFunc(ConfigEntryBase setting, ref bool isCurrentlyAcceptingInput);

	public bool? ShowRangeAsPercent;

	public Action<ConfigEntryBase> CustomDrawer;

	public CustomHotkeyDrawerFunc CustomHotkeyDrawer;

	public bool? Browsable;

	public string Category;

	public object DefaultValue;

	public bool? HideDefaultButton;

	public bool? HideSettingName;

	public string Description;

	public string DispName;

	public int? Order;

	public bool? ReadOnly;

	public bool? IsAdvanced;

	public Func<object, string> ObjToStr;

	public Func<string, object> StrToObj;
}
namespace Archipelago.MultiClient.Net
{
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, Inherited = false, AllowMultiple = false)]
	internal sealed class DataStoragePropertyAttribute : Attribute
	{
		public string? SessionVariable { get; }

		public Scope Scope { get; }

		public string Key { get; }

		public DataStoragePropertyAttribute(string sessionVariable, Scope scope, string key)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			SessionVariable = sessionVariable;
			Scope = scope;
			Key = key;
		}

		public DataStoragePropertyAttribute(string sessionVariable, string key)
			: this(sessionVariable, (Scope)0, key)
		{
		}
	}
}
namespace HotLavaArchipelagoPlugin
{
	[BepInPlugin("HotLavaArchipelagoPlugin", "Hot Lava Archipelago Plugin", "0.0.3")]
	public class Plugin : BaseUnityPlugin
	{
		internal static ManualLogSource Logger = new ManualLogSource(string.Empty);

		public static ConfigEntry<string> ConfigArchipelagoHost;

		public static ConfigEntry<int> ConfigArchipelagoPort;

		public static ConfigEntry<string> ConfigArchipelagoPlayerName;

		public static ConfigEntry<string> ConfigArchipelagoPassword;

		internal async Task Awake()
		{
			Logger = ((BaseUnityPlugin)this).Logger;
			Logger.LogInfo((object)"Plugin HotLavaArchipelagoPlugin is loaded!");
			Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), (string)null);
			Logger.LogInfo((object)"Harmony patches applied!");
			ConfigArchipelagoHost = ((BaseUnityPlugin)this).Config.Bind<string>("Archipelago", "Host", "archipelago.gg", new ConfigDescription("The host name of the Archipelago server", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 4
				}
			}));
			ConfigArchipelagoPort = ((BaseUnityPlugin)this).Config.Bind<int>("Archipelago", "Port", 38281, new ConfigDescription("The port for the Archipelago server", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 3
				}
			}));
			ConfigArchipelagoPlayerName = ((BaseUnityPlugin)this).Config.Bind<string>("Archipelago", "PlayerName", "Player", new ConfigDescription("Your slot name in your YAML file", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 2
				}
			}));
			ConfigArchipelagoPassword = ((BaseUnityPlugin)this).Config.Bind<string>("Archipelago", "Password", string.Empty, new ConfigDescription("The password for connecting to the server, if one is required", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 1
				}
			}));
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "HotLavaArchipelagoPlugin";

		public const string PLUGIN_NAME = "Hot Lava Archipelago Plugin";

		public const string PLUGIN_VERSION = "0.0.3";
	}
}
namespace HotLavaArchipelagoPlugin.Properties
{
	[GeneratedCode("System.Resources.Tools.StronglyTypedResourceBuilder", "18.0.0.0")]
	[DebuggerNonUserCode]
	[CompilerGenerated]
	internal class Resources
	{
		private static ResourceManager resourceMan;

		private static CultureInfo resourceCulture;

		[EditorBrowsable(EditorBrowsableState.Advanced)]
		internal static ResourceManager ResourceManager
		{
			get
			{
				if (resourceMan == null)
				{
					resourceMan = new ResourceManager("HotLavaArchipelagoPlugin.Properties.Resources", typeof(Resources).Assembly);
				}
				return resourceMan;
			}
		}

		[EditorBrowsable(EditorBrowsableState.Advanced)]
		internal static CultureInfo Culture
		{
			get
			{
				return resourceCulture;
			}
			set
			{
				resourceCulture = value;
			}
		}

		internal static byte[] ArchipelagoLogo => (byte[])ResourceManager.GetObject("ArchipelagoLogo", resourceCulture);

		internal static byte[] BoostJump => (byte[])ResourceManager.GetObject("BoostJump", resourceCulture);

		internal static byte[] Climb => (byte[])ResourceManager.GetObject("Climb", resourceCulture);

		internal static byte[] Crouch => (byte[])ResourceManager.GetObject("Crouch", resourceCulture);

		internal static byte[] DoubleJump => (byte[])ResourceManager.GetObject("DoubleJump", resourceCulture);

		internal static byte[] ForceField => (byte[])ResourceManager.GetObject("ForceField", resourceCulture);

		internal static byte[] Grab => (byte[])ResourceManager.GetObject("Grab", resourceCulture);

		internal static byte[] Jetpack => (byte[])ResourceManager.GetObject("Jetpack", resourceCulture);

		internal static byte[] Pogo => (byte[])ResourceManager.GetObject("Pogo", resourceCulture);

		internal static byte[] SlideJump => (byte[])ResourceManager.GetObject("SlideJump", resourceCulture);

		internal static byte[] Surf => (byte[])ResourceManager.GetObject("Surf", resourceCulture);

		internal static byte[] Swing => (byte[])ResourceManager.GetObject("Swing", resourceCulture);

		internal static byte[] TinyToy => (byte[])ResourceManager.GetObject("TinyToy", resourceCulture);

		internal static byte[] VaultJump => (byte[])ResourceManager.GetObject("VaultJump", resourceCulture);

		internal static byte[] WallJump => (byte[])ResourceManager.GetObject("WallJump", resourceCulture);

		internal static byte[] XPShard => (byte[])ResourceManager.GetObject("XPShard", resourceCulture);

		internal Resources()
		{
		}
	}
}
namespace HotLavaArchipelagoPlugin.Patches.Unlockables
{
	[HarmonyPatch(typeof(Statistics))]
	internal class StatisticsPatches
	{
		[HarmonyPatch("UnlockUnlockable")]
		[HarmonyPostfix]
		public static void UnlockUnlockable_PostFix(Unlockable unlockable, bool display)
		{
			Plugin.Logger.LogInfo((object)("Unlocking: " + ((object)unlockable).ToString()));
			if (!Multiworld.Connected)
			{
				return;
			}
			Location unlockableLocation = Locations.GetUnlockableLocation(unlockable.m_Key.m_Value);
			if (unlockableLocation != null && !Multiworld.HasCheckedLocation(unlockableLocation))
			{
				Plugin.Logger.LogInfo((object)("Sending AP Check for: " + unlockableLocation.LocationID));
				Multiworld.Instance.SendLocationCheck(unlockableLocation.LocationID);
				ScoutedItemInfo itemForLocation = Multiworld.Instance.GetItemForLocation(unlockableLocation.LocationID);
				if (itemForLocation != null)
				{
					Plugin.Logger.LogInfo((object)("Queueing scouted itme: " + ((ItemInfo)itemForLocation).ItemDisplayName));
					Multiworld.Instance.QueueAwardItem(itemForLocation);
				}
			}
		}

		[HarmonyPatch("HasUnlockedUnlockable")]
		[HarmonyPrefix]
		public static bool HasUnlockedUnlockable_PreFix(Unlockable unlockable, ref bool __result)
		{
			if (Multiworld.Connected)
			{
				Location unlockableLocation = Locations.GetUnlockableLocation(unlockable.m_Key.m_Value);
				if (unlockableLocation != null)
				{
					__result = Multiworld.HasCheckedLocation(unlockableLocation);
					return false;
				}
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(Unlockable))]
	internal class UnlockablePatches
	{
	}
}
namespace HotLavaArchipelagoPlugin.Patches.UI
{
	[HarmonyPatch(typeof(AwardsScreen))]
	internal class AwardsScreenPatches
	{
		[HarmonyPatch("DisplayAwards_Internal")]
		[HarmonyPrefix]
		public static bool DisplayAwards_Internal_Prefix(AwardsScreen __instance)
		{
			if (Multiworld.Connected)
			{
				try
				{
					ScoutedItemInfo val = Multiworld.Instance.PopAwardsQueue();
					if (val == null)
					{
						typeof(AwardsScreen).GetMethod("NoAward", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(__instance, Array.Empty<object>());
						return false;
					}
					string value = "Found Item";
					RewardVisualization rewardVisualization = null;
					if (val.IsReceiverRelatedToActivePlayer)
					{
						Item item = Items.GetItem(((ItemInfo)val).ItemId);
						if (item != null)
						{
							rewardVisualization = item.GetRewardVisualization(__instance.m_GiftDropData);
						}
					}
					if (rewardVisualization == null)
					{
						rewardVisualization = RewardVisualizationFactory.GetArchipelagoReward(__instance.m_GiftDropData);
					}
					rewardVisualization.m_ScratchDescription = ((ItemInfo)val).ItemDisplayName + " for " + val.Player.Name + " (" + ((ItemInfo)val).ItemGame + ")";
					typeof(AwardsScreen).GetField("m_UnlockTitle", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(__instance, value);
					typeof(AwardsScreen).GetMethod("Award", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(__instance, new object[1] { (Func<RewardVisualization>)(() => rewardVisualization) });
					return false;
				}
				catch (Exception ex)
				{
					Plugin.Logger.LogError((object)ex.ToString());
					return false;
				}
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(CharacterSelectIcon))]
	internal class CharacterSelectIconPatches
	{
		[HarmonyPatch("Set")]
		[HarmonyPostfix]
		public static void Set_Postfix(CharacterSelectIcon __instance)
		{
			CharacterSelectIcon __instance2 = __instance;
			if (!Multiworld.Connected)
			{
				return;
			}
			CharacterItem characterItem = Items.CharacterItems.FirstOrDefault((CharacterItem c) => c.CharacterId == __instance2.m_Character.CharacterEnum);
			if (characterItem != null)
			{
				bool flag = Multiworld.HasReceivedItem(characterItem);
				if (!flag)
				{
					__instance2.m_LockedText.text = "LOCKED";
					__instance2.m_LockedText.fontSize = 12;
				}
				__instance2.m_Locked.gameObject.SetActive(!flag);
				((Selectable)((Component)__instance2).GetComponent<Button>()).interactable = flag;
			}
		}
	}
	[HarmonyPatch(typeof(GiftDropVisualization))]
	internal class GiftDropVisualizationPatches
	{
	}
	[HarmonyPatch]
	internal class LevelWidgetContinueGamePatches
	{
		public static MethodInfo TargetMethod()
		{
			return AccessTools.Method("Klei.HotLava.UI.LevelWidget:ContinueGame", (Type[])null, (Type[])null);
		}

		public static bool Prefix(object __instance)
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Expected O, but got Unknown
			if (Multiworld.Connected && !(bool)AccessTools.Method("Klei.HotLava.Continue.Serialization:HasContinueFile", (Type[])null, (Type[])null).Invoke(null, Array.Empty<object>()))
			{
				FieldInfo field = typeof(Data).GetField("s_PlayerStatistics", BindingFlags.Static | BindingFlags.NonPublic);
				PlayerStatistics playerStatistics = (PlayerStatistics)field.GetValue(null);
				WorldInfo worldInfo = Worlds.AllWorlds.FirstOrDefault((WorldInfo w) => w.InternalName == playerStatistics.m_LastKleiLevel);
				if (worldInfo != null && !Multiworld.HasReceivedItem(worldInfo.ItemId))
				{
					WorldSelect startWorld = Multiworld.Instance.SlotData.StartWorld;
					WorldInfo worldInfo2 = Worlds.AllWorlds.FirstOrDefault((WorldInfo w) => w.WorldOptionId == startWorld);
					if (worldInfo2 == null)
					{
						return true;
					}
					Singleton<GameSystem>.Instance.RequestLoadLevel(worldInfo2.InternalName);
					return false;
				}
			}
			return true;
		}
	}
	[HarmonyPatch]
	internal class LevelWidgetPopulateCoursesPatches
	{
		public static MethodInfo TargetMethod()
		{
			return AccessTools.Method("Klei.HotLava.UI.LevelWidget:PopulateCourses", (Type[])null, (Type[])null);
		}

		public static bool Prefix(object __instance, ref LevelMetaData level, ref sbyte course_index)
		{
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Expected O, but got Unknown
			if (Multiworld.Connected)
			{
				string levelName = level.GetWorldName();
				WorldInfo worldInfo = Worlds.AllWorlds.FirstOrDefault((WorldInfo w) => w.InternalName == levelName);
				Plugin.Logger.LogInfo((object)("Checking if player has world: " + levelName));
				if (worldInfo != null && !Multiworld.HasReceivedItem(worldInfo.ItemId))
				{
					WorldSelect startWorld = Multiworld.Instance.SlotData.StartWorld;
					WorldInfo worldInfo2 = Worlds.AllWorlds.FirstOrDefault((WorldInfo w) => w.WorldOptionId == startWorld);
					if (worldInfo2 == null)
					{
						return true;
					}
					LevelMetaData val = (LevelMetaData)typeof(Info).GetMethod("GetLevelMetaData", BindingFlags.Static | BindingFlags.NonPublic).Invoke(null, new object[1] { worldInfo2.InternalName });
					if ((Object)(object)val != (Object)null)
					{
						level = val;
						course_index = -1;
					}
				}
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(PauseMenu))]
	internal class PauseMenuPatches
	{
		[HarmonyPatch("InitializeCardPanels")]
		[HarmonyPostfix]
		public static void InitializeCardPanels_Postfix(PauseMenu __instance)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			((Component)__instance.m_TargetCardPanel).gameObject.transform.position = new Vector3(2400f, 46.66663f, 0f);
		}
	}
	[HarmonyPatch(typeof(WorldInfoLevelSelect))]
	internal class WorldInfoLevelSelectPatches
	{
		[HarmonyPatch("SetLocked")]
		[HarmonyPrefix]
		public static void SetLocked_Prefix(WorldInfoLevelSelect __instance, ref LockState locked, ref string info_text)
		{
			FieldInfo field = ((object)__instance).GetType().GetField("m_LevelName", BindingFlags.Instance | BindingFlags.NonPublic);
			string levelName = (string)field.GetValue(__instance);
			if (Multiworld.Connected)
			{
				WorldUnlockItem worldUnlockItem = Items.GetItems<WorldUnlockItem>().FirstOrDefault((WorldUnlockItem m) => m.InternalName == levelName);
				if (worldUnlockItem != null && Multiworld.HasReceivedItem(worldUnlockItem))
				{
					locked = (LockState)0;
					info_text = string.Empty;
				}
				else
				{
					locked = (LockState)1;
					info_text = "  Locked ";
				}
			}
		}
	}
}
namespace HotLavaArchipelagoPlugin.Patches.Game
{
	[HarmonyPatch(typeof(CollectibleForLevel))]
	internal class CollectibleForLevelPatches
	{
		[HarmonyPatch("OnEnable")]
		[HarmonyPrefix]
		public static bool OnEnable_Prefix(CollectibleForLevel __instance)
		{
			if (Multiworld.Connected && (Object)(object)__instance.m_Unlockable != (Object)null && Locations.GetUnlockableLocation(__instance.m_Unlockable.m_Key.m_Value) is StarLocation starLocation)
			{
				if (starLocation.StarType != StarType.GoldenPin)
				{
					_ = starLocation.StarType;
					_ = 6;
				}
				((TypeMaskObject)__instance).m_XRayMode = true;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(Data))]
	internal class DataPatches
	{
		[HarmonyPatch("CanUserPlayLevel")]
		[HarmonyPrefix]
		public static bool CanUserPlayLevel_Prefix(Data __instance, int index, ref bool __result)
		{
			__result = true;
			return false;
		}
	}
	[HarmonyPatch(typeof(GameModeCompletedGate))]
	internal class GameModeCompletedGatePatches
	{
		private static long Counter;

		[HarmonyPatch("UpdateRequirements")]
		[HarmonyPrefix]
		public static bool UpdateRequirements_Prefix(GameModeCompletedGate __instance)
		{
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			GameModeCompletedGate __instance2 = __instance;
			long num = Counter++;
			LevelMetaData currentLevel = LevelHelper.GetCurrentLevelMetaData();
			ManualLogSource logger = Plugin.Logger;
			string text = num.ToString();
			LevelMetaData obj = currentLevel;
			logger.LogInfo((object)("[" + text + "] World: " + ((obj != null) ? ((Object)obj).name.Replace("_meta_data", "") : null)));
			Plugin.Logger.LogInfo((object)("[" + num + "] Name: " + ((Object)__instance2).name));
			Plugin.Logger.LogInfo((object)("[" + num + "] Position: " + ((Component)__instance2).transform.position.x + ", " + ((Component)__instance2).transform.position.y + ", " + ((Component)__instance2).transform.position.z));
			GameModeContainer[] requiredGameModes = __instance2.m_RequiredGameModes;
			foreach (GameModeContainer val in requiredGameModes)
			{
				ManualLogSource logger2 = Plugin.Logger;
				string text2 = num.ToString();
				LevelMetaData obj2 = currentLevel;
				logger2.LogInfo((object)("[" + text2 + "] Level: " + ((obj2 != null) ? obj2.GetTranslatedName(val.m_GameMode) : null)));
			}
			if (Multiworld.Connected)
			{
				if (Multiworld.Instance.SlotData.ForceFieldLogicOption == ForceFieldLogicOption.Disabled)
				{
					((CompletionGate)__instance2).OnEnableConditionsMet(true);
					return false;
				}
				if (Multiworld.Instance.SlotData.ForceFieldLogicOption == ForceFieldLogicOption.Item)
				{
					ForceFieldItem forceFieldItem = Items.GetItems<ForceFieldItem>().FirstOrDefault((ForceFieldItem m) => m.InternalWorldName == currentLevel?.GetWorldName() && m.Position == ((Component)__instance2).transform.position);
					if (forceFieldItem != null)
					{
						bool flag = Multiworld.HasReceivedItem(forceFieldItem);
						__instance2.ClearList();
						GameModeCompletedRequirement val2 = Object.Instantiate<GameModeCompletedRequirement>(__instance2.m_RequirementTemplate, ((Component)__instance2.m_RequirementsList).transform);
						val2.m_GameModeName.text = "Unlock via Archipelago";
						((Selectable)val2.m_RequirementIcon).interactable = flag;
						((Component)val2).gameObject.SetActive(true);
						((List<GameModeCompletedRequirement>)typeof(GameModeCompletedGate).GetField("m_Rows", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(__instance2)).Add(val2);
						((CompletionGate)__instance2).OnEnableConditionsMet(flag);
					}
					else
					{
						((CompletionGate)__instance2).OnEnableConditionsMet(true);
					}
					return false;
				}
				return true;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(GameModeTweak))]
	internal class GameModeTweakPatches
	{
		[HarmonyPatch("IsUnlocked")]
		[HarmonyPrefix]
		public static bool IsUnlocked_Prefix(ref bool __result)
		{
			__result = true;
			return false;
		}
	}
	[HarmonyPatch(typeof(Highlightable))]
	internal class HighlightablePatches
	{
		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		[HarmonyPrefix]
		public static void Highlight_Prefix(Highlightable __instance, ref bool value)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Invalid comparison between Unknown and I4
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Invalid comparison between Unknown and I4
			if (!Multiworld.Connected)
			{
				return;
			}
			Handhold val = (Handhold)(object)((__instance is Handhold) ? __instance : null);
			if (val != null)
			{
				if ((int)val.m_Type == 1 || (int)val.m_Type == 2)
				{
					value &= Multiworld.HasReceivedItem(Items.Swing);
				}
				else
				{
					value &= Multiworld.HasReceivedItem(Items.Climb);
				}
			}
			else if (((Object)__instance).name != null && ((Object)__instance).name.Contains("surf", StringComparison.OrdinalIgnoreCase))
			{
				value &= Multiworld.HasReceivedItem(Items.Surf);
			}
		}
	}
	[HarmonyPatch(typeof(HotLavaGameContainer))]
	internal class HotLavaGameContainerPatches
	{
		[HarmonyPatch("OnKilled")]
		[HarmonyPrefix]
		public static void OnKilled_Postfix(PlayerController __instance, OnKilledInfo on_killed_info)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			Plugin.Logger.LogInfo((object)("Player died because: " + ((object)(eDeathReason)(ref on_killed_info.m_Reason)).ToString()));
			if (Multiworld.Connected)
			{
				string reason = DEATH_REASON.GetReason(on_killed_info.m_Reason);
				if (on_killed_info.m_Player.IsMine && reason.Contains("%playera"))
				{
					reason = reason.Replace("%playera", Multiworld.Instance.PlayerName).Trim();
					Multiworld.Instance.SendDeath(reason);
				}
			}
		}

		[HarmonyPatch("IsGameModeUnlocked")]
		[HarmonyPrefix]
		public static bool IsGameModeUnlocked_Prefix(GameMode course, ref bool __result)
		{
			if (Multiworld.Connected)
			{
				if (course.Modifier is PogoStickModifier)
				{
					__result = Multiworld.HasReceivedItem(Items.Pogo);
				}
				else if (course.Modifier is TinyToyModifier)
				{
					__result = Multiworld.HasReceivedItem(Items.TinyToy);
				}
				else if (course.Modifier is HoverModifier)
				{
					__result = Multiworld.HasReceivedItem(Items.Jetpack);
				}
				else
				{
					__result = true;
				}
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(LevelSingleton))]
	internal class LevelSingletonPatches
	{
		[HarmonyPatch("SendChatMessage")]
		[HarmonyPrefix]
		public static bool SendChatMessage_Prefix(LevelSingleton __instance, string message, object target)
		{
			string message2 = message;
			if (message2.StartsWith("/apconnect"))
			{
				Task.Run(() => Multiworld.Connect(message2)).GetAwaiter().GetResult();
				return false;
			}
			if (Multiworld.Connected)
			{
				Multiworld.Instance.ArchipelagoSession.Say(message2);
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(ObjectPool))]
	internal class ObjectPoolPatches
	{
	}
	[HarmonyPatch(typeof(SeasonalDateManager))]
	internal class SeasonalDateManagerPatches
	{
	}
}
namespace HotLavaArchipelagoPlugin.Patches.Gameplay
{
	[HarmonyPatch]
	internal class HotPotatoPatches
	{
		public static MethodInfo TargetMethod()
		{
			return AccessTools.Method("Klei.HotLava.Gameplay.HotPotato:Awake", (Type[])null, (Type[])null);
		}

		public static bool Prefix(object __instance)
		{
			Plugin.Logger.LogInfo((object)"Loaded Hot Potato");
			return true;
		}
	}
}
namespace HotLavaArchipelagoPlugin.Patches.Character
{
	[HarmonyPatch(typeof(CharacterModifierData))]
	internal class CharacterModifierDataPatches
	{
		[HarmonyPatch("Load")]
		[HarmonyPrefix]
		public static bool Load_Prefix()
		{
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Expected O, but got Unknown
			FieldInfo field = typeof(CharacterModifierData).GetField("s_Instance", BindingFlags.Static | BindingFlags.NonPublic);
			CharacterModifierData val = Resources.Load<CharacterModifierData>("Characters/character_modifier_data");
			FieldInfo field2 = typeof(CharacterModifierData).GetField("m_Modifiers", BindingFlags.Instance | BindingFlags.NonPublic);
			Array array = (Array)field2.GetValue(val);
			object value = array.GetValue(array.Length - 1);
			FieldInfo field3 = value.GetType().GetField("m_Modifier", BindingFlags.Instance | BindingFlags.NonPublic);
			AbilityRandomizerModifier value2 = ScriptableObject.CreateInstance<AbilityRandomizerModifier>();
			for (int i = 0; i < array.Length; i++)
			{
				PlayerControllerModifier val2 = (PlayerControllerModifier)field3.GetValue(array.GetValue(i));
				LungeModifier val3 = (LungeModifier)(object)((val2 is LungeModifier) ? val2 : null);
				if (val3 != null)
				{
					AbilityRandomizerModifier.LungeModifier = val3;
					continue;
				}
				DoubleJumpModifier val4 = (DoubleJumpModifier)(object)((val2 is DoubleJumpModifier) ? val2 : null);
				if (val4 != null)
				{
					AbilityRandomizerModifier.DoubleJumpModifier = val4;
					continue;
				}
				SlideJumpModifier val5 = (SlideJumpModifier)(object)((val2 is SlideJumpModifier) ? val2 : null);
				if (val5 != null)
				{
					AbilityRandomizerModifier.SlideJumpModifier = val5;
				}
			}
			field3.SetValue(value, value2);
			value.GetType().GetField("m_Icon", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(value, SpriteFactory.GetArchipelagoSprite());
			Array array2 = Array.CreateInstance(value.GetType(), array.Length + 1);
			for (int j = 0; j < array.Length; j++)
			{
				array2.SetValue(array.GetValue(j), j);
			}
			array2.SetValue(value, array.Length);
			field2.SetValue(val, array2);
			field.SetValue(null, val);
			return false;
		}
	}
	[HarmonyPatch(typeof(Climber))]
	internal class ClimberPatches
	{
		[HarmonyPatch("AttachHandhold")]
		[HarmonyPrefix]
		public static bool AttachHandhold_Prefix(Climber __instance, Vector3 contact_point, Handhold handhold)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Invalid comparison between Unknown and I4
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Invalid comparison between Unknown and I4
			if (Multiworld.Connected)
			{
				if ((int)handhold.m_Type == 1 || (int)handhold.m_Type == 2)
				{
					return Multiworld.HasReceivedItem(Items.Swing);
				}
				return Multiworld.HasReceivedItem(Items.Climb);
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(ItemGrabber))]
	internal class ItemGrabberPatches
	{
		[HarmonyPatch("StartGrab")]
		[HarmonyPrefix]
		public static bool StartGrab_Prefix()
		{
			if (Multiworld.Connected && !Multiworld.HasReceivedItem(Items.Grab))
			{
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(PlayerController))]
	internal class PlayerControllerPatches
	{
		[HarmonyPatch("StartCrouching")]
		[HarmonyTranspiler]
		public static IEnumerable<CodeInstruction> StartCrouching_Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0019: 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_0042: Expected O, but got Unknown
			MethodInfo methodInfo = AccessTools.Method(typeof(PlayerControllerPatches), "CanSlide", (Type[])null, (Type[])null);
			return new CodeMatcher(instructions, (ILGenerator)null).MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
			{
				new CodeMatch((OpCode?)OpCodes.Isinst, (object)typeof(SlideJumpModifier), (string)null)
			}).Set(OpCodes.Call, (object)methodInfo).InstructionEnumeration();
		}

		public static bool CanSlide(PlayerControllerModifier modifier)
		{
			bool flag = modifier is SlideJumpModifier || modifier is AbilityRandomizerModifier;
			if (flag && Multiworld.Connected)
			{
				flag &= Multiworld.HasReceivedItem(Items.SlideJump);
			}
			return flag;
		}
	}
	[HarmonyPatch(typeof(Player))]
	internal class PlayerPatches
	{
		private static PlayerControllerModifier _modifier = (PlayerControllerModifier)new LavaBounceModifier();
	}
	[HarmonyPatch(typeof(PlayerRigAnimator))]
	internal class PlayerRigAnimatorPatches
	{
	}
}
namespace HotLavaArchipelagoPlugin.Patches.Character.Modifiers
{
	[HarmonyPatch(typeof(DoubleJumpModifier))]
	internal class DoubleJumpModifierPatches
	{
		[HarmonyPatch("Update")]
		[HarmonyPrefix]
		public static bool Update_Prefix()
		{
			if (Multiworld.Connected)
			{
				return Multiworld.HasReceivedItem(Items.DoubleJump);
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(LungeModifier))]
	internal class LungeModifierPatches
	{
		[HarmonyPatch("FixedUpdate")]
		[HarmonyPrefix]
		public static bool FixedUpdate_Prefix()
		{
			if (Multiworld.Connected)
			{
				return Multiworld.HasReceivedItem(Items.VaultJump);
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(PlayerControllerModifier))]
	internal class PlayerControllerModifierPatches
	{
		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		[HarmonyPrefix]
		public static bool MovesetName_Prefix(PlayerControllerModifier __instance, ref string __result)
		{
			if (__instance is AbilityRandomizerModifier)
			{
				__result = "Ability Randomizer";
				return false;
			}
			return true;
		}

		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		[HarmonyPrefix]
		public static bool MovesetDescription_Prefix(PlayerControllerModifier __instance, ref string __result)
		{
			if (__instance is AbilityRandomizerModifier)
			{
				__result = "Unlock abilities by completing location checks";
				return false;
			}
			return true;
		}

		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		[HarmonyPrefix]
		public static bool CanBhop_Prefix(PlayerControllerModifier __instance, ref bool __result)
		{
			if (__instance is AbilityRandomizerModifier || __instance is DefaultPlayerControllerModifier)
			{
				__result = !Multiworld.Connected || Multiworld.HasReceivedItem(Items.BoostJump);
				return false;
			}
			return true;
		}

		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		[HarmonyPrefix]
		public static bool CanCrouch_Prefix(PlayerControllerModifier __instance, ref bool __result)
		{
			if (Multiworld.Connected)
			{
				__result = Multiworld.HasReceivedItem(Items.Crouch);
				return false;
			}
			return true;
		}

		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		[HarmonyPrefix]
		public static bool CanSurf_Prefix(PlayerControllerModifier __instance, ref bool __result)
		{
			if (Multiworld.Connected)
			{
				__result = Multiworld.HasReceivedItem(Items.Surf);
				return false;
			}
			return true;
		}

		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		[HarmonyPrefix]
		public static bool CanWallRun_Prefix(PlayerControllerModifier __instance, ref bool __result)
		{
			if (Multiworld.Connected)
			{
				__result = Multiworld.HasReceivedItem(Items.WallJump);
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(SlideJumpModifier))]
	internal class SlideJumpModifierPatches
	{
		[HarmonyPatch("FixedUpdate")]
		[HarmonyTranspiler]
		public static IEnumerable<CodeInstruction> FixedUpdate_Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0019: 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_0042: Expected O, but got Unknown
			MethodInfo methodInfo = AccessTools.Method(typeof(SlideJumpModifierPatches), "GetForwardVelocityMultiplier", (Type[])null, (Type[])null);
			return new CodeMatcher(instructions, (ILGenerator)null).MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
			{
				new CodeMatch((OpCode?)OpCodes.Ldc_R4, (object)0.85f, (string)null)
			}).Set(OpCodes.Call, (object)methodInfo).InstructionEnumeration();
		}

		[HarmonyPatch("FixedUpdate")]
		[HarmonyPrefix]
		public static bool FixedUpdate_Prefix()
		{
			if (Multiworld.Connected)
			{
				return Multiworld.HasReceivedItem(Items.SlideJump);
			}
			return true;
		}

		public static float GetForwardVelocityMultiplier()
		{
			PlayerController localPlayer = HotLavaPlayerHelper.GetLocalPlayer();
			float result = 0.85f;
			if ((Object)(object)localPlayer == (Object)null)
			{
				return result;
			}
			if (Multiworld.Connected && localPlayer.Modifier is AbilityRandomizerModifier && Multiworld.HasReceivedItem(Items.SlideJump))
			{
				result = 1f;
			}
			return result;
		}
	}
}
namespace HotLavaArchipelagoPlugin.Models.Game
{
	internal class CourseInfo
	{
		[JsonIgnore]
		public static CourseInfo Default => new CourseInfo(string.Empty, Array.Empty<StarInfo>());

		[JsonIgnore]
		public WorldInfo World { get; set; } = WorldInfo.Default;


		public string Name { get; }

		public CourseType CourseType { get; }

		public StarInfo[] Stars { get; set; }

		public CourseInfo(string name, StarInfo[] stars)
			: this(name, CourseType.Standard, stars)
		{
		}

		public CourseInfo(string name, CourseType courseType, StarInfo[] stars)
		{
			Name = name;
			CourseType = courseType;
			Stars = stars;
			for (int i = 0; i < stars.Length; i++)
			{
				stars[i].Course = this;
			}
		}
	}
	internal class ForceFieldInfo
	{
		[JsonIgnore]
		public WorldInfo World = WorldInfo.Default;

		public long ItemId { get; set; }

		public string Name { get; }

		[JsonIgnore]
		public Vector3 Position { get; }

		public ForceFieldInfo(long itemId, string name, Vector3 position)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			ItemId = itemId;
			Name = name;
			Position = position;
		}
	}
	internal class StarInfo
	{
		[JsonIgnore]
		public CourseInfo Course { get; set; } = CourseInfo.Default;


		public long LocationId { get; set; }

		[JsonIgnore]
		public string UnlockableId { get; }

		public string Name { get; }

		public StarType StarType { get; }

		public StarInfo(long locationId, string unlockableId, string name, StarType starType = StarType.Generic)
		{
			LocationId = locationId;
			UnlockableId = unlockableId;
			Name = name;
			StarType = starType;
		}

		public override string ToString()
		{
			return Course.World.Name + " - " + Course.Name + " - " + Name;
		}
	}
	internal class WorldInfo
	{
		private ForceFieldInfo[] _forceFields = Array.Empty<ForceFieldInfo>();

		private ForceFieldInfo[] _disabledForceFields = Array.Empty<ForceFieldInfo>();

		[JsonIgnore]
		public static WorldInfo Default => new WorldInfo((WorldSelect)(-1), -1, string.Empty, string.Empty, string.Empty, Array.Empty<CourseInfo>());

		public WorldSelect WorldOptionId { get; }

		public long ItemId { get; set; }

		[JsonIgnore]
		public string UnlockableId { get; set; }

		[JsonIgnore]
		public string InternalName { get; set; }

		public string Name { get; }

		public CourseInfo[] Courses { get; }

		public ForceFieldInfo[] ForceFields
		{
			get
			{
				return _forceFields;
			}
			set
			{
				for (int i = 0; i < value.Length; i++)
				{
					value[i].World = this;
				}
				_forceFields = value;
			}
		}

		public ForceFieldInfo[] DisabledForceFields
		{
			get
			{
				return _disabledForceFields;
			}
			set
			{
				for (int i = 0; i < value.Length; i++)
				{
					value[i].World = this;
				}
				_disabledForceFields = value;
			}
		}

		public WorldInfo(WorldSelect worldOptionId, int itemId, string unlockableId, string internalName, string name, CourseInfo[] courses)
		{
			WorldOptionId = worldOptionId;
			ItemId = itemId;
			UnlockableId = unlockableId;
			InternalName = internalName;
			Name = name;
			Courses = courses;
			CourseInfo[] courses2 = Courses;
			for (int i = 0; i < courses2.Length; i++)
			{
				courses2[i].World = this;
			}
		}
	}
}
namespace HotLavaArchipelagoPlugin.Helpers
{
	internal static class HotLavaPlayerHelper
	{
		public static PlayerController? GetLocalPlayer()
		{
			return State.LocalPlayer;
		}

		public static void KillLocalPlayer()
		{
			PlayerController localPlayer = GetLocalPlayer();
			if ((Object)(object)localPlayer != (Object)null)
			{
				localPlayer.BroadcastKilled((eDeathReason)39);
			}
		}
	}
	internal static class LevelHelper
	{
		public static LevelMetaData? GetCurrentLevelMetaData()
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			return (LevelMetaData)typeof(Info).GetProperty("CurrentLevelMetaData", BindingFlags.Static | BindingFlags.NonPublic).GetValue(null);
		}

		public static string? GetCurrentWorldName()
		{
			return GetCurrentLevelMetaData()?.GetWorldName();
		}

		public static string? GameModeToValidStringKeyElement(GameMode mode)
		{
			int num = mode.m_ID.IndexOf(".");
			if (num <= -1)
			{
				return null;
			}
			return "GAMEMODE_" + LocConversions.NameToValidStringKeyElement(mode.m_ID.Substring(num + 1));
		}
	}
	internal static class UIHelper
	{
		public static void SendNotificationMessage(string message)
		{
			string message2 = message;
			ThreadingHelper.Instance.StartSyncInvoke((Action)delegate
			{
				CharacterCanvas characterCanvas = Singleton<LevelSingleton>.Instance.m_CharacterCanvas;
				if (characterCanvas != null)
				{
					characterCanvas.m_PushMessages.QueueMessage(message2, (Sprite)null);
				}
			});
		}

		public static void SendChatMessage(string message)
		{
			string message2 = message;
			ThreadingHelper.Instance.StartSyncInvoke((Action)delegate
			{
				CharacterCanvas characterCanvas = Singleton<LevelSingleton>.Instance.m_CharacterCanvas;
				if (characterCanvas != null)
				{
					characterCanvas.m_NetworkChat.QueueMessage(message2, (Sprite)null);
				}
			});
		}

		public static void ShowPopup(string message, float width = 502f, float height = 142f)
		{
			string message2 = message;
			ThreadingHelper.Instance.StartSyncInvoke((Action)delegate
			{
				//IL_000c: 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)
				//IL_002d: Unknown result type (might be due to invalid IL or missing references)
				//IL_003f: Unknown result type (might be due to invalid IL or missing references)
				//IL_004a: Unknown result type (might be due to invalid IL or missing references)
				CharacterCanvas characterCanvas = Singleton<LevelSingleton>.Instance.m_CharacterCanvas;
				Vector2 val = new Vector2
				{
					x = width,
					y = height
				};
				if (characterCanvas != null)
				{
					characterCanvas.m_Popup.ShowPopup(message2, (Sprite)null, Color.white, (TextAnchor)4, 2.6f, val);
				}
			});
		}
	}
	internal static class UnlockableHelper
	{
		internal static Unlockable? GetUnlockableById(string id)
		{
			string id2 = id;
			return ((IEnumerable<Unlockable>)Statistics.AllUnlockables).FirstOrDefault((Func<Unlockable, bool>)((Unlockable u) => u.m_Key.m_Value.Equals(id2)));
		}
	}
}
namespace HotLavaArchipelagoPlugin.Gameplay.Modifiers
{
	public class AbilityRandomizerModifier : PlayerControllerModifier
	{
		[Header("Ability Toggles")]
		[Tooltip("Enable/disable double jump ability")]
		public bool EnableDoubleJump = true;

		[Tooltip("Enable/disable boost jump ability")]
		public bool EnableBoostJump = true;

		[Tooltip("Enable/disable slide jump ability")]
		public bool EnableSlideJump = true;

		[Tooltip("Enable/disable lunge/vault ability")]
		public bool EnableVaultJump = true;

		private DoubleJumpModifier m_DoubleJumpModifier;

		private SlideJumpModifier m_SlideJumpModifier;

		private LungeModifier m_LungeModifier;

		public static DoubleJumpModifier DoubleJumpModifier { get; set; }

		public static SlideJumpModifier SlideJumpModifier { get; set; }

		public static LungeModifier LungeModifier { get; set; }

		public override bool CanPerfectJump
		{
			get
			{
				bool flag = ((PlayerControllerModifier)this).CanPerfectJump;
				if (EnableDoubleJump && (Object)(object)m_DoubleJumpModifier != (Object)null)
				{
					flag |= ((PlayerControllerModifier)m_DoubleJumpModifier).CanPerfectJump;
				}
				if (EnableSlideJump && (Object)(object)m_SlideJumpModifier != (Object)null)
				{
					flag |= ((PlayerControllerModifier)m_SlideJumpModifier).CanPerfectJump;
				}
				if (EnableVaultJump && (Object)(object)m_LungeModifier != (Object)null)
				{
					flag |= ((PlayerControllerModifier)m_LungeModifier).CanPerfectJump;
				}
				return flag;
			}
		}

		public override bool CanReach
		{
			get
			{
				if (EnableVaultJump && (Object)(object)m_LungeModifier != (Object)null)
				{
					return ((PlayerControllerModifier)m_LungeModifier).CanReach;
				}
				return ((PlayerControllerModifier)this).CanReach;
			}
		}

		public override float GravityMultiplier
		{
			get
			{
				if (EnableDoubleJump && (Object)(object)m_DoubleJumpModifier != (Object)null)
				{
					return ((PlayerControllerModifier)m_DoubleJumpModifier).GravityMultiplier;
				}
				return ((PlayerControllerModifier)this).GravityMultiplier;
			}
		}

		public void Awake()
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Expected O, but got Unknown
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected O, but got Unknown
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Expected O, but got Unknown
			m_DoubleJumpModifier = (DoubleJumpModifier)PlayerControllerModifier.Clone((PlayerControllerModifier)(object)DoubleJumpModifier);
			m_SlideJumpModifier = (SlideJumpModifier)PlayerControllerModifier.Clone((PlayerControllerModifier)(object)SlideJumpModifier);
			m_LungeModifier = (LungeModifier)PlayerControllerModifier.Clone((PlayerControllerModifier)(object)LungeModifier);
			m_DoubleJumpModifier.m_DoubleJumpSpeedMultiplier = 1f;
		}

		public override void AddModifier(PlayerController player)
		{
			((PlayerControllerModifier)m_DoubleJumpModifier).AddModifier(player);
			((PlayerControllerModifier)m_SlideJumpModifier).AddModifier(player);
			((PlayerControllerModifier)m_LungeModifier).AddModifier(player);
			((PlayerControllerModifier)this).AddModifier(player);
		}

		public override void RemoveModifier()
		{
			((PlayerControllerModifier)this).RemoveModifier();
			((PlayerControllerModifier)m_DoubleJumpModifier).RemoveModifier();
			((PlayerControllerModifier)m_SlideJumpModifier).RemoveModifier();
			((PlayerControllerModifier)m_LungeModifier).RemoveModifier();
		}

		public override void Update()
		{
			if (base.m_PlayerController.IsMine)
			{
				if (EnableDoubleJump && (Object)(object)m_DoubleJumpModifier != (Object)null)
				{
					((PlayerControllerModifier)m_DoubleJumpModifier).Update();
				}
				if (EnableVaultJump && (Object)(object)m_LungeModifier != (Object)null)
				{
					((PlayerControllerModifier)m_LungeModifier).Update();
				}
			}
		}

		public override void FixedUpdate()
		{
			if (base.m_PlayerController.IsMine)
			{
				if (EnableSlideJump && (Object)(object)m_SlideJumpModifier != (Object)null)
				{
					((PlayerControllerModifier)m_SlideJumpModifier).FixedUpdate();
				}
				if (EnableVaultJump && (Object)(object)m_LungeModifier != (Object)null)
				{
					((PlayerControllerModifier)m_LungeModifier).FixedUpdate();
				}
			}
		}

		public override void OnVictory()
		{
			if (EnableVaultJump && (Object)(object)m_LungeModifier != (Object)null)
			{
				((PlayerControllerModifier)m_LungeModifier).OnVictory();
			}
		}
	}
}
namespace HotLavaArchipelagoPlugin.GameData
{
	internal static class Worlds
	{
		public static WorldInfo GymClass
		{
			get
			{
				//IL_0542: Unknown result type (might be due to invalid IL or missing references)
				//IL_0566: Unknown result type (might be due to invalid IL or missing references)
				//IL_058a: Unknown result type (might be due to invalid IL or missing references)
				//IL_05ae: Unknown result type (might be due to invalid IL or missing references)
				//IL_05d2: Unknown result type (might be due to invalid IL or missing references)
				WorldInfo worldInfo = new WorldInfo(WorldSelect.GymClass, 100, "", "tutorial", "Gym Class", new CourseInfo[10]
				{
					new CourseInfo("Gym Jam", new StarInfo[7]
					{
						new StarInfo(100L, "8e72934736772e94eaa50290f7ae341a", "Complete the course", StarType.CourseComplete),
						new StarInfo(101L, "2c2765d96036f40438807ce21e92b229", "Complete in under 08:00", StarType.MinTime),
						new StarInfo(102L, "2b6db09b813d3f54cb1424cbf312ca8d", "Complete in under 02:10", StarType.MinTime),
						new StarInfo(103L, "e7991396471eede4d82f90334472ae2d", "Reach a speed of 9", StarType.Challenge),
						new StarInfo(104L, "2f492a67f28d82c429c93fa9e48bfe3e", "No Deaths", StarType.NoDeaths),
						new StarInfo(105L, "718fac78ec94caa478f347b892adae7a", "Grab the golden pin", StarType.GoldenPin),
						new StarInfo(106L, "7680ae1ce1a1c1f49afc80c4e50df8a1", "Buddy Mode", StarType.Buddy)
					}),
					new CourseInfo("Trampoline Trouble", new StarInfo[7]
					{
						new StarInfo(110L, "52813bff26455a34c92918c183c034fe", "Complete the course", StarType.CourseComplete),
						new StarInfo(111L, "181644ae625180e4eb6989129d83e2fb", "Complete in under 02:30", StarType.MinTime),
						new StarInfo(112L, "3262cf7f58754504dbb378912ea87f07", "Complete in under 01:00", StarType.MinTime),
						new StarInfo(113L, "0059648cfcaf1d3459f89b8b76db5eef", "Don't perform any swings", StarType.Challenge),
						new StarInfo(114L, "5d26c3d1697052c45a3f29ab54d8bb0d", "No Deaths", StarType.NoDeaths),
						new StarInfo(115L, "1a2ff5486c095154c9bf507773051774", "Grab the golden pin", StarType.GoldenPin),
						new StarInfo(116L, "540b0bdc06ed2dd4887deff906e0575f", "Buddy Mode", StarType.Buddy)
					}),
					new CourseInfo("Livin' on the Ledge", new StarInfo[7]
					{
						new StarInfo(120L, "f2aca0ab34ef5a34fb9b3d9a52087aff", "Complete the course", StarType.CourseComplete),
						new StarInfo(121L, "c689392b82845f948b1a088de15c27ab", "Complete in under 02:00", StarType.MinTime),
						new StarInfo(122L, "513a99591da7c8f49855898242e338e7", "Complete in under 00:55", StarType.MinTime),
						new StarInfo(123L, "dc67bb49b6bdd3f4ba6af59e7f46dc7e", "Spend less than 25 seconds on the ground", StarType.Challenge),
						new StarInfo(124L, "df11767c8cafed7429faabbe863fac18", "No Deaths", StarType.NoDeaths),
						new StarInfo(125L, "3a0ab619a819e514cb7aa6c7ceaa3175", "Grab the golden pin", StarType.GoldenPin),
						new StarInfo(126L, "2b821237eb81a37448942997afb21e9e", "Buddy Mode", StarType.Buddy)
					}),
					new CourseInfo("Surfing Surfaces", new StarInfo[7]
					{
						new StarInfo(130L, "b772330c648bc5b4dbf560e1636a765b", "Complete the course", StarType.CourseComplete),
						new StarInfo(131L, "720fa9c239a1b224eae03b1dd031c9c5", "Complete in under 01:50", StarType.MinTime),
						new StarInfo(132L, "4218afbc7f4895141a4ebd26d61272d3", "Complete in under 00:50", StarType.MinTime),
						new StarInfo(133L, "a6179cec5a395964a807d262ec059a9e", "Reach a speed of 10.5", StarType.Challenge),
						new StarInfo(134L, "5bd4d45837fdac649965d0e2b89e63d7", "No Deaths", StarType.NoDeaths),
						new StarInfo(135L, "7ed7e2810fd00a14aaea4f267e33400e", "Grab the golden pin", StarType.GoldenPin),
						new StarInfo(136L, "d2a264a37b85ab045a885dc98fa2ad56", "Buddy Mode", StarType.Buddy)
					}),
					new CourseInfo("Pole Vault", new StarInfo[7]
					{
						new StarInfo(140L, "b854fd83bb9c6b2438d05cfdaba66a91", "Complete the course", StarType.CourseComplete),
						new StarInfo(141L, "3bb1fbe4b84c03a4086c6ac366f2ba27", "Complete in under 02:30", StarType.MinTime),
						new StarInfo(142L, "f89d1fb8ad92a634d8703d0b8bb1c976", "Complete in under 01:10", StarType.MinTime),
						new StarInfo(143L, "6bc239d7f01e9ee40a4ce3687f205482", "Spend less than 30 seconds on the ground", StarType.Challenge),
						new StarInfo(144L, "f8a55461338a712468a59dcd64888350", "No Deaths", StarType.NoDeaths),
						new StarInfo(145L, "5101c9e9015f4204bb42649a58127217", "Grab the golden pin", StarType.GoldenPin),
						new StarInfo(146L, "b6fb416d4c5c4984db326bab8e23079a", "Buddy Mode", StarType.Buddy)
					}),
					new CourseInfo("Chase Your Sister", new StarInfo[7]
					{
						new StarInfo(150L, "39d3e311aa4b8dc4e92da8ec2fc093e1", "Complete the course", StarType.CourseComplete),
						new StarInfo(151L, "46a134cc36e348d4eb3416dc4f9df9de", "Complete in under 01:10", StarType.MinTime),
						new StarInfo(152L, "f6a106bb664df5a4089b4fa5101f0152", "Complete in under 00:45", StarType.MinTime),
						new StarInfo(153L, "34f041456579a904a98c746ea6e6bb2e", "Don't perform any swings", StarType.Challenge),
						new StarInfo(154L, "34a0bf50ab8394f46a9a94542fbfc553", "Tag your sister", StarType.Challenge),
						new StarInfo(155L, "a45613d4c2daadb4aa581548048d2c7a", "Grab the golden pin", StarType.GoldenPin),
						new StarInfo(156L, "078d212bcd4e55a4f9fe32de2cf0ad2b", "Wild Buddy Chase", StarType.BuddyChase)
					}),
					new CourseInfo("Pogo Trial", CourseType.Pogo, new StarInfo[1]
					{
						new StarInfo(160L, "5069ece9ed4a8ed479d1743620a34023", "Find all the checkpoints using the Pogo Stick", StarType.TrialComplete)
					}),
					new CourseInfo("Tiny Toy Trial", CourseType.TinyToy, new StarInfo[1]
					{
						new StarInfo(161L, "98310f580476ff04384f6abd4357370e", "Get to the finish line", StarType.TrialComplete)
					}),
					new CourseInfo("Jetpack Trial", CourseType.Jetpack, new StarInfo[1]
					{
						new StarInfo(162L, "62137bb4c16995d4aaf2f385225156e8", "Find all the checkpoints using the Jetpack", StarType.TrialComplete)
					}),
					new CourseInfo("All Course Marathon", CourseType.AllCourseMarathon, new StarInfo[1]
					{
						new StarInfo(163L, "e9ee84430ecf11740beb41326451d414", "Complete the course", StarType.TrialComplete)
					})
				});
				worldInfo.ForceFields = new ForceFieldInfo[5]
				{
					new ForceFieldInfo(110L, "Gym/Office Hallway", new Vector3(33.752f, 1.76f, 1.6f)),
					new ForceFieldInfo(111L, "Office Hallway/Janitor's Closet", new Vector3(24.622f, 1.758f, 25.966f)),
					new ForceFieldInfo(112L, "Office Hallway/Back Hallway", new Vector3(18.55f, 1.86f, 29.089f)),
					new ForceFieldInfo(113L, "Computer Lab Hallway/Back Hallway", new Vector3(0.853f, 1.633f, 25.97f)),
					new ForceFieldInfo(114L, "Back Hallway/Side Entrance", new Vector3(-1.35f, 1.86f, 29.089f))
				};
				return worldInfo;
			}
		}

		public static WorldInfo Playground
		{
			get
			{
				//IL_0611: Unknown result type (might be due to invalid IL or missing references)
				//IL_0638: Unknown result type (might be due to invalid IL or missing references)
				WorldInfo worldInfo = new WorldInfo(WorldSelect.Playground, 200, "83328d77e87a0d34b8cc4aae038bd158", "playground", "Playground", new CourseInfo[13]
				{
					new CourseInfo("Recess", new StarInfo[7]
					{
						new StarInfo(200L, "60dff4f3d39f9664d8cde41acf5a9465", "Complete the course", StarType.CourseComplete),
						new StarInfo(201L, "e6704c37a77263d4fb352b2ebe0c9dd5", "Complete in under 07:00", StarType.MinTime),
						new StarInfo(202L, "4e708a47372bdfd4c96d9853dd7204ac", "Complete in under 02:10", StarType.MinTime),
						new StarInfo(203L, "724bcc52ae9d6df46a1fe83bc9e5f3b7", "No Deaths", StarType.NoDeaths),
						new StarInfo(204L, "5a0c11e0ebfe8a642acdcb3f224e44c5", "Grab the golden pin", StarType.GoldenPin),
						new StarInfo(205L, "f0804c3773358e54ea3381ab1d9a4fa4", "Find the hidden G.A.T. comic", StarType.Comic),
						new StarInfo(206L, "36f06de3ffe852648bbf28e3f8383a1a", "Buddy Mode", StarType.Buddy)
					}),
					new CourseInfo("Big Kids Side", new StarInfo[7]
					{
						new StarInfo(210L, "1ce626b7d30c7984bafa0241356ca1aa", "Complete the course", StarType.CourseComplete),
						new StarInfo(211L, "d0a1872e506424544a944d02f1273cba", "Complete in under 08:00", StarType.MinTime),
						new StarInfo(212L, "a92ec2a42e5efbf4eaf8b574dd625253", "Complete in under 02:45", StarType.MinTime),
						new StarInfo(213L, "f417c8cd9958fe44a8c8bfb747a14856", "No Deaths", StarType.NoDeaths),
						new StarInfo(214L, "f3605b943b5651b4eb7289ce220d4cef", "Grab the golden pin", StarType.GoldenPin),
						new StarInfo(215L, "985db81c1b97b00498884c81ce9c1001", "Find the hidden G.A.T. comic", StarType.Comic),
						new StarInfo(216L, "fe07e2dc513868a4cad555546bd3ce1c", "Buddy Mode", StarType.Buddy)
					}),
					new CourseInfo("Bouncy Castle", new StarInfo[7]
					{
						new StarInfo(220L, "25da304df7917554c932e0db2ed12bbe", "Complete the course", StarType.CourseComplete),
						new StarInfo(221L, "45851bf0a9623944fad09518b9be8a54", "Complete in under 04:30", StarType.MinTime),
						new StarInfo(222L, "d7a3953016f961c43b8c97b3c538d838", "Complete in under 01:45", StarType.MinTime),
						new StarInfo(223L, "15ba77a1f2ff6ec45a5d8a6ce1a2d7d3", "No Deaths", StarType.NoDeaths),
						new StarInfo(224L, "b13ffe80cf201d54b9f48af60809cbd6", "Grab the golden pin", StarType.GoldenPin),
						new StarInfo(225L, "81d32f5a10c05fe4c88a74abb7db2b84", "Find the hidden G.A.T. comic", StarType.Comic),
						new StarInfo(226L, "623714b5444588f43a7e8d01a84b6525", "Buddy Mode", StarType.Buddy)
					}),
					new CourseInfo("Back to Class", new StarInfo[7]
					{
						new StarInfo(230L, "888924c3b32682b4eba329c0840548d8", "Complete the course", StarType.CourseComplete),
						new StarInfo(231L, "bcceae8fcf65da644b7252e135889074", "Complete in under 06:00", StarType.MinTime),
						new StarInfo(232L, "1a524b89d300c44468b7057596730d82", "Complete in under 01:45", StarType.MinTime),
						new StarInfo(233L, "3377dfa30ba551447b5c15d4f276c2c6", "No Deaths", StarType.NoDeaths),
						new StarInfo(234L, "8c335e082a2eb024aa36d8c2e6cadb48", "Grab the golden pin", StarType.GoldenPin),
						new StarInfo(235L, "69f0cf9071aad05479efee996377ea21", "Find the hidden G.A.T. comic", StarType.Comic),
						new StarInfo(236L, "748605251b94a514f8ec0f85415ffa91", "Buddy Mode", StarType.Buddy)
					}),
					new CourseInfo("Sports Day", new StarInfo[7]
					{
						new StarInfo(240L, "b9de4719a85dd0f48be1ef9df00248f5", "Complete the course", StarType.CourseComplete),
						new StarInfo(241L, "8d1c5b5442d995f428a89236adaa7900", "Complete in under 01:40", StarType.MinTime),
						new StarInfo(242L, "1b1ddc847b094bd4aafe998d05829548", "Complete in under 01:10", StarType.MinTime),
						new StarInfo(243L, "d6d01532f4668284382bdbde28e3b59d", "No Deaths", StarType.NoDeaths),
						new StarInfo(244L, "b3eb8fe6d65356a49a0cf46e288c69f6", "Grab the golden pin", StarType.GoldenPin),
						new StarInfo(245L, "04ffbbd04e97bb441a90e7c7fb0d052e", "Find the hidden G.A.T. comic", StarType.Comic),
						new StarInfo(246L, "c96eefdfbaa06d0459b7eec5221cd510", "Buddy Mode", StarType.Buddy)
					}),
					new CourseInfo("Chase the Big Kid", new StarInfo[7]
					{
						new StarInfo(250L, "edd7311d9d1623e4891f8d4b955d345e", "Complete the course", StarType.CourseComplete),
						new StarInfo(251L, "9a08d0a4fd4585c4fac47e975c79ad0d", "Complete in under 01:15", StarType.MinTime),
						new StarInfo(252L, "a1b0ed2d2c267ae4d8391a364830160f", "Complete in under 00:58", StarType.MinTime),
						new StarInfo(253L, "ce5ef6bbd31e325499fb9cf28fd80d36", "Tag your sister", StarType.Challenge),
						new StarInfo(254L, "e621f981cf18e2242b26195512632798", "Grab the golden pin", StarType.GoldenPin),
						new StarInfo(255L, "732eafb0ad0d6c547921c904d1ee4073", "Find the hidden G.A.T. comic", StarType.Comic),
						new StarInfo(256L, "9b5c1d100a2db99428e779f8cf33486e", "Chase Buddy", StarType.BuddyChase)
					}),
					new CourseInfo("Pogo Trial 1", CourseType.Pogo, new StarInfo[1]
					{
						new StarInfo(260L, "1a56d171c35fcf547980a37d8f7f7960", "Find all the checkpoints using the Pogo Stick", StarType.TrialComplete)
					}),
					new CourseInfo("Pogo Trial 2", CourseType.Pogo, new StarInfo[1]
					{
						new StarInfo(261L, "9fc0edaa2793c9c45927c92caf5634b3", "Find all the checkpoints using the Pogo Stick", StarType.TrialComplete)
					}),
					new CourseInfo("Tiny Toy Trial 1", CourseType.TinyToy, new StarInfo[1]
					{
						new StarInfo(262L, "415b0dd0ab657c840a3073f2e952cb6c", "Get to the finish line", StarType.TrialComplete)
					}),
					new CourseInfo("Tiny Toy Trial 2", CourseType.TinyToy, new StarInfo[1]
					{
						new StarInfo(263L, "5896145f43d1a6a4dbce56b1dbf7ca61", "Get to the finish line", StarType.TrialComplete)
					}),
					new CourseInfo("Jetpack Trial", CourseType.Jetpack, new StarInfo[1]
					{
						new StarInfo(264L, "6065e19024fa4cc4d9d9ea20e581a25b", "Find all the checkpoints using the Jetpack", StarType.TrialComplete)
					}),
					new CourseInfo("Chase the Grade", CourseType.Chase, new StarInfo[1]
					{
						new StarInfo(265L, "d5c3b1aaf1343a143a7186eafdcdeaad", "Complete the course", StarType.TrialComplete)
					}),
					new CourseInfo("All Course Marathon", CourseType.AllCourseMarathon, new StarInfo[1]
					{
						new StarInfo(266L, "234d3bf0d0df2af408329011a45dfd1b", "Complete the course", StarType.TrialComplete)
					})
				});
				worldInfo.ForceFields = new ForceFieldInfo[2]
				{
					new ForceFieldInfo(210L, "Spawn/Basketball Courts", new Vector3(17.603f, 2.501f, 14.035f)),
					new ForceFieldInfo(211L, "Basketball Courts/Sports Day Side", new Vector3(17.4f, 2.5f, -11.5f))
				};
				return worldInfo;
			}
		}

		public static WorldInfo School
		{
			get
			{
				//IL_0611: Unknown result type (might be due to invalid IL or missing references)
				//IL_0638: Unknown result type (might be due to invalid IL or missing references)
				//IL_065f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0686: Unknown result type (might be due to invalid IL or missing references)
				//IL_06ad: Unknown result type (might be due to invalid IL or missing references)
				//IL_06d4: Unknown result type (might be due to invalid IL or missing references)
				//IL_06fb: Unknown result type (might be due to invalid IL or missing references)
				//IL_0722: Unknown result type (might be due to invalid IL or missing references)
				//IL_0755: Unknown result type (might be due to invalid IL or missing references)
				//IL_077c: Unknown result type (might be due to invalid IL or missing references)
				//IL_07a3: Unknown result type (might be due to invalid IL or missing references)
				//IL_07ca: Unknown result type (might be due to invalid IL or missing references)
				//IL_07f1: Unknown result type (might be due to invalid IL or missing references)
				WorldInfo worldInfo = new WorldInfo(WorldSelect.School, 300, "212f728535833224287d420c81f43ef1", "school", "School", new CourseInfo[13]
				{
					new CourseInfo("ABCs and 123s", new StarInfo[7]
					{
						new StarInfo(300L, "57e0344bd3abfb4449346d182cd8e901", "Complete the course", StarType.CourseComplete),
						new StarInfo(301L, "2ee56bdf1e09d1a4eb0170081b60b883", "Complete in under 12:00", StarType.MinTime),
						new StarInfo(302L, "b2311faf93b83d0428c2a97d1ee72c6b", "Complete in under 05:00", StarType.MinTime),
						new StarInfo(303L, "a14a4456df2c527479a4889c2555ae0a", "No Deaths", StarType.NoDeaths),
						new StarInfo(304L, "9f6ad9759e59fc14cbffdd76792c9796", "Grab the golden pin", StarType.GoldenPin),
						new StarInfo(305L, "d15988c45557cd641b5c1fed6d28b93c", "Find the hidden G.A.T. comic", StarType.Comic),
						new StarInfo(306L, "21c2d3bc6b1078546a556f6065b9944f", "Buddy Mode", StarType.Buddy)
					}),
					new CourseInfo("Middle School Mischief", new StarInfo[7]
					{
						new StarInfo(310L, "73c90f4f92fb86e4d8643e0efe67f386", "Complete the course", StarType.CourseComplete),
						new StarInfo(311L, "f495576fc3c4f654d97c874f8c48235f", "Complete in under 11:00", StarType.MinTime),
						new StarInfo(312L, "bf0d228482a8f564d80bc8fc3919834e", "Complete in under 03:00", StarType.MinTime),
						new StarInfo(313L, "bcc4ecc8b68979143924c78e147e54cb", "No Deaths", StarType.NoDeaths),
						new StarInfo(314L, "f0271c912e6562745aa87f64120386ca", "Grab the golden pin", StarType.GoldenPin),
						new StarInfo(315L, "c4c3c7f707f83a74a91fd35a3c996200", "Find the hidden G.A.T. comic", StarType.Comic),
						new StarInfo(316L, "b2f7d84f93346b84880bf32ccb684c5a", "Buddy Mode", StarType.Buddy)
					}),
					new CourseInfo("Repeat the Grade", new StarInfo[7]
					{
						new StarInfo(320L, "72a71e5e6cb185843940831aff9f05d9", "Complete the course", StarType.CourseComplete),
						new StarInfo(321L, "12bc63b0a54486449b09fa0883f5937a", "Complete in under 10:00", StarType.MinTime),
						new StarInfo(322L, "ab81decce36f68b4db6801c220184dad", "Complete in under 03:30", StarType.MinTime),
						new StarInfo(323L, "77e419b13b4e62d4f857c36a8a9622b7", "No Deaths", StarType.NoDeaths),
						new StarInfo(324L, "de32cab8a4473d045a1095a17f779697", "Grab the golden pin", StarType.GoldenPin),
						new StarInfo(325L, "d419edaf69289854f95c5c075c934b8c", "Find the hidden G.A.T. comic", StarType.Comic),
						new StarInfo(326L, "893408fe1ea036b4db838b1f48e25271", "Buddy Mode", StarType.Buddy)
					}),
					new CourseInfo("Senior Trip", new StarInfo[7]
					{
						new StarInfo(330L, "972ec486a5a1b8d4c9d5d5c6894ff904", "Complete the course", StarType.CourseComplete),
						new StarInfo(331L, "28b6b575cd513074fb9b9408bf3b46d9", "Complete in under 08:00", StarType.MinTime),
						new StarInfo(332L, "ee745e4fd95cc00468fa3ce854a39245", "Complete in under 03:00", StarType.MinTime),
						new StarInfo(333L, "18afc8a3a23bee045a7e502e8ee50216", "No Deaths", StarType.NoDeaths),
						new StarInfo(334L, "b7a195d971b1d7848bb37ca8fcc68112", "Grab the golden pin", StarType.GoldenPin),
						new StarInfo(335L, "29f436273460d574fbdfa1d797f29d13", "Find the hidden G.A.T. comic", StarType.Comic),
						new StarInfo(336L, "1620c9eae36334a4783950bdacc65a5d", "Buddy Mode", StarType.Buddy)
					}),
					new CourseInfo("Freshman Frenzy", new StarInfo[7]
					{
						new StarInfo(340L, "180ece11a7fb5c841bcbb633544e131f", "Complete the course", StarType.CourseComplete),
						new StarInfo(341L, "6b267b4581572464d8340e34babd9492", "Complete in under 10:00", StarType.MinTime),
						new StarInfo(342L, "a1eb55827bd43be4bbb57ddd7845ee9f", "Complete in under 03:30", StarType.MinTime),
						new StarInfo(343L, "c0e9b9f96d82eb84f8c579a1418440d4", "No Deaths", StarType.NoDeaths),
						new StarInfo(344L, "a003111804c160e4a96cbad1914e793e", "Grab the golden pin", StarType.GoldenPin),
						new StarInfo(345L, "3706423d30537ba4191a10e58d3b1611", "Find the hidden G.A.T. comic", StarType.Comic),
						new StarInfo(346L, "2fa7368db5bfb58489ec7e1a2adffa31", "Buddy Mode", StarType.Buddy)
					}),
					new CourseInfo("Chase Your Sister", new StarInfo[7]
					{
						new StarInfo(350L, "4d0edbf502e968b4a8a672e0a7355c81", "Complete the course", StarType.CourseComplete),
						new StarInfo(351L, "93120cacc4fb33b4a813d188d5696fd5", "Complete in under 02:00", StarType.MinTime),
						new StarInfo(352L, "c563a09d63593a54092506d5aca87747", "Complete in under 00:50", StarType.MinTime),
						new StarInfo(353L, "a8ff9a42e05c9c0448b37c1b8eb03412", "Tag your sister", StarType.Challenge),
						new StarInfo(354L, "0fc1239839daab54686b01a5b36332c4", "Grab the golden pin", StarType.GoldenPin),
						new StarInfo(355L, "b27ebe301bf36cf46b6a42735638d6fa", "Find the hidden G.A.T. comic", StarType.Comic),
						new StarInfo(356L, "30fdf0d70ac2f11469ea3a313dd76c2c", "Chase The Escaped Dog", StarType.BuddyChase)
					}),
					new CourseInfo("Pogo Trial 1", CourseType.Pogo, new StarInfo[1]
					{
						new StarInfo(360L, "e641257639cc2354aa58580dae083b03", "Find all the checkpoints using the Pogo Stick", StarType.TrialComplete)
					}),
					new CourseInfo("Pogo Trial 2", CourseType.Pogo, new StarInfo[1]
					{
						new StarInfo(361L, "e09457a7ecb51044fb72744ce6699e25", "Find all the checkpoints using the Pogo Stick", StarType.TrialComplete)
					}),
					new CourseInfo("Pogo Trial 3", CourseType.Pogo, new StarInfo[1]
					{
						new StarInfo(362L, "a9c4d26b69466bd45886f8825aff4054", "Find all the checkpoints using the Pogo Stick", StarType.TrialComplete)
					}),
					new CourseInfo("Tiny Toy Trial", CourseType.TinyToy, new StarInfo[1]
					{
						new StarInfo(363L, "ef5401ba94301e74fa8f32d8af2f429d", "Get to the finish line", StarType.TrialComplete)
					}),
					new CourseInfo("Jetpack Trial", CourseType.Jetpack, new StarInfo[1]
					{
						new StarInfo(364L, "b635ffc7a94e4eb4787160b9dc2b77fe", "Find all the checkpoints using the Jetpack", StarType.TrialComplete)
					}),
					new CourseInfo("Chase the Grade", CourseType.Chase, new StarInfo[1]
					{
						new StarInfo(365L, "bc1ad6587b18207469969deace0ac6c5", "Complete the course", StarType.TrialComplete)
					}),
					new CourseInfo("All Course Marathon", CourseType.AllCourseMarathon, new StarInfo[1]
					{
						new StarInfo(366L, "4aa7293d5e6db8d409a3655cfe6efefa", "Complete the course", StarType.TrialComplete)
					})
				});
				worldInfo.ForceFields = new ForceFieldInfo[8]
				{
					new ForceFieldInfo(310L, "Gym Hallway/Computer Lab", new Vector3(32.16f, 2.168f, -24.77f)),
					new ForceFieldInfo(311L, "Social Studies Hallway/Art Hallway", new Vector3(19f, 2.85f, -12.65f)),
					new ForceFieldInfo(312L, "Teacher's Lounge Hallway/Art Hallway", new Vector3(-23.64f, 2.85f, -12.65f)),
					new ForceFieldInfo(313L, "English Hallway/Teacher's Lounge Hallway", new Vector3(-23.745f, 3.46f, 1.31f)),
					new ForceFieldInfo(314L, "Science Lab/Art Closet", new Vector3(4.046f, 2.177f, -24.828f)),
					new ForceFieldInfo(315L, "Art Hallway/Art Class", new Vector3(-10.526f, 2.704f, -18.816f)),
					new ForceFieldInfo(316L, "Art Closet/Art Class", new Vector3(-0.077f, 2.687f, -28.871f)),
					new ForceFieldInfo(317L, "Teacher's Lounge/Courtyard", new Vector3(-8.333f, 3.724f, -6.338f))
				};
				worldInfo.DisabledForceFields = new ForceFieldInfo[5]
				{
					new ForceFieldInfo(318L, "Atrium/Cafeteria", new Vector3(5.079f, 2.141f, 16.822f)),
					new ForceFieldInfo(319L, "Social Studies Class Left", new Vector3(22.022f, 2.1f, 1.9f)),
					new ForceFieldInfo(320L, "Gym Hallway/Science Lab", new Vector3(15.927f, 2.177f, -29.253f)),
					new ForceFieldInfo(321L, "Atrium/Social Studies Hallway", new Vector3(15.945f, 2.146f, 6.217f)),
					new ForceFieldInfo(322L, "Social Studies Class Right", new Vector3(22.022f, 2.1f, -10.116f))
				};
				return worldInfo;
			}
		}

		public static WorldInfo Wholesale
		{
			get
			{
				//IL_0611: Unknown result type (might be due to invalid IL or missing references)
				//IL_0638: Unknown result type (might be due to invalid IL or missing references)
				//IL_065f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0686: Unknown result type (might be due to invalid IL or missing references)
				//IL_06ad: Unknown result type (might be due to invalid IL or missing references)
				//IL_06d4: Unknown result type (might be due to invalid IL or missing references)
				WorldInfo worldInfo = new WorldInfo(WorldSelect.Wholesale, 400, "f5bd38e199f54fa46aff759206fd0806", "wholesale_expanded", "Wholesale", new CourseInfo[13]
				{
					new CourseInfo("To the Top", new StarInfo[7]
					{
						new StarInfo(400L, "16834aaf2d1962e44b22cbf1bd2d3a6f", "Complete the course", StarType.CourseComplete),
						new StarInfo(401L, "058594844899efe45b805507f1addd7b", "Complete in under 10:00", StarType.MinTime),
						new StarInfo(402L, "f87018bfc1f842740b56c2a1a92cf4a5", "Complete in under 03:00", StarType.MinTime),
						new StarInfo(403L, "9f8de75e70e8b5942842e8fb62b50a58", "No Deaths", StarType.NoDeaths),
						new StarInfo(404L, "d73a042fdcb801841864b76903065548", "Grab the golden pin", StarType.GoldenPin),
						new StarInfo(405L, "89dcbb351c916b944ae2d04c72a1ba22", "Find the hidden G.A.T. comic", StarType.Comic),
						new StarInfo(406L, "996d266c518979d438cbbe4a4a6b7b4a", "Buddy Mode", StarType.Buddy)
					}),
					new CourseInfo("Duct and Cover", new StarInfo[7]
					{
						new StarInfo(410L, "2d0738601a766234087120f1a016a344", "Complete the course", StarType.CourseComplete),
						new StarInfo(411L, "72bc9354d22810544ba7a1b8f66bc942", "Complete in under 08:00", StarType.MinTime),
						new StarInfo(412L, "41ecfbd3c9df62543be573b0253c6f54", "Complete in under 02:30", StarType.MinTime),
						new StarInfo(413L, "c7bfa995db564b9418bf9c523b38c5ce", "No Deaths", StarType.NoDeaths),
						new StarInfo(414L, "57cd7507ede3def4da02d8e46cb66d30", "Grab the golden pin", StarType.GoldenPin),
						new StarInfo(415L, "4c9dedd9fc5625e47afbd9dae457de29", "Find the hidden G.A.T. comic", StarType.Comic),
						new StarInfo(416L, "1b289b5ad606abb4e9f982b3d9d4fa32", "Buddy Mode", StarType.Buddy)
					}),
					new CourseInfo("Meat Market", new StarInfo[7]
					{
						new StarInfo(420L, "edac1a5bb7363854086f7896a6a38255", "Complete the course", StarType.CourseComplete),
						new StarInfo(421L, "81ac63c1ad8c4d5418ea125eaf3bb1f7", "Complete in under 08:00", StarType.MinTime),
						new StarInfo(422L, "e9c3888f1669e1344a9dc063e961efb8", "Complete in under 03:30", StarType.MinTime),
						new StarInfo(423L, "ecbef8112dd43cb40a7515ac45e52731", "No Deaths", StarType.NoDeaths),
						new StarInfo(424L, "aaf16c7eb791b4a4b9bd82b86c6c98ea", "Grab the golden pin", StarType.GoldenPin),
						new StarInfo(425L, "33124f465d203ae49a6cec0a4764dc33", "Find the hidden G.A.T. comic", StarType.Comic),
						new StarInfo(426L, "2545f6cd979390b408e0d6d40de14a95", "Buddy Mode", StarType.Buddy)
					}),
					new CourseInfo("Returns", new StarInfo[7]
					{
						new StarInfo(430L, "bab110cfadbf0584992291250189509a", "Complete the course", StarType.CourseComplete),
						new StarInfo(431L, "4069629cbae76e44c85bad4829835876", "Complete in under 04:00", StarType.MinTime),
						new StarInfo(432L, "75d3d573dae4a4f42a2b391d09746933", "Complete in under 02:30", StarType.MinTime),
						new StarInfo(433L, "e8fdb40f968d6aa40841f7bcd0f46170", "No Deaths", StarType.NoDeaths),
						new StarInfo(434L, "f518343abbc940042b21423aef055173", "Grab the golden pin", StarType.GoldenPin),
						new StarInfo(435L, "292e394b0fcd3fc47b647f3364ca70f6", "Find the hidden G.A.T. comic", StarType.Comic),
						new StarInfo(436L, "2031f866b2c2f884ba940f5384f34ec7", "Buddy Mode", StarType.Buddy)
					}),
					new CourseInfo("Meat Grinder", new StarInfo[7]
					{
						new StarInfo(440L, "d647509540004f049a23d32a2f4d795c", "Complete the course", StarType.CourseComplete),
						new StarInfo(441L, "0cc12dc8e0f5270458650b573b883ee3", "Complete in under 10:00", StarType.MinTime),
						new StarInfo(442L, "869fef92e76d8c149b574ada1d109d9c", "Complete in under 04:30", StarType.MinTime),
						new StarInfo(443L, "2d2c927fe825ed24a907e6e1d8dadf5e", "No Deaths", StarType.NoDeaths),
						new StarInfo(444L, "6a7f4265256d34d408021ba7f9473f41", "Grab the golden pin", StarType.GoldenPin),
						new StarInfo(445L, "9c1c28cdc25a53341b6eafb0a0a87768", "Find the hidden G.A.T. comic", StarType.Comic),
						new StarInfo(446L, "8ec1308f20c329147ac1a3f5661b79d4", "Buddy Mode", StarType.Buddy)
					}),
					new CourseInfo("Chase Through the Store", new StarInfo[7]
					{
						new StarInfo(450L, "b13b5b41ee88fe144bfa267efb59c710", "Complete the course", StarType.CourseComplete),
						new StarInfo(451L, "952e95490fb1bc34a93e5a3d2a543472", "Complete in under 00:50", StarType.MinTime),
						new StarInfo(452L, "9cf25623f3fd60a44818bd90028dba35", "Complete in under 00:33", StarType.MinTime),
						new StarInfo(453L, "aac1119a19a3e7743995599868918357", "No Deaths", StarType.NoDeaths),
						new StarInfo(454L, "550fcd82164dcea41b524a107a2632c2", "Grab the golden pin", StarType.GoldenPin),
						new StarInfo(455L, "efe2e7dbec062e2448a4f80219fdfe78", "Find the hidden G.A.T. comic", StarType.Comic),
						new StarInfo(456L, "c241690961d459243ad294a277746e36", "Chase the Runaway Dog", StarType.BuddyChase)
					}),
					new CourseInfo("Pogo Trial 1", CourseType.Pogo, new StarInfo[1]
					{
						new StarInfo(460L, "314ee7741f7851e4e82f7d5581088470", "Find all the checkpoints using the Pogo Stick", StarType.TrialComplete)
					}),
					new CourseInfo("Pogo Trial 2", CourseType.Pogo, new StarInfo[1]
					{
						new StarInfo(461L, "d7fe16db846211043ae130ad5db97bd3", "Find all the checkpoints using the Pogo Stick", StarType.TrialComplete)
					}),
					new CourseInfo("Pogo Trial 3", CourseType.Pogo, new StarInfo[1]
					{
						new StarInfo(462L, "70ae3c38be714cc40bba4feeea5fd355", "Find all the checkpoints using the Pogo Stick", StarType.TrialComplete)
					}),
					new CourseInfo("Tiny Toy Trial", CourseType.TinyToy, new StarInfo[1]
					{
						new StarInfo(463L, "4604d3c043b5320489bd6eaac865277b", "Get to the finish line", StarType.TrialComplete)
					}),
					new CourseInfo("Jetpack Trial", CourseType.Jetpack, new StarInfo[1]
					{
						new StarInfo(464L, "6a8ec6917998047489e769a72a418d5a", "Find all the checkpoints using the Jetpack", StarType.TrialComplete)
					}),
					new CourseInfo("Chase the Grade", CourseType.Chase, new StarInfo[1]
					{
						new StarInfo(465L, "eee4a71e511af8f498f55c55fe06a8aa", "Complete the course", StarType.TrialComplete)
					}),
					new CourseInfo("All Course Marathon", CourseType.AllCourseMarathon, new StarInfo[1]
					{
						new StarInfo(466L, "1d4f91a1fb1547b429b539972938e5d9", "Complete the course", StarType.TrialComplete)
					})
				});
				worldInfo.ForceFields = new ForceFieldInfo[6]
				{
					new ForceFieldInfo(410L, "Employee Hallway/Checkout", new Vector3(-32.53f, 2.7f, -12.203f)),
					new ForceFieldInfo(411L, "Employee Hallway/Janitor's Closet", new Vector3(-10.862f, 6.123f, -3.862f)),
					new ForceFieldInfo(412L, "Under the Shelves", new Vector3(-2.871f, 1.38f, -37.507f)),
					new ForceFieldInfo(413L, "Checkout/Cart Storage", new Vector3(-29.134f, 2.125f, -40.67f)),
					new ForceFieldInfo(414L, "Employee Hallway/Breakroom", new Vector3(-4.788f, 6.112f, 2.11f)),
					new ForceFieldInfo(415L, "Checkout/Shopping Area", new Vector3(-26.5f, 2.700001f, -17.8f))
				};
				return worldInfo;
			}
		}

		public static WorldInfo MasterClass => new WorldInfo(WorldSelect.MasterClass, 500, "6bd78323a271b804890f9bd232ae0abb", "mastery_gym", "Master Class", new CourseInfo[10]
		{
			new CourseInfo("Air Control Mastery", new StarInfo[6]
			{
				new StarInfo(500L, "399017d32e64e7147850bb221ad9a330", "Complete the course", StarType.CourseComplete),
				new StarInfo(501L, "d9f265807b6647a46a071e38d0f43199", "Complete in under 02:30", StarType.MinTime),
				new StarInfo(502L, "5745104145f93b54fb585474ed7f395f", "Complete in under 01:00", StarType.MinTime),
				new StarInfo(503L, "a19ee0938f049324b8e0f5c2994926f9", "No Deaths", StarType.NoDeaths),
				new StarInfo(504L, "05207fb7837a51645b97a0b17b018f4c", "Reach a speed of 4.5", StarType.Challenge),
				new StarInfo(505L, "59b9c6018baa64c48961b3f4d897e49e", "Grab the golden pin", StarType.GoldenPin)
			}),
			new CourseInfo("Wall Jump Mastery", new StarInfo[6]
			{
				new StarInfo(510L, "eb5e3cb0b7b99b04284d730869ce9fb6", "Complete the course", StarType.CourseComplete),
				new StarInfo(511L, "377e30517bff4ac47929b80aecda0062", "Complete in under 02:30", StarType.MinTime),
				new StarInfo(512L, "52e25e2c6bf4c454c8d44ef4d6b66688", "Complete in under 00:50", StarType.MinTime),
				new StarInfo(513L, "b90b53beac85f6c4098e99c45a51b279", "No Deaths", StarType.NoDeaths),
				new StarInfo(514L, "3517d5ce270ecd64c9c75ffb7f3f475e", "Spend less than 10 seconds on the ground", StarType.Challenge),
				new StarInfo(515L, "1a2ff5486c095154c9bf507773051774", "Grab the golden pin", StarType.GoldenPin)
			}),
			new CourseInfo("Surf Mastery", new StarInfo[6]
			{
				new StarInfo(520L, "4c31e47b2b82aa64e94b5a4e67139775", "Complete the course", StarType.CourseComplete),
				new StarInfo(521L, "079222fa9d56f2242a92321dd8d5a599", "Complete in under 01:00", StarType.MinTime),
				new StarInfo(522L, "4a6c828b9643ba4459bd1ae1f978dadb", "Complete in under 00:30", StarType.MinTime),
				new StarInfo(523L, "75645b25d426a094090d1cccadcf9d8d", "No Deaths", StarType.NoDeaths),
				new StarInfo(524L, "417d208b1ed26b148987a5aa7c4ca388", "Complete in 5 jumps or less", StarType.Challenge),
				new StarInfo(525L, "5101c9e9015f4204bb42649a58127217", "Grab the golden pin", StarType.GoldenPin)
			}),
			new CourseInfo("Boosting Mastery", new StarInfo[6]
			{
				new StarInfo(530L, "5b3155d2c67f23b41b5b0ba6bf1d6740", "Complete the course", StarType.CourseComplete),
				new StarInfo(531L, "b7922c4cbf053554bb909c37ec79be1a", "Complete in under 04:00", StarType.MinTime),
				new StarInfo(532L, "ac633c1cbf3212d4f95012155cd973e3", "Complete in under 01:00", StarType.MinTime),
				new StarInfo(533L, "245dcd87539561241bc955e5fa833fab", "No Deaths", StarType.NoDeaths),
				new StarInfo(534L, "9e048a77386525d4297f9775efcb19bc", "Reach a speed of 5.5", StarType.Challenge),
				new StarInfo(535L, "3a0ab619a819e514cb7aa6c7ceaa3175", "Grab the golden pin", StarType.GoldenPin)
			}),
			new CourseInfo("Wind Tunnel Mastery", new StarInfo[6]
			{
				new StarInfo(540L, "cd8c91a38849df5459afed878e70071b", "Complete the course", StarType.CourseComplete),
				new StarInfo(541L, "bdf016c29782aae43b9774c23d505fd0", "Complete in under 01:00", StarType.MinTime),
				new StarInfo(542L, "a7ce1e8f9ec2b6948a3b6ad889c26876", "Complete in under 00:30", StarType.MinTime),
				new StarInfo(543L, "2a07db3d496a8ac4fa4ab923375af82f", "No Deaths", StarType.NoDeaths),
				new StarInfo(544L, "b5c4c4bffc5aac04c864a1f502e10e35", "Spend less than 5 seconds on the ground", StarType.Challenge),
				new StarInfo(545L, "7ed7e2810fd00a14aaea4f267e33400e", "Grab the golden pin", StarType.GoldenPin)
			}),
			new CourseInfo("Honors Gym Class", new StarInfo[6]
			{
				new StarInfo(550L, "878f8f8195d19424aa87e2208d772141", "Complete the course", StarType.CourseComplete),
				new StarInfo(551L, "5ea9aa8d87657b944b5c2dcc3d4cb3e3", "Complete in under 04:30", StarType.MinTime),
				new StarInfo(552L, "ccf6b59e15b3b7d4b8b69bbc4dbcda13", "Complete in under 02:00", StarType.MinTime),
				new StarInfo(553L, "61f2faa484a77ca4f946157b8a8db437", "No Deaths", StarType.NoDeaths),
				new StarInfo(554L, "837d73aefc94673408942e14f960f13a", "Reach a speed of 9", StarType.Challenge),
				new StarInfo(555L, "a45613d4c2daadb4aa581548048d2c7a", "Grab the golden pin", StarType.GoldenPin)
			}),
			new CourseInfo("Pogo Trial", CourseType.Pogo, new StarInfo[1]
			{
				new StarInfo(560L, "18fb5a39cfc1f434694fdb7f9f2e87b2", "Find all the checkpoints using the Pogo Stick", StarType.TrialComplete)
			}),
			new CourseInfo("Tiny Toy Trial", CourseType.TinyToy, new StarInfo[1]
			{
				new StarInfo(561L, "a4cb9f0819847fa4a85dc913af64ac57", "Get to the finish line", StarType.TrialComplete)
			}),
			new CourseInfo("Jetpack Trial", CourseType.Jetpack, new StarInfo[1]
			{
				new StarInfo(562L, "57638f812bae42d43b2a164910db9f86", "Find all the checkpoints using the Jetpack", StarType.TrialComplete)
			}),
			new CourseInfo("All Course Marathon", CourseType.AllCourseMarathon, new StarInfo[1]
			{
				new StarInfo(563L, "4ed34eb6dd88bce4e8f33c59d6a122f5", "Complete the course", StarType.TrialComplete)
			})
		});

		public static WorldInfo Basement
		{
			get
			{
				//IL_0587: Unknown result type (might be due to invalid IL or missing references)
				//IL_05ae: Unknown result type (might be due to invalid IL or missing references)
				//IL_05d5: Unknown result type (might be due to invalid IL or missing references)
				//IL_05fc: Unknown result type (might be due to invalid IL or missing references)
				WorldInfo worldInfo = new WorldInfo(WorldSelect.Basement, 600, "baf5e18a2fbcc64409f83e53e836cb42", "basement", "Basement", new CourseInfo[10]
				{
					new CourseInfo("Race to the Summit", new StarInfo[7]
					{
						new StarInfo(600L, "e9684256332e65f418b64e8d7c7f1083", "Complete the course", StarType.CourseComplete),
						new StarInfo(601L, "7ab28797b20035d488ff0f3c0cfc1c98", "Complete in under 05:00", StarType.MinTime),
						new StarInfo(602L, "65445040deaac5e439c9926b978befb8", "Complete in under 02:00", StarType.MinTime),
						new StarInfo(603L, "3c9e33538aac447439e7a663e123652c", "No Deaths", StarType.NoDeaths),
						new StarInfo(604L, "ce2c9f759d68d004ba81ee6cddb350bc", "Grab the golden pin", StarType.GoldenPin),
						new StarInfo(605L, "6d2fd769cbf276844aa8000559cf1dde", "Find the hidden G.A.T. comic", StarType.Comic),
						new StarInfo(606L, "d7f3d5b0a214e734aaa4bf3c163437d7", "Buddy Mode", StarType.Buddy)
					}),
					new CourseInfo("Lights Out", new StarInfo[7]
					{
						new StarInfo(610L, "2567589f5e43ea64b90b794dc26ad549", "Complete the course", StarType.CourseComplete),
						new StarInfo(611L, "f06fe218b38d7a74bb24f0519376abfa", "Complete in under 03:00", StarType.MinTime),
						new StarInfo(612L, "d45f9fffe87307a45b29d8e206340869", "Complete in under 00:45", StarType.MinTime),
						new StarInfo(613L, "85a44c29137af204082bf25a249fb034", "No Deaths", StarType.NoDeaths),
						new StarInfo(614L, "a9fe5a26ad9c854488e1af94f556a140", "Grab the golden pin", StarType.GoldenPin),
						new StarInfo(615L, "b469c7dc9ab662e4a9e49c9bfb0af06e", "Find the hidden G.A.T. comic", StarType.Comic),
						new StarInfo(616L, "bdeea14bf70a23d4399cabe73c3b0f63", "Buddy Mode", StarType.Buddy)
					}),
					new CourseInfo("Temple Sprint", new StarInfo[7]
					{
						new StarInfo(620L, "7a9fc04771d0bc74cb3eb77a37154b04", "Complete the course", StarType.CourseComplete),
						new StarInfo(621L, "e51bf9051e4f37246a94bcc0a2623cc6", "Complete in under 04:20", StarType.MinTime),
						new StarInfo(622L, "990e4a1fe47afba429bff232c94a4f72", "Complete in under 01:30", StarType.MinTime),
						new StarInfo(623L, "85a44c29137af204082bf25a249fb034", "No Deaths", StarType.NoDeaths),
						new StarInfo(624L, "48afaf66fe2ec6c41834505aa259bb09", "Grab the golden pin", StarType.GoldenPin),
						new StarInfo(625L, "9ef52ac567b7f134dbb25daa37cb20fb", "Find the hidden G.A.T. comic", StarType.Comic),
						new StarInfo(626L, "887c43d4f3391654ea31c1c63502d4f2", "Buddy Mode", StarType.Buddy)
					}),
					new CourseInfo("Fancy Footwork", new StarInfo[7]
					{
						new StarInfo(630L, "23bd55daa347ba2479460ba058dda3dc", "Complete the course", StarType.CourseComplete),
						new StarInfo(631L, "5fb475ac42879ff4c95f3108e99aa5ab", "Complete in under 06:00", StarType.MinTime),
						new StarInfo(632L, "60734bb36a050544587517fc1d07b0a8", "Complete in under 02:00", StarType.MinTime),
						new StarInfo(633L, "1f474d92398472040b1fcfa02c69e470", "No Deaths", StarType.NoDeaths),
						new StarInfo(634L, "f7a769806969c2e4f952e731eeaed8f4", "Grab the golden pin", StarType.GoldenPin),
						new StarInfo(635L, "ba6127dff14d6cc4fb43181bc5ab2da2", "Find the hidden G.A.T. comic", StarType.Comic),
						new StarInfo(636L, "2eab13332f36cee418049ace462d3afc", "Buddy Mode", StarType.Buddy)
					}),
					new CourseInfo("Minecart Carnage", new StarInfo[7]
					{
						new StarInfo(640L, "c4f662f027b94e04b9b7515ca4697cb1", "Complete the course", StarType.CourseComplete),
						new StarInfo(641L, "820f31c7b04f8234689d920452441a02", "Complete in under 08:00", StarType.MinTime),
						new StarInfo(642L, "3c1f4f9c6972bab4ebf185a920c02d59", "Complete in under 02:45", StarType.MinTime),
						new StarInfo(643L, "4a3d5f503d20c4d4b8a7eb35549d2f0d", "No Deaths", StarType.NoDeaths),
						new StarInfo(644L, "b54421460675e7041b5f8579a3e986f9", "Grab the golden pin", StarType.GoldenPin),
						new StarInfo(645L, "474bf210742ef8349a3704799ee50cab", "Find the hidden G.A.T. comic", StarType.Comic),
						new StarInfo(646L, "8bea8301696abde4d949694e60998281", "Buddy Mode", StarType.Buddy)
					}),
					new CourseInfo("Chase The Meaning", new StarInfo[7]
					{
						new StarInfo(650L, "f41dcc3163d3a6e44b1e63e50aef6203", "Complete the course", StarType.CourseComplete),
						new StarInfo(651L, "632f4236200df684097e0c208be9f7cc", "Complete in under 03:00", StarType.MinTime),
						new StarInfo(652L, "e8a89364a03ff9148b9e8fdd8cef0881", "Complete in under 01:30", StarType.MinTime),
						new StarInfo(653L, "2ae00895938d8944b92613a97364ddae", "Tag your sister", StarType.Challenge),
						new StarInfo(654L, "dcdf12844ab861b4aa611b5d82b86d69", "Grab the golden pin", StarType.GoldenPin),
						new StarInfo(655L, "381a82e80aa2b544f93638befa072438", "Find the hidden G.A.T. comic", StarType.Comic),
						new StarInfo(656L, "8e6b8c0b2c298004dad92e10625712b9", "Wild Teddy Chase", StarType.BuddyChase)
					}),
					new CourseInfo("Pogo Trial", CourseType.Pogo, new StarInfo[1]
					{
						new StarInfo(660L, "0dd75e2d4a1de8a41ad6d6d559efc3ea", "Find all the checkpoints using the Pogo Stick", StarType.TrialComplete)
					}),
					new CourseInfo("Tiny Toy Trial", CourseType.TinyToy, new StarInfo[1]
					{
						new StarInfo(661L, "ae2f8bc0810d0b34bb39bafa448eb903", "Get to the finish line", StarType.TrialComplete)
					}),
					new CourseInfo("Jetpack Trial", CourseType.Jetpack, new StarInfo[1]
					{
						new StarInfo(662L, "d314f1d6e3dfa7f44b710b731fc91a1b", "Find all the checkpoints using the Jetpack", StarType.TrialComplete)
					}),
					new CourseInfo("All Course Marathon", CourseType.AllCourseMarathon, new StarInfo[1]
					{
						new StarInfo(663L, "2b2d24eea94f2884db79dd2a24720bea", "Complete the course", StarType.TrialComplete)
					})
				});
				worldInfo.ForceFields = new ForceFieldInfo[4]
				{
					new ForceFieldInfo(610L, "Foyer/Living Room", new Vector3(37.874f, 8.016f, 10.712f)),
					new ForceFieldInfo(611L, "Foyer/Dining Room", new Vector3(36.5f, 8.05f, 18f)),
					new ForceFieldInfo(612L, "Kitchen/Basement Storage", new Vector3(26.247f, 7.945f, 19.363f)),
					new ForceFieldInfo(613L, "Basement Storage/Den", new Vector3(34.6f, 3.35f, 30.2f))
				};
				return worldInfo;
			}
		}

		public static WorldInfo RoccosArcade => new WorldInfo(WorldSelect.RoccosArcade, 700, "", "fun_centre", "Rocco's Arcade", new CourseInfo[12]
		{
			new CourseInfo("Arcade Action", new StarInfo[7]
			{
				new StarInfo(700L, "def601d8323ecaf4fb65504a3f73192c", "Complete the course", StarType.CourseComplete),
				new StarInfo(701L, "9fc84b49f92528142b1d847cbc2d7076", "Complete in under 02:50", StarType.MinTime),
				new StarInfo(702L, "6c06cd3d4a063bd43b7f3907c1cb845b", "Complete in under 01:15", StarType.MinTime),
				new StarInfo(703L, "d4cb50cf712af3b42b2913bf1488b220", "No Deaths", StarType.NoDeaths),
				new StarInfo(704L, "879548bdea3315a468c217c7347d1156", "Grab the golden pin", StarType.GoldenPin),
				new StarInfo(705L, "fd1c5375abccef44cb5859c68e8ae767", "Find the Mini Rocco", StarType.Comic),
				new StarInfo(706L, "b7da07bfefcdab049ad77dfd640733ca", "Buddy Mode", StarType.Buddy)
			}),
			new CourseInfo("Rocco's Rumpus Room", new StarInfo[7]
			{
				new StarInfo(710L, "4360d78fb741961408ad39277bab8569", "Complete the course", StarType.CourseComplete),
				new StarInfo(711L, "509cc0ce876e60f44825c9fec48d2846", "Complete in under 02:20", StarType.MinTime),
				new StarInfo(712L, "43ef3811606de8f41a7f04dba809bbbd", "Complete in under 00:45", StarType.MinTime),
				new StarInfo(713L, "c8c5fd1cbefd8b147a8fc93d201f5177", "Spend less than 24 seconds on the ground", StarType.Challenge),
				new StarInfo(714L, "46be6e61ceff30040b2d5ad104fe427f", "Grab the golden pin", StarType.GoldenPin),
				new StarInfo(715L, "4661b76be6f35644d9c4ecd5077cdf45", "Find the Mini Rocco", StarType.Comic),
				new StarInfo(716L, "58fc1ca34eabb944d96dd3b79f8046f0", "Buddy Mode", StarType.Buddy)
			}),
			new CourseInfo("Employees Only", new StarInfo[7]
			{
				new StarInfo(720L, "f00b65ab24cc4294eb1b6f789b4fa5e5", "Complete the course", StarType.CourseComplete),
				new StarInfo(721L, "5590fcc88aea11d4bbde7f9154311c9a", "Complete in under 04:20", StarType.MinTime),
				new StarInfo(722L, "75ca91dee56785c4eb545f27a08f6477", "Complete in under 01:20", StarType.MinTime),
				new StarInfo(723L, "85465cc4d88f37747874af642e374fc4", "No Deaths", StarType.NoDeaths),
				new StarInfo(724L, "f3970acce4d9d0249b4525dea7e29dbe", "Find and open all the gas valves", StarType.Challenge),
				new StarInfo(725L, "46e85cc6d2ecc284480793e01c66ad09", "Find the Mini Rocco", StarType.Comic),
				new StarInfo(726L, "61e4e68c37bac3849a98162aad462baa", "Buddy Mode", StarType.Buddy)
			}),
			new CourseInfo("Storage Room Spree", new StarInfo[7]
			{
				new StarInfo(730L, "12080125e1eed3e4ea145410df8528e8", "Complete the course", StarType.CourseComplete),
				new StarInfo(731L, "ff3e742bc84f4b242a4ad86c72a50f3c", "Complete in under 02:00", StarType.MinTime),
				new StarInfo(732L, "daceedb0d8bde56419ddc1f8c8f05d08", "Complete in under 00:45", StarType.MinTime),
				new StarInfo(733L, "21bed3d7ca947254a95a9ac508584f0e", "Find and open all the gas valves", StarType.Challenge),
				new StarInfo(734L, "f191a515520153d42a31e4361daa25d8", "Grab the golden pin", StarType.GoldenPin),
				new StarInfo(735L, "16cd44721efa3e647b6dc75a424fa585", "Find the Mini Rocco", StarType.Comic),
				new StarInfo(736L, "2f681afeeb6dfd245bcff249e8ca150d", "Buddy Mode", StarType.Buddy)
			}),
			new CourseInfo("Birthday Blowout", new StarInfo[7]
			{
				new StarInfo(740L, "7b6ec6b095231fb4d84022e058bb9f53", "Complete the course", StarType.CourseComplete),
				new StarInfo(741L, "8aafd5d3de65d9e4b90d2875e2b67b13", "Complete in under 03:00", StarType.MinTime),
				new StarInfo(742L, "6e354066417749141a55c5c916ee99c3", "Complete in under 00:50", StarType.MinTime),
				new StarInfo(743L, "5272c3fadb5946f499db0b553fb0eefb", "Find and open all the gas valves", StarType.Challenge),
				new StarInfo(744L, "ce5b071025807c444ae7da9e7e348687", "Grab the golden pin", StarType.GoldenPin),
				new StarInfo(745L, "9a85e15e907facb4fb6a48e0e0bd468b", "No Deaths", StarType.NoDeaths),
				new StarInfo(746L, "e6f8303c99230264bad389031ad58fc0", "Buddy Mode", StarType.Buddy)
			}),
			new CourseInfo("Chase to the Arcade", new StarInfo[7]
			{
				new StarInfo(750L, "e442a16f1da076a409aadf5584f28161", "Complete the course", StarType.CourseComplete),
				new StarInfo(751L, "df5fae0241f4cf443bba120eb89713ca", "Complete in under 00:55", StarType.MinTime),
				new StarInfo(752L, "c8e591626c816e344be403b1411e1b30", "Complete in under 00:35", StarType.MinTime),
				new StarInfo(753L, "1a1eb323b4515c74793443fe24a91a9e", "Tag your sister", StarType.Challenge),
				new StarInfo(754L, "d494f370cec9bc84ca84837a50f071f7", "Grab the golden pin", StarType.GoldenPin),
				new StarInfo(755L, "47f87b32bbb4ac746ab54919f323786f", "Find the Mini Rocco", StarType.Comic),
				new StarInfo(756L, "dfe34b01be6b7814ba491f4da69fa75f", "Where's Buddy?", StarType.BuddyChase)
			}),
			new CourseInfo("Pogo Trial 1", CourseType.Pogo, new StarInfo[1]
			{
				new StarInfo(760L, "21b743df5b4bf694498aa3767394ba60", "Find all the checkpoints using the Pogo Stick", StarType.TrialComplete)
			}),
			new CourseInfo("Pogo Trial 2", CourseType.Pogo, new StarInfo[1]
			{
				new StarInfo(761L, "bb25c6331ce2f6f4e9e33f0ad73b1364", "Find all the checkpoints using the Pogo Stick", StarType.TrialComplete)
			}),
			new CourseInfo("Tiny Toy Trial 1", CourseType.TinyToy, new StarInfo[1]
			{
				new StarInfo(762L, "2001a9f8edfe4d845aa91cd9f12cabd7", "Get to the finish line", StarType.TrialComplete)
			}),
			new CourseInfo("Tiny Toy Trial 2", CourseType.TinyToy, new StarInfo[1]
			{
				new StarInfo(763L, "9dc7036229864094bae7c57f1f4df399", "Get to the finish line", StarType.TrialComplete)
			}),
			new CourseInfo("Jetpack Trial", CourseType.Jetpack, new StarInfo[1]
			{
				new StarInfo(764L, "6bed6a2b0e10a754d83714792bc01057", "Find all the checkpoints using the Jetpack", StarType.TrialComplete)
			}),
			new CourseInfo("All Course Marathon", CourseType.AllCourseMarathon, new StarInfo[1]
			{
				new StarInfo(765L, "84226baa8e2082048869e81e1b53e167", "Complete the course", StarType.TrialComplete)
			})
		});

		public static IEnumerable<WorldInfo> AllWorlds => new <>z__ReadOnlyArray<WorldInfo>(new WorldInfo[7] { GymClass, Playground, School, Wholesale, MasterClass, Basement, RoccosArcade });
	}
}
namespace HotLavaArchipelagoPlugin.Factories
{
	internal static class RewardVisualizationFactory
	{
		public static RewardVisualization FromImage(GiftDropVisualization giftDropVisualization, byte[] image)
		{
			return FromSprite(giftDropVisualization, SpriteFactory.FromImage(image));
		}

		public static RewardVisualization FromSprite(GiftDropVisualization giftDropVisualization, Sprite sprite)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			ItemMetaDataEntry val = ScriptableObject.CreateInstance<ItemMetaDataEntry>();
			val.m_Category = (eItemCategory)4;
			val.m_Sprite = sprite;
			RewardVisualization obj = giftDropVisualization.ItemViz[4].ShallowCopy();
			obj.Load(val);
			return obj;
		}

		public static RewardVisualization GetArchipelagoReward(GiftDropVisualization giftDropVisualization)
		{
			return FromSprite(giftDropVisualization, SpriteFactory.GetArchipelagoSprite());
		}
	}
	internal class SpriteFactory
	{
		public static Sprite FromImage(byte[] image)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(256, 256);
			ImageConversion.LoadImage(val, image);
			return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f);
		}

		public static Sprite GetArchipelagoSprite()
		{
			return FromImage(Resources.ArchipelagoLogo);
		}
	}
}
namespace HotLavaArchipelagoPlugin.Extensions
{
	internal static class ArchipelagoColorExtensionMethods
	{
		public static string ToHexColorCode(this Color color)
		{
			return "#" + ((Color)(ref color)).R.ToString("X2") + ((Color)(ref color)).G.ToString("X2") + ((Color)(ref color)).B.ToString("X2");
		}
	}
	internal static class LevelMetaDataExtensionMethods
	{
		public static string GetWorldName(this LevelMetaData levelMetaData)
		{
			return ((Object)levelMetaData).name.Replace("_meta_data", "");
		}
	}
}
namespace HotLavaArchipelagoPlugin.Enums
{
	internal enum CourseType
	{
		Standard,
		Pogo,
		TinyToy,
		Jetpack,
		Chase,
		AllCourseMarathon
	}
	internal enum StarType
	{
		Generic,
		CourseComplete,
		MinTime,
		NoDeaths,
		Challenge,
		GoldenPin,
		Comic,
		TrialComplete,
		Buddy,
		BuddyChase
	}
}
namespace HotLavaArchipelagoPlugin.Archipelago
{
	internal class Multiworld
	{
		private static Multiworld? _instance;

		public string PlayerName = "Unknown";

		internal ArchipelagoSession ArchipelagoSession;

		internal SlotData SlotData = new SlotData();

		private DeathLinkService? DeathLinkService;

		private Dictionary<long, ScoutedItemInfo> ScoutedItems = new Dictionary<long, ScoutedItemInfo>();

		private Queue<ScoutedItemInfo> QueuedAwardItems = new Queue<ScoutedItemInfo>();

		private int _deathCount;

		private int _deathsToSendDeathLink = 5;

		public static Multiworld Instance
		{
			get
			{
				if (_instance == null)
				{
					throw new NullReferenceException("Multiworld has not been initialized");
				}
				return _instance;
			}
		}

		public static bool Connected => _instance != null;

		public Multiworld(ArchipelagoSession archipelagoSession)
		{
			ArchipelagoSession = archipelagoSession;
		}

		public static async Task Connect(string message)
		{
			try
			{
				string text = Plugin.ConfigArchipelagoHost.Value;
				int num = Plugin.ConfigArchipelagoPort.Value;
				string playerName = Plugin.ConfigArchipelagoPlayerName.Value;
				string password = Plugin.ConfigArchipelagoPassword.Value;
				string[] array = message.Trim().Split(" ");
				if (array.Length > 1)
				{
					string text2 = array[1];
					if (!text2.Contains("://"))
					{
						text2 = "http://" + text2;
					}
					Uri uri;
					try
					{
						uri = new Uri(text2);
					}
					catch (Exception)
					{
						UIHelper.ShowPopup("Failed to parse provided URL for room");
						return;
					}
					text = uri.Host;
					num = uri.Port;
					if (array.Length > 2)
					{
						playerName = array[2];
					}
					password = ((array.Length > 3) ? array[3] : null);
				}
				ArchipelagoSession archipelagoSession = ArchipelagoSessionFactory.CreateSession(text,