Decompiled source of Silksong BingoSync v1.2.2

plugins/BingoAPI.dll

Decompiled a month ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.WebSockets;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using BingoAPI.Conditions.Attributes;
using BingoAPI.Conditions.Factories;
using BingoAPI.Conditions.Interfaces;
using BingoAPI.Events;
using BingoAPI.Events.BuiltIn;
using BingoAPI.Goals;
using BingoAPI.Helpers;
using BingoAPI.Models;
using BingoAPI.Models.Settings;
using BingoAPI.Networking.Clients;
using BingoAPI.Networking.Converters;
using BingoAPI.Networking.DTOs;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")]
[assembly: AssemblyCompany("WarperSan")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Library that allows to communicate with BingoSync's servers through code")]
[assembly: AssemblyFileVersion("0.1.5.0")]
[assembly: AssemblyInformationalVersion("0.1.5-alpha+b7cb9dd026341a5c323cf8a1570ec19c245e36bf")]
[assembly: AssemblyProduct("BingoAPI")]
[assembly: AssemblyTitle("BingoAPI")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/WarperSan/BingoAPI")]
[assembly: AssemblyVersion("0.0.0.0")]
[module: RefSafetyRules(11)]
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class IsReadOnlyAttribute : Attribute
	{
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace System
{
	[ExcludeFromCodeCoverage]
	[Embedded]
	internal readonly struct Index : IEquatable<Index>
	{
		private static class ThrowHelper
		{
			[DoesNotReturn]
			public static void ThrowValueArgumentOutOfRange_NeedNonNegNumException()
			{
				throw new ArgumentOutOfRangeException("value", "Non-negative number required.");
			}
		}

		private readonly int _value;

		public static Index Start => new Index(0);

		public static Index End => new Index(-1);

		public int Value
		{
			get
			{
				if (_value < 0)
				{
					return ~_value;
				}
				return _value;
			}
		}

		public bool IsFromEnd => _value < 0;

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Index(int value, bool fromEnd = false)
		{
			if (value < 0)
			{
				ThrowHelper.ThrowValueArgumentOutOfRange_NeedNonNegNumException();
			}
			if (fromEnd)
			{
				_value = ~value;
			}
			else
			{
				_value = value;
			}
		}

		private Index(int value)
		{
			_value = value;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Index FromStart(int value)
		{
			if (value < 0)
			{
				ThrowHelper.ThrowValueArgumentOutOfRange_NeedNonNegNumException();
			}
			return new Index(value);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Index FromEnd(int value)
		{
			if (value < 0)
			{
				ThrowHelper.ThrowValueArgumentOutOfRange_NeedNonNegNumException();
			}
			return new Index(~value);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public int GetOffset(int length)
		{
			int num = _value;
			if (IsFromEnd)
			{
				num += length + 1;
			}
			return num;
		}

		public override bool Equals([NotNullWhen(true)] object? value)
		{
			if (value is Index)
			{
				return _value == ((Index)value)._value;
			}
			return false;
		}

		public bool Equals(Index other)
		{
			return _value == other._value;
		}

		public override int GetHashCode()
		{
			return _value;
		}

		public static implicit operator Index(int value)
		{
			return FromStart(value);
		}

		public override string ToString()
		{
			if (IsFromEnd)
			{
				return ToStringFromEnd();
			}
			return ((uint)Value).ToString();
		}

		private string ToStringFromEnd()
		{
			return "^" + Value;
		}
	}
	[ExcludeFromCodeCoverage]
	[Embedded]
	internal readonly struct Range : IEquatable<Range>
	{
		private static class HashHelpers
		{
			public static int Combine(int h1, int h2)
			{
				uint num = (uint)((h1 << 5) | (h1 >>> 27));
				return ((int)num + h1) ^ h2;
			}
		}

		private static class ThrowHelper
		{
			[DoesNotReturn]
			public static void ThrowArgumentOutOfRangeException()
			{
				throw new ArgumentOutOfRangeException("length");
			}
		}

		public Index Start { get; }

		public Index End { get; }

		public static Range All => Index.Start..Index.End;

		public Range(Index start, Index end)
		{
			Start = start;
			End = end;
		}

		public override bool Equals([NotNullWhen(true)] object? value)
		{
			if (value is Range { Start: var start } range && start.Equals(Start))
			{
				return range.End.Equals(End);
			}
			return false;
		}

		public bool Equals(Range other)
		{
			if (other.Start.Equals(Start))
			{
				return other.End.Equals(End);
			}
			return false;
		}

		public override int GetHashCode()
		{
			return HashHelpers.Combine(Start.GetHashCode(), End.GetHashCode());
		}

		public override string ToString()
		{
			return Start.ToString() + ".." + End;
		}

		public static Range StartAt(Index start)
		{
			return start..Index.End;
		}

		public static Range EndAt(Index end)
		{
			return Index.Start..end;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public (int Offset, int Length) GetOffsetAndLength(int length)
		{
			Index start = Start;
			int num = ((!start.IsFromEnd) ? start.Value : (length - start.Value));
			Index end = End;
			int num2 = ((!end.IsFromEnd) ? end.Value : (length - end.Value));
			if ((uint)num2 > (uint)length || (uint)num > (uint)num2)
			{
				ThrowHelper.ThrowArgumentOutOfRangeException();
			}
			return (Offset: num, Length: num2 - num);
		}
	}
}
namespace System.Diagnostics.CodeAnalysis
{
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, Inherited = false)]
	[ExcludeFromCodeCoverage]
	[Embedded]
	internal sealed class AllowNullAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Constructor, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	[Embedded]
	internal sealed class SetsRequiredMembersAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
	[ExcludeFromCodeCoverage]
	[Embedded]
	internal sealed class MemberNotNullAttribute : Attribute
	{
		public string[] Members { get; }

		public MemberNotNullAttribute(string member)
		{
			Members = new string[1] { member };
		}

		public MemberNotNullAttribute(params string[] members)
		{
			Members = members;
		}
	}
	[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
	[ExcludeFromCodeCoverage]
	[Embedded]
	internal sealed class MaybeNullWhenAttribute : Attribute
	{
		public bool ReturnValue { get; }

		public MaybeNullWhenAttribute(bool returnValue)
		{
			ReturnValue = returnValue;
		}
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, Inherited = false)]
	[ExcludeFromCodeCoverage]
	[Embedded]
	internal sealed class DisallowNullAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Parameter | AttributeTargets.ReturnValue, AllowMultiple = true, Inherited = false)]
	[ExcludeFromCodeCoverage]
	[Embedded]
	internal sealed class NotNullIfNotNullAttribute : Attribute
	{
		public string ParameterName { get; }

		public NotNullIfNotNullAttribute(string parameterName)
		{
			ParameterName = parameterName;
		}
	}
	[AttributeUsage(AttributeTargets.Method, Inherited = false)]
	[ExcludeFromCodeCoverage]
	[Embedded]
	internal sealed class DoesNotReturnAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue, Inherited = false)]
	[ExcludeFromCodeCoverage]
	[Embedded]
	internal sealed class NotNullAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	[Embedded]
	internal sealed class UnscopedRefAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
	[ExcludeFromCodeCoverage]
	[Embedded]
	internal sealed class DoesNotReturnIfAttribute : Attribute
	{
		public bool ParameterValue { get; }

		public DoesNotReturnIfAttribute(bool parameterValue)
		{
			ParameterValue = parameterValue;
		}
	}
	[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
	[ExcludeFromCodeCoverage]
	[Embedded]
	internal sealed class NotNullWhenAttribute : Attribute
	{
		public bool ReturnValue { get; }

		public NotNullWhenAttribute(bool returnValue)
		{
			ReturnValue = returnValue;
		}
	}
	[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
	[ExcludeFromCodeCoverage]
	[Embedded]
	internal sealed class MemberNotNullWhenAttribute : Attribute
	{
		public bool ReturnValue { get; }

		public string[] Members { get; }

		public MemberNotNullWhenAttribute(bool returnValue, string member)
		{
			ReturnValue = returnValue;
			Members = new string[1] { member };
		}

		public MemberNotNullWhenAttribute(bool returnValue, params string[] members)
		{
			ReturnValue = returnValue;
			Members = members;
		}
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue, Inherited = false)]
	[ExcludeFromCodeCoverage]
	[Embedded]
	internal sealed class MaybeNullAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	[Embedded]
	internal sealed class StringSyntaxAttribute : Attribute
	{
		public const string CompositeFormat = "CompositeFormat";

		public const string DateOnlyFormat = "DateOnlyFormat";

		public const string DateTimeFormat = "DateTimeFormat";

		public const string EnumFormat = "EnumFormat";

		public const string GuidFormat = "GuidFormat";

		public const string Json = "Json";

		public const string NumericFormat = "NumericFormat";

		public const string Regex = "Regex";

		public const string TimeOnlyFormat = "TimeOnlyFormat";

		public const string TimeSpanFormat = "TimeSpanFormat";

		public const string Uri = "Uri";

		public const string Xml = "Xml";

		public string Syntax { get; }

		public object?[] Arguments { get; }

		public StringSyntaxAttribute(string syntax)
		{
			Syntax = syntax;
			Arguments = new object[0];
		}

		public StringSyntaxAttribute(string syntax, params object?[] arguments)
		{
			Syntax = syntax;
			Arguments = arguments;
		}
	}
	[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false)]
	[ExcludeFromCodeCoverage]
	[Embedded]
	internal sealed class ExperimentalAttribute : Attribute
	{
		public string DiagnosticId { get; }

		public string? UrlFormat { get; set; }

		public ExperimentalAttribute(string diagnosticId)
		{
			DiagnosticId = diagnosticId;
		}
	}
	[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
	[ExcludeFromCodeCoverage]
	[Embedded]
	internal sealed class ConstantExpectedAttribute : Attribute
	{
		public object? Min { get; set; }

		public object? Max { get; set; }
	}
}
namespace System.Runtime.Versioning
{
	[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false)]
	[ExcludeFromCodeCoverage]
	[Embedded]
	internal sealed class RequiresPreviewFeaturesAttribute : Attribute
	{
		public string? Message { get; }

		public string? Url { get; set; }

		public RequiresPreviewFeaturesAttribute()
		{
		}

		public RequiresPreviewFeaturesAttribute(string? message)
		{
			Message = message;
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Parameter, Inherited = true, AllowMultiple = false)]
	[ExcludeFromCodeCoverage]
	[Embedded]
	internal sealed class ParamCollectionAttribute : Attribute
	{
	}
	[EditorBrowsable(EditorBrowsableState.Never)]
	[ExcludeFromCodeCoverage]
	[Embedded]
	internal static class IsExternalInit
	{
	}
	[EditorBrowsable(EditorBrowsableState.Never)]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false)]
	[ExcludeFromCodeCoverage]
	[Embedded]
	internal sealed class ExtensionMarkerAttribute : Attribute
	{
		public string Name { get; }

		public ExtensionMarkerAttribute(string name)
		{
			Name = name;
		}
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface, Inherited = false)]
	[ExcludeFromCodeCoverage]
	[Embedded]
	internal sealed class CollectionBuilderAttribute : Attribute
	{
		public Type BuilderType { get; }

		public string MethodName { get; }

		public CollectionBuilderAttribute(Type builderType, string methodName)
		{
			BuilderType = builderType;
			MethodName = methodName;
		}
	}
	[AttributeUsage(AttributeTargets.Class, Inherited = false)]
	[ExcludeFromCodeCoverage]
	[Embedded]
	internal sealed class CompilerLoweringPreserveAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Method, Inherited = false)]
	[ExcludeFromCodeCoverage]
	[Embedded]
	internal sealed class ModuleInitializerAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	[Embedded]
	internal sealed class OverloadResolutionPriorityAttribute : Attribute
	{
		public int Priority { get; }

		public OverloadResolutionPriorityAttribute(int priority)
		{
			Priority = priority;
		}
	}
	[AttributeUsage(AttributeTargets.All, AllowMultiple = true, Inherited = false)]
	[ExcludeFromCodeCoverage]
	[Embedded]
	internal sealed class CompilerFeatureRequiredAttribute : Attribute
	{
		public const string RefStructs = "RefStructs";

		public const string RequiredMembers = "RequiredMembers";

		public string FeatureName { get; }

		public bool IsOptional { get; set; }

		public CompilerFeatureRequiredAttribute(string featureName)
		{
			FeatureName = featureName;
		}
	}
	[AttributeUsage(AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Event | AttributeTargets.Interface, Inherited = false)]
	[ExcludeFromCodeCoverage]
	[Embedded]
	internal sealed class SkipLocalsInitAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
	[EditorBrowsable(EditorBrowsableState.Never)]
	[ExcludeFromCodeCoverage]
	[Embedded]
	internal sealed class RequiresLocationAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	[Embedded]
	internal sealed class CallerArgumentExpressionAttribute : Attribute
	{
		public string ParameterName { get; }

		public CallerArgumentExpressionAttribute(string parameterName)
		{
			ParameterName = parameterName;
		}
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false, AllowMultiple = false)]
	[ExcludeFromCodeCoverage]
	[Embedded]
	internal sealed class AsyncMethodBuilderAttribute : Attribute
	{
		public Type BuilderType { get; }

		public AsyncMethodBuilderAttribute(Type builderType)
		{
			BuilderType = builderType;
		}
	}
	[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	[Embedded]
	internal sealed class InterpolatedStringHandlerArgumentAttribute : Attribute
	{
		public string[] Arguments { get; }

		public InterpolatedStringHandlerArgumentAttribute(string argument)
		{
			Arguments = new string[1] { argument };
		}

		public InterpolatedStringHandlerArgumentAttribute(params string[] arguments)
		{
			Arguments = arguments;
		}
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	[Embedded]
	internal sealed class RequiredMemberAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	[Embedded]
	internal sealed class InterpolatedStringHandlerAttribute : Attribute
	{
	}
}
namespace Microsoft.CodeAnalysis
{
	[Embedded]
	[AttributeUsage(AttributeTargets.All)]
	[ExcludeFromCodeCoverage]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace BingoAPI.Networking
{
	internal sealed class RequestBuilder
	{
		private HttpMethod _method = HttpMethod.Get;

		private string? _endpoint;

		private HttpContent? _content;

		private RequestBuilder WithMethod(HttpMethod method)
		{
			_method = method;
			return this;
		}

		public RequestBuilder Get()
		{
			return WithMethod(HttpMethod.Get);
		}

		public RequestBuilder Post()
		{
			return WithMethod(HttpMethod.Post);
		}

		public RequestBuilder Put()
		{
			return WithMethod(HttpMethod.Put);
		}

		public RequestBuilder ToEndpoint(string endpoint)
		{
			_endpoint = endpoint;
			return this;
		}

		public RequestBuilder WithJson(object json)
		{
			string content = JsonConvert.SerializeObject(json);
			_content = new StringContent(content, Encoding.UTF8, "application/json");
			return this;
		}

		public RequestBuilder WithForm(object form)
		{
			List<KeyValuePair<string, string>> list = new List<KeyValuePair<string, string>>();
			var enumerable = from m in form.GetType().GetMembers(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).Where(delegate(MemberInfo m)
				{
					MemberTypes memberType = m.MemberType;
					return (memberType == MemberTypes.Field || memberType == MemberTypes.Property) ? true : false;
				})
				select new
				{
					Member = m,
					Attribute = m.GetCustomAttribute<DataMemberAttribute>()
				} into m
				where m.Attribute != null
				select m;
			foreach (var item in enumerable)
			{
				string key = item.Attribute?.Name ?? item.Member.Name;
				MemberInfo member = item.Member;
				string text = ((member is FieldInfo fieldInfo) ? fieldInfo.GetValue(form)?.ToString() : ((!(member is PropertyInfo propertyInfo)) ? null : propertyInfo.GetValue(form)?.ToString()));
				string text2 = text;
				if (text2 == null)
				{
					text2 = "";
				}
				list.Add(new KeyValuePair<string, string>(key, text2));
			}
			_content = new FormUrlEncodedContent(list);
			return this;
		}

		public HttpRequestMessage Build()
		{
			HttpRequestMessage httpRequestMessage = new HttpRequestMessage
			{
				Method = _method,
				Content = _content
			};
			if (_endpoint != null)
			{
				httpRequestMessage.RequestUri = new Uri(_endpoint, UriKind.Relative);
			}
			return httpRequestMessage;
		}
	}
	public sealed class Session : IDisposable
	{
		private readonly BingoApiClient _api;

		private readonly BingoSocketClient _socket;

		private readonly EventDispatcher _dispatcher;

		private string? _roomCode;

		public Team Team { get; private set; }

		[MemberNotNullWhen(true, "_roomCode")]
		public bool IsInRoom
		{
			[MemberNotNullWhen(true, "_roomCode")]
			get
			{
				return _roomCode != null;
			}
		}

		public Session(EventDispatcher dispatcher, HttpClient client, Uri socketAddress)
		{
			_dispatcher = dispatcher;
			_api = new BingoApiClient(client);
			_socket = new BingoSocketClient(socketAddress);
		}

		public async Task<bool> CreateRoom(CreateRoomSettings settings, CancellationToken ct = default(CancellationToken))
		{
			throw new NotImplementedException();
		}

		public async Task<bool> JoinRoom(JoinRoomSettings settings, CancellationToken ct = default(CancellationToken))
		{
			if (IsInRoom)
			{
				Log.Error("Tried to join a room while being connected.");
				return false;
			}
			Log.Info("Joining room '" + settings.Code + "'...");
			try
			{
				string socketKey = await _api.JoinRoom(settings, ct);
				await _socket.Connect(socketKey, OnMessageReceived, ct);
				GetSocketInformationResponse getSocketInformationResponse = await _api.GetSocketInformation(socketKey, ct);
				_roomCode = getSocketInformationResponse.Code;
				Team = Team.Red;
				Player player = new Player
				{
					Name = settings.Nickname,
					Team = Team,
					UUID = getSocketInformationResponse.PlayerUUID
				};
				_dispatcher.DispatchConnect(player);
				Log.Info("Room '" + settings.Code + "' was joined.");
				return true;
			}
			catch (Exception arg)
			{
				Log.Error($"Failed to join the room '{settings.Code}': {arg}");
				return false;
			}
		}

		public async Task<bool> LeaveRoom(CancellationToken ct = default(CancellationToken))
		{
			if (!IsInRoom)
			{
				Log.Error("Tried to leave the room before being connected.");
				return false;
			}
			string room = _roomCode;
			Log.Info("Leaving the room '" + room + "'...");
			try
			{
				await _socket.Disconnect(ct);
				_roomCode = null;
				_dispatcher.DispatchDisconnect();
				Log.Info("Left the room '" + room + "'.");
				return true;
			}
			catch (Exception arg)
			{
				Log.Error($"Failed to leave the room '{room}: {arg}");
				return false;
			}
		}

		public async Task<bool> SendMessage(string message, CancellationToken ct = default(CancellationToken))
		{
			if (!IsInRoom)
			{
				Log.Error("Tried to send a message before being connected.");
				return false;
			}
			Log.Info("Sending the following chat message: '" + message + "'...");
			try
			{
				await _api.SendMessage(_roomCode, message, ct);
				Log.Info("Sent the following chat message: '" + message + "'.");
				return true;
			}
			catch (Exception arg)
			{
				Log.Error($"Failed to sent the chat message: {arg}");
				return false;
			}
		}

		public async Task<bool> ChangeTeam(Team team, CancellationToken ct = default(CancellationToken))
		{
			if (!IsInRoom)
			{
				Log.Error("Tried to change team before being connected.");
				return false;
			}
			if (team == Team)
			{
				Log.Error("Tried to change to the same team.");
				return false;
			}
			Log.Info($"Changing team to '{team}'...");
			try
			{
				await _api.ChangeTeam(_roomCode, team, ct);
				Team = team;
				Log.Info($"Changed team to '{team}'.");
				return true;
			}
			catch (Exception arg)
			{
				Log.Error($"Failed to change the team: {arg}");
				return false;
			}
		}

		public async Task<Card?> GetCard(GoalPool pool, CancellationToken ct = default(CancellationToken))
		{
			if (!IsInRoom)
			{
				Log.Error("Tried to get the squares before being connected.");
				return null;
			}
			Log.Info("Getting the squares of the room '" + _roomCode + "'...");
			try
			{
				ICollection<Square> collection = await _api.GetSquares(_roomCode, ct);
				Log.Info($"Got {collection.Count} squares for room '{_roomCode}'.");
				return new Card(collection, pool);
			}
			catch (Exception arg)
			{
				Log.Error($"Failed to get squares for room '{_roomCode}': {arg}");
				return null;
			}
		}

		public async Task<bool> MarkSquare(int index, CancellationToken ct = default(CancellationToken))
		{
			if (!IsInRoom)
			{
				Log.Error("Tried to mark a square before being connected.");
				return false;
			}
			if (Team == Team.None)
			{
				Log.Error("Tried to clear a square without being in a team.");
				return false;
			}
			Log.Info($"Marking the square #{index} for the team '{Team}'...");
			try
			{
				await _api.MarkSquare(_roomCode, Team, index, ct);
				Log.Info($"Marked the square #{index} for the team '{Team}'.");
				return true;
			}
			catch (Exception arg)
			{
				Log.Error($"Failed to mark the square #{index} for the team '{Team}': {arg}");
				return false;
			}
		}

		public async Task<bool> ClearSquare(int index, CancellationToken ct = default(CancellationToken))
		{
			if (!IsInRoom)
			{
				Log.Error("Tried to clear a square before being connected.");
				return false;
			}
			if (Team == Team.None)
			{
				Log.Error("Tried to clear a square without being in a team.");
				return false;
			}
			Log.Info($"Clearing the square #{index} for the team '{Team}'...");
			try
			{
				await _api.ClearSquare(_roomCode, Team, index, ct);
				Log.Info($"Cleared the square #{index} for the team '{Team}'.");
				return true;
			}
			catch (Exception arg)
			{
				Log.Error($"Failed to clear the square #{index} for the team '{Team}': {arg}");
				return false;
			}
		}

		public async Task<bool> RevealCard(CancellationToken ct = default(CancellationToken))
		{
			if (!IsInRoom)
			{
				Log.Error("Tried to reveal the card before being connected.");
				return false;
			}
			Log.Info("Revealing the card for the room '" + _roomCode + "'...");
			try
			{
				await _api.RevealCard(_roomCode, ct);
				Log.Info("Revealed the card for the room '" + _roomCode + "'.");
				return true;
			}
			catch (Exception arg)
			{
				Log.Error($"Failed to reveal the card for the room '{_roomCode}': {arg}");
				return false;
			}
		}

		private void OnMessageReceived(string message)
		{
			IEvent obj = JsonConvert.DeserializeObject<IEvent>(message);
			if (obj == null)
			{
				Log.Warning($"Failed to deserialize the message into a '{typeof(IEvent)}': {message}");
			}
			else
			{
				_dispatcher.Dispatch(obj);
			}
		}

		public void Dispose()
		{
			_socket.Dispose();
		}
	}
}
namespace BingoAPI.Networking.DTOs
{
	internal record ChangeTeamRequest
	{
		[JsonProperty("room")]
		public required string Code { get; init; }

		[JsonProperty("color")]
		public required Team Team { get; init; }

		[CompilerGenerated]
		[SetsRequiredMembers]
		protected ChangeTeamRequest(ChangeTeamRequest original)
		{
			Code = original.Code;
			Team = original.Team;
		}

		public ChangeTeamRequest()
		{
		}
	}
	internal record ClearSquareRequest
	{
		[JsonProperty("room")]
		public required string Code { get; init; }

		[JsonProperty("color")]
		public required Team Team { get; init; }

		[JsonProperty("slot")]
		public required string Index { get; init; }

		[JsonProperty("remove_color")]
		public bool RemoveColor => true;

		[CompilerGenerated]
		[SetsRequiredMembers]
		protected ClearSquareRequest(ClearSquareRequest original)
		{
			Code = original.Code;
			Team = original.Team;
			Index = original.Index;
		}

		public ClearSquareRequest()
		{
		}
	}
	internal record CreateRoomRequest
	{
		[DataMember(Name = "game_type")]
		public int GameType => 18;

		[DataMember(Name = "lockout_mode")]
		private int LockoutMode
		{
			get
			{
				if (!IsLockout)
				{
					return 1;
				}
				return 2;
			}
		}

		[DataMember(Name = "is_spectator")]
		public bool IsSpectator => false;

		[DataMember(Name = "variant_type")]
		private int VariantType
		{
			get
			{
				if (!IsRandomized)
				{
					return 18;
				}
				return 172;
			}
		}

		[DataMember(Name = "hide_card")]
		public bool HideCard => false;

		private const int RANDOMIZED_VARIANT_TYPE = 172;

		private const int FIXED_BOARD_VARIANT_TYPE = 18;

		private const int LOCKOUT_MODE = 2;

		private const int NON_LOCKOUT_MODE = 1;

		[DataMember(Name = "room_name")]
		public required string RoomName;

		[DataMember(Name = "passphrase")]
		public required string Password;

		[DataMember(Name = "nickname")]
		public required string Nickname;

		public required bool IsLockout;

		[DataMember(Name = "seed")]
		public required string Seed;

		public required bool IsRandomized;

		[DataMember(Name = "custom_json")]
		public required string Board;

		[DataMember(Name = "csrfmiddlewaretoken")]
		public required string CreationToken;

		[CompilerGenerated]
		protected virtual bool PrintMembers(StringBuilder builder)
		{
			RuntimeHelpers.EnsureSufficientExecutionStack();
			builder.Append("RoomName = ");
			builder.Append((object?)RoomName);
			builder.Append(", Password = ");
			builder.Append((object?)Password);
			builder.Append(", Nickname = ");
			builder.Append((object?)Nickname);
			builder.Append(", GameType = ");
			builder.Append(GameType.ToString());
			builder.Append(", IsLockout = ");
			builder.Append(IsLockout.ToString());
			builder.Append(", Seed = ");
			builder.Append((object?)Seed);
			builder.Append(", IsSpectator = ");
			builder.Append(IsSpectator.ToString());
			builder.Append(", IsRandomized = ");
			builder.Append(IsRandomized.ToString());
			builder.Append(", Board = ");
			builder.Append((object?)Board);
			builder.Append(", HideCard = ");
			builder.Append(HideCard.ToString());
			builder.Append(", CreationToken = ");
			builder.Append((object?)CreationToken);
			return true;
		}

		[CompilerGenerated]
		[SetsRequiredMembers]
		protected CreateRoomRequest(CreateRoomRequest original)
		{
			RoomName = original.RoomName;
			Password = original.Password;
			Nickname = original.Nickname;
			IsLockout = original.IsLockout;
			Seed = original.Seed;
			IsRandomized = original.IsRandomized;
			Board = original.Board;
			CreationToken = original.CreationToken;
		}

		public CreateRoomRequest()
		{
		}
	}
	internal record GetSocketInformationResponse
	{
		[JsonProperty("room")]
		[JsonRequired]
		public required string Code { get; init; }

		[JsonProperty("player")]
		[JsonRequired]
		public required string PlayerUUID { get; init; }

		[CompilerGenerated]
		[SetsRequiredMembers]
		protected GetSocketInformationResponse(GetSocketInformationResponse original)
		{
			Code = original.Code;
			PlayerUUID = original.PlayerUUID;
		}

		public GetSocketInformationResponse()
		{
		}
	}
	internal record JoinRoomRequest
	{
		[JsonProperty("room")]
		public required string Code { get; init; }

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

		[JsonProperty("nickname")]
		public required string Username { get; init; }

		[JsonProperty("is_spectator")]
		public bool IsSpectator => false;

		[CompilerGenerated]
		[SetsRequiredMembers]
		protected JoinRoomRequest(JoinRoomRequest original)
		{
			Code = original.Code;
			Password = original.Password;
			Username = original.Username;
		}

		public JoinRoomRequest()
		{
		}
	}
	internal record JoinRoomResponse
	{
		[JsonProperty("socket_key")]
		[JsonRequired]
		public required string SocketKey { get; init; }

		[CompilerGenerated]
		[SetsRequiredMembers]
		protected JoinRoomResponse(JoinRoomResponse original)
		{
			SocketKey = original.SocketKey;
		}

		public JoinRoomResponse()
		{
		}
	}
	internal record MarkSquareRequest
	{
		[JsonProperty("room")]
		public required string Code { get; init; }

		[JsonProperty("color")]
		public required Team Team { get; init; }

		[JsonProperty("slot")]
		public required string Index { get; init; }

		[JsonProperty("remove_color")]
		public bool RemoveColor => false;

		[CompilerGenerated]
		[SetsRequiredMembers]
		protected MarkSquareRequest(MarkSquareRequest original)
		{
			Code = original.Code;
			Team = original.Team;
			Index = original.Index;
		}

		public MarkSquareRequest()
		{
		}
	}
	internal record RevealCardRequest
	{
		[JsonProperty("room")]
		public required string Code { get; init; }

		[CompilerGenerated]
		[SetsRequiredMembers]
		protected RevealCardRequest(RevealCardRequest original)
		{
			Code = original.Code;
		}

		public RevealCardRequest()
		{
		}
	}
	internal record SendMessageRequest
	{
		[JsonProperty("room")]
		public required string Code { get; init; }

		[JsonProperty("text")]
		public required string Message { get; init; }

		[CompilerGenerated]
		[SetsRequiredMembers]
		protected SendMessageRequest(SendMessageRequest original)
		{
			Code = original.Code;
			Message = original.Message;
		}

		public SendMessageRequest()
		{
		}
	}
	[JsonConverter(typeof(SlotIndexConverter))]
	internal record SlotIndex
	{
		public readonly int Index;

		internal SlotIndex(int index)
		{
			Index = index;
		}
	}
	internal record Tokens
	{
		public required string PublicToken { get; init; }

		public required string CreationToken { get; init; }

		[CompilerGenerated]
		[SetsRequiredMembers]
		protected Tokens(Tokens original)
		{
			PublicToken = original.PublicToken;
			CreationToken = original.CreationToken;
		}

		public Tokens()
		{
		}
	}
}
namespace BingoAPI.Networking.Converters
{
	internal class EventConverter : JsonConverter
	{
		public override bool CanWrite => false;

		public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
		{
			throw new InvalidOperationException();
		}

		public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer)
		{
			JObject val = JObject.Load(reader);
			string text = ((JToken)val).Value<string>((object)"type");
			return text switch
			{
				"chat" => ((JToken)val).ToObject<ChatEvent>(), 
				"goal" => ((JToken)val).ToObject<GoalEvent>(), 
				"color" => ((JToken)val).ToObject<ColorEvent>(), 
				"revealed" => ((JToken)val).ToObject<CardRevealedEvent>(), 
				"new-card" => ((JToken)val).ToObject<CardGeneratedEvent>(), 
				"connection" => ((JToken)val).ToObject<ConnectionEvent>(), 
				_ => throw new InvalidOperationException($"No event was found of type '{text}': {val}"), 
			};
		}

		public override bool CanConvert(Type objectType)
		{
			return objectType == typeof(IEvent);
		}
	}
	internal class SlotIndexConverter : JsonConverter<SlotIndex>
	{
		private const string PREFIX = "slot";

		public override void WriteJson(JsonWriter writer, SlotIndex? value, JsonSerializer serializer)
		{
			int num = 0;
			if (value != null)
			{
				num = value.Index + 1;
			}
			writer.WriteValue(string.Format("{0}{1}", "slot", num));
		}

		public override SlotIndex ReadJson(JsonReader reader, Type objectType, SlotIndex? existingValue, bool hasExistingValue, JsonSerializer serializer)
		{
			//IL_0024: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			if (!(reader.Value is string text))
			{
				throw new JsonException(string.Format("Expected a '{0}', but  got '{1}'.", "String", reader.ValueType));
			}
			if (!text.StartsWith("slot"))
			{
				throw new JsonException("Expected value starting with 'slot'.");
			}
			string text2 = text.Substring("slot".Length);
			if (!int.TryParse(text2, out var result))
			{
				throw new JsonException("Could not parse index from '" + text2 + "'.");
			}
			if (result <= 0)
			{
				throw new JsonException("Index must be greater than 0.");
			}
			return new SlotIndex(result - 1);
		}
	}
	internal class StringEqualConverter : JsonConverter<bool>
	{
		private readonly string _value;

		public override bool CanWrite => false;

		public StringEqualConverter(string value)
		{
			_value = value;
		}

		public override void WriteJson(JsonWriter writer, bool value, JsonSerializer serializer)
		{
			throw new InvalidOperationException(string.Format("Class '{0}' cannot write a '{1}' as '{2}'.", "StringEqualConverter", typeof(bool), typeof(string)));
		}

		public override bool ReadJson(JsonReader reader, Type objectType, bool existingValue, bool hasExistingValue, JsonSerializer serializer)
		{
			if (!(reader.Value is string a))
			{
				return false;
			}
			return string.Equals(a, _value);
		}
	}
	internal class TeamConverter : JsonConverter<Team>
	{
		private static readonly Lazy<Dictionary<string, Team>> TeamMappings = new Lazy<Dictionary<string, Team>>(delegate
		{
			Dictionary<string, Team> dictionary = new Dictionary<string, Team>();
			string[] names = Enum.GetNames(typeof(Team));
			string[] array = names;
			foreach (string text in array)
			{
				FieldInfo field = typeof(Team).GetField(text);
				Team value = (Team)field.GetValue(null);
				string text2 = (from EnumMemberAttribute a in field.GetCustomAttributes(typeof(EnumMemberAttribute), inherit: false)
					select a.Value).SingleOrDefault();
				dictionary.Add(text2 ?? text, value);
			}
			return dictionary;
		});

		public override void WriteJson(JsonWriter writer, Team value, JsonSerializer serializer)
		{
			List<string> list = new List<string>();
			foreach (KeyValuePair<string, Team> item in TeamMappings.Value)
			{
				if ((item.Value != Team.None || value == Team.None) && value.HasFlag(item.Value))
				{
					list.Add(item.Key);
				}
			}
			writer.WriteValue(string.Join(" ", list));
		}

		public override Team ReadJson(JsonReader reader, Type objectType, Team existingValue, bool hasExistingValue, JsonSerializer serializer)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			if (!(reader.Value is string text))
			{
				throw new JsonException($"Expected a '{typeof(string)}', but got '{reader.ValueType}'.");
			}
			Team team = Team.None;
			string[] array = text.Split(new char[1] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
			foreach (string text2 in array)
			{
				if (!TeamMappings.Value.TryGetValue(text2, out var value))
				{
					throw new InvalidOperationException("Unknown team '" + text2 + "'");
				}
				team |= value;
			}
			return team;
		}
	}
}
namespace BingoAPI.Networking.Clients
{
	internal sealed class BingoApiClient
	{
		public const Team DEFAULT_TEAM = Team.Red;

		private readonly HttpClient _client;

		public BingoApiClient(HttpClient client)
		{
			_client = client;
		}

		private Task<HttpResponseMessage> Send(HttpRequestMessage request, CancellationToken ct)
		{
			return _client.SendAsync(request, ct);
		}

		private async Task SendAsync(HttpRequestMessage request, CancellationToken ct)
		{
			using HttpResponseMessage httpResponseMessage = await Send(request, ct);
			httpResponseMessage.EnsureSuccessStatusCode();
		}

		private async Task<T> SendAndParse<T>(HttpRequestMessage request, CancellationToken ct)
		{
			using HttpResponseMessage response = await _client.SendAsync(request, ct);
			response.EnsureSuccessStatusCode();
			T val = JsonConvert.DeserializeObject<T>(await response.Content.ReadAsStringAsync());
			if (val == null)
			{
				throw new InvalidOperationException("Failed to deserialize response to " + typeof(T).Name);
			}
			return val;
		}

		private async Task<Tokens> GetTokens(CancellationToken ct)
		{
			using HttpRequestMessage request = new RequestBuilder().Get().ToEndpoint("").Build();
			using HttpResponseMessage response = await Send(request, ct);
			response.EnsureSuccessStatusCode();
			CookieContainer cookieContainer = new CookieContainer();
			IEnumerable<string> values = response.Headers.GetValues("Set-Cookie");
			foreach (string item in values)
			{
				cookieContainer.SetCookies(_client.BaseAddress, item);
			}
			CookieCollection cookies = cookieContainer.GetCookies(_client.BaseAddress);
			Cookie publicTokenCookie = cookies["csrftoken"];
			if (publicTokenCookie == null)
			{
				throw new KeyNotFoundException("No cookie was set for 'csrftoken'.");
			}
			Match match = Regex.Match(await response.Content.ReadAsStringAsync(), "<input[^>]*name=\"csrfmiddlewaretoken\"[^>]*value=\"(.*?)\"[^>]*>");
			if (!match.Success)
			{
				throw new KeyNotFoundException("Could not find any input with 'csrfmiddlewaretoken'.");
			}
			return new Tokens
			{
				PublicToken = publicTokenCookie.Value,
				CreationToken = match.Groups[1].Value
			};
		}

		public async Task<string> CreateRoom(CreateRoomSettings settings, CancellationToken ct)
		{
			throw new NotImplementedException();
		}

		public async Task<string> JoinRoom(JoinRoomSettings settings, CancellationToken ct)
		{
			JoinRoomRequest json = new JoinRoomRequest
			{
				Code = settings.Code,
				Password = settings.Password,
				Username = settings.Nickname
			};
			using HttpRequestMessage request = new RequestBuilder().Post().ToEndpoint("/api/join-room").WithJson(json)
				.Build();
			return (await SendAndParse<JoinRoomResponse>(request, ct)).SocketKey;
		}

		public async Task MarkSquare(string room, Team team, int index, CancellationToken ct)
		{
			MarkSquareRequest json = new MarkSquareRequest
			{
				Code = room,
				Team = team,
				Index = (index + 1).ToString()
			};
			using HttpRequestMessage request = new RequestBuilder().Put().ToEndpoint("/api/select").WithJson(json)
				.Build();
			await SendAsync(request, ct);
		}

		public async Task ClearSquare(string room, Team team, int index, CancellationToken ct)
		{
			ClearSquareRequest json = new ClearSquareRequest
			{
				Code = room,
				Team = team,
				Index = (index + 1).ToString()
			};
			using HttpRequestMessage request = new RequestBuilder().Put().ToEndpoint("/api/select").WithJson(json)
				.Build();
			await SendAsync(request, ct);
		}

		public async Task SendMessage(string room, string message, CancellationToken ct)
		{
			SendMessageRequest json = new SendMessageRequest
			{
				Code = room,
				Message = message
			};
			using HttpRequestMessage request = new RequestBuilder().Put().ToEndpoint("/api/chat").WithJson(json)
				.Build();
			await SendAsync(request, ct);
		}

		public async Task ChangeTeam(string room, Team team, CancellationToken ct)
		{
			ChangeTeamRequest json = new ChangeTeamRequest
			{
				Code = room,
				Team = team
			};
			using HttpRequestMessage request = new RequestBuilder().Put().ToEndpoint("/api/color").WithJson(json)
				.Build();
			await SendAsync(request, ct);
		}

		public async Task<ICollection<Square>> GetSquares(string room, CancellationToken ct)
		{
			using HttpRequestMessage request = new RequestBuilder().Get().ToEndpoint("/room/" + room + "/board").Build();
			return await SendAndParse<Square[]>(request, ct);
		}

		public async Task RevealCard(string room, CancellationToken ct)
		{
			RevealCardRequest json = new RevealCardRequest
			{
				Code = room
			};
			using HttpRequestMessage request = new RequestBuilder().Put().ToEndpoint("/api/revealed").WithJson(json)
				.Build();
			await SendAsync(request, ct);
		}

		public async Task<GetSocketInformationResponse> GetSocketInformation(string socketKey, CancellationToken ct)
		{
			using HttpRequestMessage request = new RequestBuilder().Get().ToEndpoint("/api/socket/" + socketKey).Build();
			return await SendAndParse<GetSocketInformationResponse>(request, ct);
		}
	}
	internal sealed class BingoSocketClient : IDisposable
	{
		private WebSocket? _socket;

		private CancellationTokenSource? _cts;

		private Task? _socketReceiveTask;

		private readonly Uri _broadcastUri;

		public BingoSocketClient(Uri socketAddress)
		{
			UriBuilder uriBuilder = new UriBuilder(socketAddress)
			{
				Path = "broadcast"
			};
			_broadcastUri = uriBuilder.Uri;
		}

		public async Task Connect(string socketKey, Action<string> onMessageReceived, CancellationToken ct)
		{
			if (_socket != null)
			{
				throw new InvalidOperationException("Socket is already connected.");
			}
			ClientWebSocket socket = new ClientWebSocket();
			try
			{
				await socket.ConnectAsync(_broadcastUri, ct);
				string s = JsonConvert.SerializeObject((object)new
				{
					socket_key = socketKey
				});
				await socket.SendAsync(new ArraySegment<byte>(Encoding.UTF8.GetBytes(s)), WebSocketMessageType.Text, endOfMessage: true, ct);
				_socket = socket;
				_cts = new CancellationTokenSource();
				_socketReceiveTask = ReceiveLoop(_socket, onMessageReceived, _cts.Token);
			}
			catch
			{
				socket.Dispose();
				throw;
			}
		}

		public async Task Disconnect(CancellationToken ct)
		{
			if (_socket == null)
			{
				return;
			}
			_cts?.Cancel();
			if (_socket.State == WebSocketState.Open)
			{
				try
				{
					await _socket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Client disconnecting", ct);
				}
				catch (Exception ex)
				{
					Log.Error("Error closing WebSocket: " + ex.Message);
				}
			}
			if (_socketReceiveTask != null)
			{
				try
				{
					await _socketReceiveTask;
				}
				catch (OperationCanceledException)
				{
				}
				catch (Exception ex3)
				{
					Log.Error("Receive loop failed during disconnect: " + ex3.Message);
				}
			}
			CleanUp();
		}

		private static async Task ReceiveLoop(WebSocket socket, Action<string> onReceive, CancellationToken ct)
		{
			byte[] buffer = new byte[1024];
			using MemoryStream ms = new MemoryStream();
			while (!ct.IsCancellationRequested && socket.State == WebSocketState.Open)
			{
				WebSocketReceiveResult webSocketReceiveResult;
				do
				{
					webSocketReceiveResult = await socket.ReceiveAsync(new ArraySegment<byte>(buffer), ct);
					ms.Write(buffer, 0, webSocketReceiveResult.Count);
				}
				while (!webSocketReceiveResult.EndOfMessage);
				if (webSocketReceiveResult.MessageType == WebSocketMessageType.Close)
				{
					Log.Debug("Close message was received.");
					break;
				}
				if (webSocketReceiveResult.MessageType == WebSocketMessageType.Text)
				{
					string text = Encoding.UTF8.GetString(ms.ToArray());
					Log.Debug("Message received:\n" + text);
					try
					{
						onReceive(text);
					}
					catch (Exception arg)
					{
						Log.Error($"Error handling socket message: {arg}");
					}
				}
				ms.Seek(0L, SeekOrigin.Begin);
				ms.SetLength(0L);
			}
		}

		private void CleanUp()
		{
			_socket?.Dispose();
			_cts?.Dispose();
			_socket = null;
			_cts = null;
			_socketReceiveTask = null;
		}

		public void Dispose()
		{
			CleanUp();
		}
	}
}
namespace BingoAPI.Models
{
	public sealed class Card
	{
		private struct CardSquare
		{
			public readonly Goal Goal;

			public Team Teams { get; set; }

			public CardSquare(Square square, Goal goal)
			{
				Goal = goal;
				Teams = square.Teams;
			}
		}

		private readonly CardSquare[] _squares;

		public int Size { get; init; }

		internal Card(ICollection<Square> squares, GoalPool pool)
		{
			if (squares.Count == 0)
			{
				throw new ArgumentException("Tried to create a card without providing any square.");
			}
			int num = (int)Math.Sqrt(squares.Count);
			if (num * num != squares.Count)
			{
				throw new ArgumentException($"Card must be a perfect square, but received '{num}'.");
			}
			Size = num;
			_squares = new CardSquare[squares.Count];
			foreach (Square square in squares)
			{
				int index = square.Index;
				if (index < 0 || index >= _squares.Length)
				{
					throw new ArgumentOutOfRangeException("square");
				}
				if (!pool.TryGet(square, out Goal goal))
				{
					throw new KeyNotFoundException("Failed to find a goal under the name '" + square.Text + "'.");
				}
				_squares[index] = new CardSquare(square, goal);
			}
		}

		public Goal GetGoalAt(int index)
		{
			return _squares[index].Goal;
		}

		public Goal[] GetAllGoals()
		{
			HashSet<Goal> hashSet = new HashSet<Goal>();
			CardSquare[] squares = _squares;
			for (int i = 0; i < squares.Length; i++)
			{
				CardSquare cardSquare = squares[i];
				hashSet.Add(cardSquare.Goal);
			}
			return hashSet.ToArray();
		}

		public int[] FindByGoal(Goal goal)
		{
			List<int> list = new List<int>();
			for (int i = 0; i < _squares.Length; i++)
			{
				if (!(GetGoalAt(i) != goal))
				{
					list.Add(i);
				}
			}
			return list.ToArray();
		}

		public Team GetTeamsAt(int index)
		{
			return _squares[index].Teams;
		}

		public bool IsMarkedBy(int index, Team team)
		{
			return GetTeamsAt(index).HasFlag(team);
		}

		public void Mark(int index, Team team)
		{
			_squares[index].Teams |= team;
		}

		public void Unmark(int index, Team team)
		{
			_squares[index].Teams &= (Team)(ushort)(~(int)team);
		}
	}
	public record Player
	{
		[JsonProperty("uuid")]
		[JsonRequired]
		public required string UUID { get; init; }

		[JsonProperty("name")]
		[JsonRequired]
		public required string Name { get; init; }

		[JsonProperty("color")]
		[JsonRequired]
		public required Team Team { get; init; }

		[CompilerGenerated]
		[SetsRequiredMembers]
		protected Player(Player original)
		{
			UUID = original.UUID;
			Name = original.Name;
			Team = original.Team;
		}

		public Player()
		{
		}
	}
	public record Square
	{
		[JsonProperty("name")]
		[JsonRequired]
		public required string Text { get; init; }

		public int Index => _slot?.Index ?? 0;

		[JsonProperty("colors")]
		[JsonRequired]
		public required Team Teams { get; init; }

		[JsonProperty("slot")]
		[JsonRequired]
		private SlotIndex? _slot;

		[CompilerGenerated]
		protected virtual bool PrintMembers(StringBuilder builder)
		{
			RuntimeHelpers.EnsureSufficientExecutionStack();
			builder.Append("Text = ");
			builder.Append((object?)Text);
			builder.Append(", Index = ");
			builder.Append(Index.ToString());
			builder.Append(", Teams = ");
			builder.Append(Teams.ToString());
			return true;
		}

		[CompilerGenerated]
		public override int GetHashCode()
		{
			return ((EqualityComparer<Type>.Default.GetHashCode(EqualityContract) * -1521134295 + EqualityComparer<string>.Default.GetHashCode(Text)) * -1521134295 + EqualityComparer<SlotIndex>.Default.GetHashCode(_slot)) * -1521134295 + EqualityComparer<Team>.Default.GetHashCode(Teams);
		}

		[CompilerGenerated]
		public virtual bool Equals(Square? other)
		{
			if ((object)this != other)
			{
				if ((object)other != null && EqualityContract == other.EqualityContract && EqualityComparer<string>.Default.Equals(Text, other.Text) && EqualityComparer<SlotIndex>.Default.Equals(_slot, other._slot))
				{
					return EqualityComparer<Team>.Default.Equals(Teams, other.Teams);
				}
				return false;
			}
			return true;
		}

		[CompilerGenerated]
		[SetsRequiredMembers]
		protected Square(Square original)
		{
			Text = original.Text;
			_slot = original._slot;
			Teams = original.Teams;
		}

		public Square()
		{
		}
	}
	[Flags]
	[JsonConverter(typeof(TeamConverter))]
	public enum Team : ushort
	{
		[EnumMember(Value = "blank")]
		None = 0,
		[EnumMember(Value = "pink")]
		Pink = 1,
		[EnumMember(Value = "red")]
		Red = 2,
		[EnumMember(Value = "orange")]
		Orange = 4,
		[EnumMember(Value = "brown")]
		Brown = 8,
		[EnumMember(Value = "yellow")]
		Yellow = 0x10,
		[EnumMember(Value = "green")]
		Green = 0x20,
		[EnumMember(Value = "teal")]
		Teal = 0x40,
		[EnumMember(Value = "blue")]
		Blue = 0x80,
		[EnumMember(Value = "navy")]
		Navy = 0x100,
		[EnumMember(Value = "purple")]
		Purple = 0x200
	}
}
namespace BingoAPI.Models.Settings
{
	public record CreateRoomSettings
	{
		public string Name { get; set; } = string.Empty;

		public string Password { get; set; } = string.Empty;

		public string Nickname { get; set; } = string.Empty;

		public bool IsRandomized { get; set; }

		public bool IsLockout { get; set; }

		public string Seed { get; set; } = string.Empty;
	}
	public record JoinRoomSettings
	{
		public string Code { get; set; } = string.Empty;

		public string Password { get; set; } = string.Empty;

		public string Nickname { get; set; } = string.Empty;
	}
}
namespace BingoAPI.Helpers
{
	public static class Log
	{
		public enum LogLevel
		{
			Debug,
			Info,
			Warning,
			Error
		}

		public static Action<LogLevel, string>? Logger { private get; set; }

		private static void LogMessage(LogLevel level, string? message)
		{
			Logger?.Invoke(level, message ?? string.Empty);
		}

		internal static void Debug(string? message)
		{
			LogMessage(LogLevel.Debug, message);
		}

		internal static void Info(string? message)
		{
			LogMessage(LogLevel.Info, message);
		}

		internal static void Warning(string? message)
		{
			LogMessage(LogLevel.Warning, message);
		}

		internal static void Error(string? message)
		{
			LogMessage(LogLevel.Error, message);
		}
	}
	public static class Network
	{
		public static bool TryGetRoomCode(string url, [NotNullWhen(true)] out string? code)
		{
			Match match = Regex.Match(url, "(?<=/room/)[a-zA-Z\\d-_]+");
			if (!match.Success)
			{
				code = null;
				return false;
			}
			code = match.Value;
			return true;
		}
	}
}
namespace BingoAPI.Goals
{
	public sealed record Goal
	{
		[JsonProperty("name")]
		[JsonRequired]
		public required string Name { get; init; }

		[JsonProperty("condition")]
		[JsonRequired]
		public required ICondition Condition { get; init; }

		[CompilerGenerated]
		[SetsRequiredMembers]
		private Goal(Goal original)
		{
			Name = original.Name;
			Condition = original.Condition;
		}

		public Goal()
		{
		}
	}
	public sealed class GoalPool : IEnumerable<Goal>, IEnumerable
	{
		private readonly Dictionary<string, Goal> _goals = new Dictionary<string, Goal>(StringComparer.OrdinalIgnoreCase);

		public int Count => _goals.Count;

		public void Add(Goal goal)
		{
			if (!TryAdd(goal))
			{
				throw new ArgumentException("The goal has already been added.", "goal");
			}
		}

		public bool TryAdd(Goal goal)
		{
			if (_goals.ContainsKey(goal.Name))
			{
				return false;
			}
			_goals.Add(goal.Name, goal);
			return true;
		}

		public bool TryGet(Square square, [NotNullWhen(true)] out Goal? goal)
		{
			return _goals.TryGetValue(square.Text, out goal);
		}

		public IEnumerator<Goal> GetEnumerator()
		{
			return _goals.Values.GetEnumerator();
		}

		IEnumerator IEnumerable.GetEnumerator()
		{
			return GetEnumerator();
		}
	}
	public sealed record GoalSet
	{
		[JsonProperty("name")]
		public string Name { get; init; } = string.Empty;

		[JsonProperty("description")]
		public string Description { get; init; } = string.Empty;

		[JsonProperty("goals")]
		[JsonRequired]
		public required Goal[] Goals { get; init; }

		[CompilerGenerated]
		[SetsRequiredMembers]
		private GoalSet(GoalSet original)
		{
			Name = original.Name;
			Description = original.Description;
			Goals = original.Goals;
		}

		public GoalSet()
		{
		}
	}
	public sealed class GoalTracker
	{
		public delegate void GoalChangedCallback(Goal goal);

		private readonly HashSet<Goal> _trackedGoals = new HashSet<Goal>();

		private readonly HashSet<Goal> _metGoals = new HashSet<Goal>();

		public event GoalChangedCallback? OnGoalMarked;

		public event GoalChangedCallback? OnGoalCleared;

		public bool TryAdd(Goal goal)
		{
			return _trackedGoals.Add(goal);
		}

		public void Clear()
		{
			_trackedGoals.Clear();
			_metGoals.Clear();
		}

		public void Evaluate()
		{
			foreach (Goal trackedGoal in _trackedGoals)
			{
				bool wasInitiallyMet = _metGoals.Contains(trackedGoal);
				bool isCurrentlyMet;
				try
				{
					isCurrentlyMet = trackedGoal.Condition.IsMet();
				}
				catch (Exception arg)
				{
					Log.Error($"Error while evaluating '{trackedGoal.Name}': {arg}");
					isCurrentlyMet = false;
				}
				DispatchChange(wasInitiallyMet, isCurrentlyMet, trackedGoal);
			}
		}

		private void DispatchChange(bool wasInitiallyMet, bool isCurrentlyMet, Goal goal)
		{
			if (wasInitiallyMet != isCurrentlyMet)
			{
				if (isCurrentlyMet)
				{
					_metGoals.Add(goal);
					this.OnGoalMarked?.Invoke(goal);
				}
				else
				{
					_metGoals.Remove(goal);
					this.OnGoalCleared?.Invoke(goal);
				}
			}
		}
	}
}
namespace BingoAPI.Events
{
	public sealed class EventDispatcher
	{
		public delegate void ConnectionCallback(Player player);

		public delegate void DisconnectionCallback(Player player);

		public delegate void MarkCallback(Player player, Square square, Team team);

		public delegate void ClearCallback(Player player, Square square, Team team);

		public delegate void ChatCallback(Player player, string message, ulong timestamp);

		public delegate void TeamCallback(Player player, Team newTeam);

		public delegate void RevealCallback(Player player);

		public delegate void GenerateCallback(Player player, bool isHidden);

		private Player? _localPlayer;

		public event ConnectionCallback? OnSelfConnected;

		public event DisconnectionCallback? OnSelfDisconnected;

		public event MarkCallback? OnSelfSquareMarked;

		public event ClearCallback? OnSelfSquareCleared;

		public event ChatCallback? OnSelfMessageSent;

		public event TeamCallback? OnSelfTeamChanged;

		public event RevealCallback? OnSelfCardRevealed;

		public event GenerateCallback? OnSelfCardGenerated;

		public event ConnectionCallback? OnOtherConnected;

		public event DisconnectionCallback? OnOtherDisconnected;

		public event MarkCallback? OnOtherSquareMarked;

		public event ClearCallback? OnOtherSquareCleared;

		public event ChatCallback? OnOtherMessageSent;

		public event TeamCallback? OnOtherTeamChanged;

		public event RevealCallback? OnOtherCardRevealed;

		public event GenerateCallback? OnOtherCardGenerated;

		private bool IsLocal(Player player)
		{
			return player.UUID == _localPlayer?.UUID;
		}

		internal void DispatchConnect(Player player)
		{
			_localPlayer = player;
			this.OnSelfConnected?.Invoke(player);
		}

		internal void DispatchDisconnect()
		{
			if (!(_localPlayer == null))
			{
				this.OnSelfDisconnected?.Invoke(_localPlayer);
				_localPlayer = null;
			}
		}

		internal void Dispatch(IEvent evt)
		{
			if (!(evt is ConnectionEvent connectionEvent))
			{
				if (!(evt is ChatEvent evt2))
				{
					if (!(evt is ColorEvent evt3))
					{
						if (!(evt is GoalEvent goalEvent))
						{
							if (!(evt is CardRevealedEvent evt4))
							{
								if (evt is CardGeneratedEvent evt5)
								{
									DispatchCardGenerated(evt5);
								}
							}
							else
							{
								DispatchCardRevealed(evt4);
							}
						}
						else if (goalEvent.HasBeenCleared)
						{
							DispatchGoalCleared(goalEvent);
						}
						else
						{
							DispatchGoalMarked(goalEvent);
						}
					}
					else
					{
						DispatchColorEvent(evt3);
					}
				}
				else
				{
					DispatchChatEvent(evt2);
				}
			}
			else if (connectionEvent.IsConnected)
			{
				DispatchConnectedEvent(connectionEvent);
			}
			else
			{
				DispatchDisconnectedEvent(connectionEvent);
			}
		}

		private void DispatchConnectedEvent(ConnectionEvent evt)
		{
			if (!IsLocal(evt.Player))
			{
				this.OnOtherConnected?.Invoke(evt.Player);
			}
		}

		private void DispatchDisconnectedEvent(ConnectionEvent evt)
		{
			if (!IsLocal(evt.Player))
			{
				this.OnOtherDisconnected?.Invoke(evt.Player);
			}
		}

		private void DispatchChatEvent(ChatEvent evt)
		{
			if (IsLocal(evt.Player))
			{
				this.OnSelfMessageSent?.Invoke(evt.Player, evt.Text, evt.Timestamp);
			}
			else
			{
				this.OnOtherMessageSent?.Invoke(evt.Player, evt.Text, evt.Timestamp);
			}
		}

		private void DispatchColorEvent(ColorEvent evt)
		{
			if (IsLocal(evt.Player))
			{
				this.OnSelfTeamChanged?.Invoke(evt.Player, evt.NewColor);
			}
			else
			{
				this.OnOtherTeamChanged?.Invoke(evt.Player, evt.NewColor);
			}
		}

		private void DispatchGoalMarked(GoalEvent evt)
		{
			if (IsLocal(evt.Player))
			{
				this.OnSelfSquareMarked?.Invoke(evt.Player, evt.Square, evt.Team);
			}
			else
			{
				this.OnOtherSquareMarked?.Invoke(evt.Player, evt.Square, evt.Team);
			}
		}

		private void DispatchGoalCleared(GoalEvent evt)
		{
			if (IsLocal(evt.Player))
			{
				this.OnSelfSquareCleared?.Invoke(evt.Player, evt.Square, evt.Team);
			}
			else
			{
				this.OnOtherSquareCleared?.Invoke(evt.Player, evt.Square, evt.Team);
			}
		}

		private void DispatchCardRevealed(CardRevealedEvent evt)
		{
			if (IsLocal(evt.Player))
			{
				this.OnSelfCardRevealed?.Invoke(evt.Player);
			}
			else
			{
				this.OnOtherCardRevealed?.Invoke(evt.Player);
			}
		}

		private void DispatchCardGenerated(CardGeneratedEvent evt)
		{
			if (IsLocal(evt.Player))
			{
				this.OnSelfCardGenerated?.Invoke(evt.Player, evt.IsCardHidden);
			}
			else
			{
				this.OnOtherCardGenerated?.Invoke(evt.Player, evt.IsCardHidden);
			}
		}
	}
	internal interface IEvent
	{
	}
}
namespace BingoAPI.Events.BuiltIn
{
	internal record CardGeneratedEvent : IEvent
	{
		[JsonProperty("player")]
		[JsonRequired]
		public required Player Player { get; init; }

		[JsonProperty("hide_card")]
		[JsonRequired]
		public required bool IsCardHidden { get; init; }

		[JsonProperty("timestamp")]
		[JsonRequired]
		public required ulong Timestamp { get; init; }

		[CompilerGenerated]
		[SetsRequiredMembers]
		protected CardGeneratedEvent(CardGeneratedEvent original)
		{
			Player = original.Player;
			IsCardHidden = original.IsCardHidden;
			Timestamp = original.Timestamp;
		}

		public CardGeneratedEvent()
		{
		}
	}
	internal record CardRevealedEvent : IEvent
	{
		[JsonProperty("player")]
		[JsonRequired]
		public required Player Player { get; init; }

		[JsonProperty("timestamp")]
		[JsonRequired]
		public required ulong Timestamp { get; init; }

		[CompilerGenerated]
		[SetsRequiredMembers]
		protected CardRevealedEvent(CardRevealedEvent original)
		{
			Player = original.Player;
			Timestamp = original.Timestamp;
		}

		public CardRevealedEvent()
		{
		}
	}
	internal record ChatEvent : IEvent
	{
		[JsonProperty("player")]
		[JsonRequired]
		public required Player Player { get; init; }

		[JsonProperty("timestamp")]
		[JsonRequired]
		public required ulong Timestamp { get; init; }

		[JsonProperty("text")]
		[JsonRequired]
		public required string Text { get; init; }

		[CompilerGenerated]
		[SetsRequiredMembers]
		protected ChatEvent(ChatEvent original)
		{
			Player = original.Player;
			Timestamp = original.Timestamp;
			Text = original.Text;
		}

		public ChatEvent()
		{
		}
	}
	internal record ColorEvent : IEvent
	{
		[JsonProperty("player")]
		[JsonRequired]
		public required Player Player { get; init; }

		[JsonProperty("player_color")]
		[JsonRequired]
		public required Team PreviousColor { get; init; }

		[JsonProperty("color")]
		[JsonRequired]
		public required Team NewColor { get; init; }

		[JsonProperty("timestamp")]
		[JsonRequired]
		public required ulong Timestamp { get; init; }

		[CompilerGenerated]
		[SetsRequiredMembers]
		protected ColorEvent(ColorEvent original)
		{
			Player = original.Player;
			PreviousColor = original.PreviousColor;
			NewColor = original.NewColor;
			Timestamp = original.Timestamp;
		}

		public ColorEvent()
		{
		}
	}
	internal record ConnectionEvent : IEvent
	{
		[JsonProperty("player")]
		[JsonRequired]
		public required Player Player { get; init; }

		[JsonProperty("room")]
		[JsonRequired]
		public required string RoomId { get; init; }

		[JsonProperty("timestamp")]
		[JsonRequired]
		public required ulong Timestamp { get; init; }

		[JsonProperty("event_type")]
		[JsonConverter(typeof(StringEqualConverter), new object[] { "connected" })]
		public required bool IsConnected { get; init; }

		[CompilerGenerated]
		[SetsRequiredMembers]
		protected ConnectionEvent(ConnectionEvent original)
		{
			Player = original.Player;
			RoomId = original.RoomId;
			Timestamp = original.Timestamp;
			IsConnected = original.IsConnected;
		}

		public ConnectionEvent()
		{
		}
	}
	internal record GoalEvent : IEvent
	{
		[JsonProperty("player")]
		[JsonRequired]
		public required Player Player { get; init; }

		[JsonProperty("timestamp")]
		[JsonRequired]
		public required ulong Timestamp { get; init; }

		[JsonProperty("square")]
		[JsonRequired]
		public required Square Square { get; init; }

		[JsonProperty("color")]
		[JsonRequired]
		public required Team Team { get; init; }

		[JsonProperty("remove")]
		[JsonRequired]
		public required bool HasBeenCleared { get; init; }

		[CompilerGenerated]
		[SetsRequiredMembers]
		protected GoalEvent(GoalEvent original)
		{
			Player = original.Player;
			Timestamp = original.Timestamp;
			Square = original.Square;
			Team = original.Team;
			HasBeenCleared = original.HasBeenCleared;
		}

		public GoalEvent()
		{
		}
	}
}
namespace BingoAPI.Conditions
{
	internal class ConditionConverter : JsonConverter
	{
		private const string ACTION_KEY = "action";

		private const string PARAMS_KEY = "params";

		public override bool CanWrite => false;

		public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
		{
			throw new InvalidOperationException();
		}

		public override object ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer)
		{
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			JObject val = JObject.Load(reader);
			string text = ((JToken)val).Value<string>((object)"action");
			if (text == null)
			{
				throw new JsonException(string.Format("Expected '{0}' property: {1}", "action", val));
			}
			JToken val2 = default(JToken);
			if (!val.TryGetValue("params", ref val2))
			{
				throw new JsonException(string.Format("Expected '{0}' property: {1}", "params", val));
			}
			if (!ConditionRegistry.TryGetFactory(text, out IConditionFactory factory))
			{
				throw new ArgumentException("No factory has been registered under '" + text + "'.");
			}
			try
			{
				return factory.Generate(val2.CreateReader(), serializer);
			}
			catch (Exception ex)
			{
				throw new JsonException("Error while parsing the condition.", ex);
			}
		}

		public override bool CanConvert(Type objectType)
		{
			return objectType == typeof(ICondition);
		}
	}
	public static class ConditionRegistry
	{
		private static readonly Dictionary<string, IConditionFactory> FactoryPerAction = new Dictionary<string, IConditionFactory>();

		internal static bool TryGetFactory(string action, [NotNullWhen(true)] out IConditionFactory? factory)
		{
			return FactoryPerAction.TryGetValue(action, out factory);
		}

		public static void RegisterFactory(string action, IConditionFactory factory)
		{
			if (FactoryPerAction.TryGetValue(action, out IConditionFactory value))
			{
				Log.Debug($"Overriding the factory for '{action}' from '{value.GetType()}' to '{factory.GetType()}'.");
			}
			FactoryPerAction[action] = factory;
		}

		public static void RegisterFactory<T>(string action) where T : IConditionFactory, new()
		{
			RegisterFactory(action, new T());
		}

		public static bool TryRegisterFactory(Type type)
		{
			if (type.IsAbstract || type.IsInterface)
			{
				return false;
			}
			ConditionFactoryAttribute customAttribute = type.GetCustomAttribute<ConditionFactoryAttribute>();
			if (customAttribute == null)
			{
				return false;
			}
			if (!typeof(IConditionFactory).IsAssignableFrom(type))
			{
				return false;
			}
			if (!(Activator.CreateInstance(type) is IConditionFactory factory))
			{
				throw new InvalidOperationException($"Could not create factory '{type}'.");
			}
			try
			{
				Log.Debug($"Registering the factory '{type}' under '{customAttribute.Action}'.");
				RegisterFactory(customAttribute.Action, factory);
			}
			catch (Exception arg)
			{
				Log.Error($"Error while registering '{type}' under '{customAttribute.Action}': {arg}");
				return false;
			}
			return true;
		}

		internal static void RegisterCondition(string action, Type type)
		{
			ConditionJsonFactory factory = new ConditionJsonFactory(type);
			RegisterFactory(action, factory);
		}

		public static void RegisterCondition<T>(string action) where T : ICondition
		{
			RegisterCondition(action, typeof(T));
		}

		public static bool TryRegisterCondition(Type type)
		{
			if (type.IsAbstract || type.IsInterface)
			{
				return false;
			}
			ConditionAttribute customAttribute = type.GetCustomAttribute<ConditionAttribute>();
			if (customAttribute == null)
			{
				return false;
			}
			if (!typeof(ICondition).IsAssignableFrom(type))
			{
				return false;
			}
			try
			{
				Log.Debug($"Registering the condition '{type}' under '{customAttribute.Action}'.");
				RegisterCondition(customAttribute.Action, type);
			}
			catch (Exception arg)
			{
				Log.Error($"Error while registering '{type}' under '{customAttribute.Action}': {arg}");
				return false;
			}
			return true;
		}

		public static bool TryRegisterCondition<T>() where T : ICondition
		{
			return TryRegisterCondition(typeof(T));
		}

		public static void RegisterAllFromType(Type type)
		{
			TryRegisterCondition(type);
			TryRegisterFactory(type);
		}

		public static void RegisterAllFromAssembly(Assembly assembly)
		{
			IEnumerable<Type> types;
			try
			{
				types = assembly.GetTypes();
			}
			catch (ReflectionTypeLoadException ex)
			{
				types = ex.Types;
			}
			foreach (Type item in types)
			{
				if (!(item == null))
				{
					RegisterAllFromType(item);
				}
			}
		}

		public static void RegisterAll()
		{
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			foreach (Assembly assembly in assemblies)
			{
				RegisterAllFromAssembly(assembly);
			}
		}
	}
}
namespace BingoAPI.Conditions.Interfaces
{
	[JsonConverter(typeof(ConditionConverter))]
	public interface ICondition
	{
		bool IsMet();
	}
	public interface IConditionFactory
	{
		ICondition Generate(JsonReader reader, JsonSerializer serializer);
	}
}
namespace BingoAPI.Conditions.Factories
{
	internal sealed class ConditionJsonFactory : IConditionFactory
	{
		private readonly Type _type;

		public ConditionJsonFactory(Type type)
		{
			_type = type;
		}

		public ICondition Generate(JsonReader reader, JsonSerializer serializer)
		{
			object obj = Activator.CreateInstance(_type);
			if (!(obj is ICondition condition))
			{
				throw new ArgumentException(string.Format("Type '{0}' cannot be used inside '{1}'.", _type, "ConditionJsonFactory"));
			}
			serializer.Populate(reader, (object)condition);
			return condition;
		}
	}
	public abstract class ParameterizedConditionFactory<TParams> : IConditionFactory
	{
		public ICondition Generate(JsonReader reader, JsonSerializer serializer)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			TParams val = serializer.Deserialize<TParams>(reader);
			if (val == null)
			{
				throw new JsonException($"Failed to deserialize the parameters as '{typeof(TParams)}'.");
			}
			return Generate(val);
		}

		protected abstract ICondition Generate(TParams parameters);
	}
}
namespace BingoAPI.Conditions.BuiltIn
{
	[Condition("AND")]
	public sealed class AndCondition : ICondition
	{
		[JsonProperty("conditions")]
		[JsonRequired]
		[Description("Conditions that must all be met")]
		public required IReadOnlyCollection<ICondition> Conditions { get; init; }

		public bool IsMet()
		{
			return Conditions.All((ICondition condition) => condition.IsMet());
		}
	}
	[Condition("NOT")]
	public sealed class NotCondition : ICondition
	{
		[JsonProperty("condition")]
		[JsonRequired]
		[Description("Condition to negate")]
		public required ICondition Condition { get; init; }

		public bool IsMet()
		{
			return !Condition.IsMet();
		}
	}
	[Condition("OR")]
	public sealed class OrCondition : ICondition
	{
		[JsonProperty("conditions")]
		[JsonRequired]
		[Description("Conditions where at least one must be met")]
		public required IReadOnlyCollection<ICondition> Conditions { get; init; }

		public bool IsMet()
		{
			return Conditions.Any((ICondition condition) => condition.IsMet());
		}
	}
	[Condition("SOME")]
	public sealed class SomeCondition : ICondition
	{
		[JsonProperty("conditions")]
		[JsonRequired]
		[Description("Conditions that could be met")]
		public required IReadOnlyCollection<ICondition> Conditions { get; init; }

		[JsonProperty("amount")]
		[DefaultValue(1)]
		[Description("Minimum number of conditions that must be met")]
		public uint Amount { get; init; }

		public bool IsMet()
		{
			if (Conditions.Count < Amount)
			{
				return false;
			}
			int num = 0;
			foreach (ICondition condition in Conditions)
			{
				if (condition.IsMet())
				{
					num++;
					if (num >= Amount)
					{
						return true;
					}
				}
			}
			return false;
		}
	}
}
namespace BingoAPI.Conditions.Attributes
{
	[AttributeUsage(AttributeTargets.Class)]
	public class ConditionAttribute : Attribute
	{
		public readonly string Action;

		public ConditionAttribute(string action)
		{
			Action = action;
		}
	}
	[AttributeUsage(AttributeTargets.Class)]
	public class ConditionFactoryAttribute : Attribute
	{
		public readonly string Action;

		public ConditionFactoryAttribute(string action)
		{
			Action = action;
		}
	}
}

plugins/Silksong.BingoSync.dll

Decompiled a month ago
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Threading;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using BingoAPI.Conditions;
using BingoAPI.Conditions.Attributes;
using BingoAPI.Conditions.BuiltIn;
using BingoAPI.Conditions.Factories;
using BingoAPI.Conditions.Interfaces;
using BingoAPI.Events;
using BingoAPI.Goals;
using BingoAPI.Helpers;
using BingoAPI.Models;
using BingoAPI.Models.Settings;
using BingoAPI.Networking;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Silksong.BingoSync.Conditions;
using Silksong.BingoSync.Configurations;
using Silksong.BingoSync.Data;
using Silksong.BingoSync.Exceptions;
using Silksong.BingoSync.Extensions;
using Silksong.BingoSync.Helpers;
using Silksong.BingoSync.Networking;
using Silksong.BingoSync.Patches;
using Silksong.BingoSync.UI.Abstract;
using Silksong.BingoSync.UI.Components;
using Silksong.BingoSync.UI.Constants;
using Silksong.BingoSync.UI.Containers;
using Silksong.BingoSync.UI.Items;
using Silksong.BingoSync.UI.Menus;
using Silksong.ModMenu.Elements;
using Silksong.ModMenu.Plugin;
using Silksong.ModMenu.Screens;
using UnityEngine;
using UnityEngine.Events;
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("WarperSan")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Connects Silksong to BingoSync, letting you play bingo directly in-game")]
[assembly: AssemblyFileVersion("1.2.2.0")]
[assembly: AssemblyInformationalVersion("1.2.2+7a8cc8dd5a9fba0ece2a5b6d060ccb2c843417d9")]
[assembly: AssemblyProduct("Silksong.BingoSync")]
[assembly: AssemblyTitle("Silksong.BingoSync")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/WarperSan/Silksong.BingoSync")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace System.Runtime.Versioning
{
	[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false)]
	[ExcludeFromCodeCoverage]
	[Embedded]
	internal sealed class RequiresPreviewFeaturesAttribute : Attribute
	{
		public string? Message { get; }

		public string? Url { get; set; }

		public RequiresPreviewFeaturesAttribute()
		{
		}

		public RequiresPreviewFeaturesAttribute(string? message)
		{
			Message = message;
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.All, AllowMultiple = true, Inherited = false)]
	[ExcludeFromCodeCoverage]
	[Embedded]
	internal sealed class CompilerFeatureRequiredAttribute : Attribute
	{
		public const string RefStructs = "RefStructs";

		public const string RequiredMembers = "RequiredMembers";

		public string FeatureName { get; }

		public bool IsOptional { get; set; }

		public CompilerFeatureRequiredAttribute(string featureName)
		{
			FeatureName = featureName;
		}
	}
	[AttributeUsage(AttributeTargets.Parameter, Inherited = true, AllowMultiple = false)]
	[ExcludeFromCodeCoverage]
	[Embedded]
	internal sealed class ParamCollectionAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	[Embedded]
	internal sealed class RequiredMemberAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Class, Inherited = false)]
	[ExcludeFromCodeCoverage]
	[Embedded]
	internal sealed class CompilerLoweringPreserveAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
	[EditorBrowsable(EditorBrowsableState.Never)]
	[ExcludeFromCodeCoverage]
	[Embedded]
	internal sealed class RequiresLocationAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	[Embedded]
	internal sealed class InterpolatedStringHandlerArgumentAttribute : Attribute
	{
		public string[] Arguments { get; }

		public InterpolatedStringHandlerArgumentAttribute(string argument)
		{
			Arguments = new string[1] { argument };
		}

		public InterpolatedStringHandlerArgumentAttribute(params string[] arguments)
		{
			Arguments = arguments;
		}
	}
	[AttributeUsage(AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Event | AttributeTargets.Interface, Inherited = false)]
	[ExcludeFromCodeCoverage]
	[Embedded]
	internal sealed class SkipLocalsInitAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Method, Inherited = false)]
	[ExcludeFromCodeCoverage]
	[Embedded]
	internal sealed class ModuleInitializerAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	[Embedded]
	internal sealed class OverloadResolutionPriorityAttribute : Attribute
	{
		public int Priority { get; }

		public OverloadResolutionPriorityAttribute(int priority)
		{
			Priority = priority;
		}
	}
	[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	[Embedded]
	internal sealed class CallerArgumentExpressionAttribute : Attribute
	{
		public string ParameterName { get; }

		public CallerArgumentExpressionAttribute(string parameterName)
		{
			ParameterName = parameterName;
		}
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	[Embedded]
	internal sealed class InterpolatedStringHandlerAttribute : Attribute
	{
	}
	[EditorBrowsable(EditorBrowsableState.Never)]
	[ExcludeFromCodeCoverage]
	[Embedded]
	internal static class IsExternalInit
	{
	}
	[EditorBrowsable(EditorBrowsableState.Never)]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false)]
	[ExcludeFromCodeCoverage]
	[Embedded]
	internal sealed class ExtensionMarkerAttribute : Attribute
	{
		public string Name { get; }

		public ExtensionMarkerAttribute(string name)
		{
			Name = name;
		}
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface, Inherited = false)]
	[ExcludeFromCodeCoverage]
	[Embedded]
	internal sealed class CollectionBuilderAttribute : Attribute
	{
		public Type BuilderType { get; }

		public string MethodName { get; }

		public CollectionBuilderAttribute(Type builderType, string methodName)
		{
			BuilderType = builderType;
			MethodName = methodName;
		}
	}
}
namespace System.Diagnostics.CodeAnalysis
{
	[AttributeUsage(AttributeTargets.Constructor, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	[Embedded]
	internal sealed class SetsRequiredMembersAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	[Embedded]
	internal sealed class UnscopedRefAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
	[ExcludeFromCodeCoverage]
	[Embedded]
	internal sealed class MemberNotNullAttribute : Attribute
	{
		public string[] Members { get; }

		public MemberNotNullAttribute(string member)
		{
			Members = new string[1] { member };
		}

		public MemberNotNullAttribute(params string[] members)
		{
			Members = members;
		}
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	[Embedded]
	internal sealed class StringSyntaxAttribute : Attribute
	{
		public const string CompositeFormat = "CompositeFormat";

		public const string DateOnlyFormat = "DateOnlyFormat";

		public const string DateTimeFormat = "DateTimeFormat";

		public const string EnumFormat = "EnumFormat";

		public const string GuidFormat = "GuidFormat";

		public const string Json = "Json";

		public const string NumericFormat = "NumericFormat";

		public const string Regex = "Regex";

		public const string TimeOnlyFormat = "TimeOnlyFormat";

		public const string TimeSpanFormat = "TimeSpanFormat";

		public const string Uri = "Uri";

		public const string Xml = "Xml";

		public string Syntax { get; }

		public object?[] Arguments { get; }

		public StringSyntaxAttribute(string syntax)
		{
			Syntax = syntax;
			Arguments = new object[0];
		}

		public StringSyntaxAttribute(string syntax, params object?[] arguments)
		{
			Syntax = syntax;
			Arguments = arguments;
		}
	}
	[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
	[ExcludeFromCodeCoverage]
	[Embedded]
	internal sealed class MemberNotNullWhenAttribute : Attribute
	{
		public bool ReturnValue { get; }

		public string[] Members { get; }

		public MemberNotNullWhenAttribute(bool returnValue, string member)
		{
			ReturnValue = returnValue;
			Members = new string[1] { member };
		}

		public MemberNotNullWhenAttribute(bool returnValue, params string[] members)
		{
			ReturnValue = returnValue;
			Members = members;
		}
	}
	[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
	[ExcludeFromCodeCoverage]
	[Embedded]
	internal sealed class ConstantExpectedAttribute : Attribute
	{
		public object? Min { get; set; }

		public object? Max { get; set; }
	}
	[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false)]
	[ExcludeFromCodeCoverage]
	[Embedded]
	internal sealed class ExperimentalAttribute : Attribute
	{
		public string DiagnosticId { get; }

		public string? UrlFormat { get; set; }

		public ExperimentalAttribute(string diagnosticId)
		{
			DiagnosticId = diagnosticId;
		}
	}
}
namespace BepInEx
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	[Embedded]
	internal sealed class BepInAutoPluginAttribute : Attribute
	{
		public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace BepInEx.Preloader.Core.Patching
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	[Embedded]
	internal sealed class PatcherAutoPluginAttribute : Attribute
	{
		public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace Microsoft.CodeAnalysis
{
	[Embedded]
	[AttributeUsage(AttributeTargets.All)]
	[ExcludeFromCodeCoverage]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace Silksong.BingoSync
{
	internal class Controller : IDisposable
	{
		public delegate void CardCallback(Card? card);

		public GoalPool Pool = new GoalPool();

		public readonly EventDispatcher Events;

		private readonly Session _session;

		private readonly HttpClient _client;

		private Card? _card;

		private Task<Card?>? _runningCardUpdate;

		private readonly GoalTracker _tracker;

		public Team Team => _session.Team;

		public bool IsConnected => _session.IsInRoom;

		public event CardCallback? OnCardUpdated;

		public Controller()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Expected O, but got Unknown
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Expected O, but got Unknown
			Events = new EventDispatcher();
			SubscribeToEvents(Events);
			_tracker = new GoalTracker();
			_tracker.OnGoalMarked += new GoalChangedCallback(OnGoalMarked);
			_tracker.OnGoalCleared += new GoalChangedCallback(OnGoalCleared);
			_client = new HttpClient(new LoggingHandler(new HttpClientHandler()))
			{
				Timeout = TimeSpan.FromSeconds(30.0),
				BaseAddress = new Uri("https://bingosync.com"),
				DefaultRequestHeaders = 
				{
					UserAgent = 
					{
						new ProductInfoHeaderValue("dev.warpersan.silksong.bingosync", Plugin.Version)
					}
				}
			};
			_session = new Session(Events, _client, new Uri("wss://sockets.bingosync.com"));
		}

		private void SubscribeToEvents(EventDispatcher events)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Expected O, but got Unknown
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Expected O, but got Unknown
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected O, but got Unknown
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Expected O, but got Unknown
			events.OnSelfConnected += new ConnectionCallback(OnConnected);
			events.OnSelfSquareMarked += new MarkCallback(OnSquareMarked);
			events.OnOtherSquareMarked += new MarkCallback(OnSquareMarked);
			events.OnSelfSquareCleared += new ClearCallback(OnSquareCleared);
			events.OnOtherSquareCleared += new ClearCallback(OnSquareCleared);
			events.OnSelfCardGenerated += new GenerateCallback(OnCardGenerated);
			events.OnOtherCardGenerated += new GenerateCallback(OnCardGenerated);
		}

		private void UnsubscribeFromEvents(EventDispatcher events)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Expected O, but got Unknown
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Expected O, but got Unknown
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected O, but got Unknown
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Expected O, but got Unknown
			events.OnSelfConnected -= new ConnectionCallback(OnConnected);
			events.OnSelfSquareMarked -= new MarkCallback(OnSquareMarked);
			events.OnOtherSquareMarked -= new MarkCallback(OnSquareMarked);
			events.OnSelfSquareCleared -= new ClearCallback(OnSquareCleared);
			events.OnOtherSquareCleared -= new ClearCallback(OnSquareCleared);
			events.OnSelfCardGenerated -= new GenerateCallback(OnCardGenerated);
			events.OnOtherCardGenerated -= new GenerateCallback(OnCardGenerated);
		}

		private void OnConnected(Player player)
		{
			UpdateCard();
		}

		private void OnGoalMarked(Goal goal)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			if (_card == null)
			{
				return;
			}
			int[] array = _card.FindByGoal(goal);
			int[] array2 = array;
			foreach (int num in array2)
			{
				if (!_card.IsMarkedBy(num, _session.Team))
				{
					_session.MarkSquare(num, default(CancellationToken));
				}
			}
		}

		private void OnGoalCleared(Goal goal)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			if (_card == null)
			{
				return;
			}
			int[] array = _card.FindByGoal(goal);
			int[] array2 = array;
			foreach (int num in array2)
			{
				if (_card.IsMarkedBy(num, _session.Team))
				{
					_session.ClearSquare(num, default(CancellationToken));
				}
			}
		}

		private void OnSquareMarked(Player player, Square square, Team team)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			Card? card = _card;
			if (card != null)
			{
				card.Mark(square.Index, team);
			}
			this.OnCardUpdated?.Invoke(_card);
		}

		private void OnSquareCleared(Player player, Square square, Team team)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			Card? card = _card;
			if (card != null)
			{
				card.Unmark(square.Index, team);
			}
			this.OnCardUpdated?.Invoke(_card);
		}

		private void OnCardGenerated(Player player, bool isHidden)
		{
			UpdateCard();
		}

		public Task<bool> Join(JoinRoomSettings settings)
		{
			return _session.JoinRoom(settings, default(CancellationToken));
		}

		public Task<bool> Exit()
		{
			return _session.LeaveRoom(default(CancellationToken));
		}

		public Task<bool> SetTeam(Team team)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			return _session.ChangeTeam(team, default(CancellationToken));
		}

		private void UpdateCard()
		{
			if (_runningCardUpdate != null && !_runningCardUpdate.IsCompleted)
			{
				Log.Warning("An update of 'Card' is already pending.");
				return;
			}
			_runningCardUpdate = Task.Run(() => _session.GetCard(Pool, default(CancellationToken)));
			_runningCardUpdate.ContinueWith(delegate(Task<Card?> task)
			{
				Card result = task.Result;
				_tracker.Clear();
				if (result != null)
				{
					Goal[] allGoals = result.GetAllGoals();
					foreach (Goal val in allGoals)
					{
						_tracker.TryAdd(val);
					}
				}
				_card = result;
				this.OnCardUpdated?.Invoke(_card);
			});
		}

		public void Evaluate()
		{
			_tracker.Evaluate();
		}

		public void Dispose()
		{
			UnsubscribeFromEvents(Events);
			_client.Dispose();
			_session.Dispose();
		}
	}
	internal static class ConfigMenu
	{
		public static AbstractMenuScreen Create(Configuration configuration)
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Expected O, but got Unknown
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Expected O, but got Unknown
			AbstractMenuScreen[] array = (AbstractMenuScreen[])(object)new AbstractMenuScreen[5]
			{
				CreateGeneralConfig(configuration.General),
				CreateJoinConfig(configuration.Join),
				CreateBoardConfig(configuration.Board),
				CreateAccessibilityConfig(configuration.Accessibility),
				CreateExperimentalConfig(configuration.Experimental)
			};
			PaginatedMenuScreenBuilder val = new PaginatedMenuScreenBuilder(LocalizedText.op_Implicit(Plugin.Name), 8);
			AbstractMenuScreen[] array2 = array;
			foreach (AbstractMenuScreen val2 in array2)
			{
				TextButton val3 = new TextButton(val2);
				val.Add((MenuElement)(object)val3);
			}
			return (AbstractMenuScreen)(object)val.Build();
		}

		private static AbstractMenuScreen CreateGeneralConfig(GeneralConfig config)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			PaginatedMenuScreenBuilder val = new PaginatedMenuScreenBuilder(LocalizedText.op_Implicit("General"), 8);
			MenuElement val2 = default(MenuElement);
			if (ConfigEntryFactory.GenerateBoolElement((ConfigEntryBase)(object)config.UseAdvancedTeams, ref val2))
			{
				val.Add(val2);
			}
			return (AbstractMenuScreen)(object)val.Build();
		}

		private static AbstractMenuScreen CreateJoinConfig(JoinConfig config)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			PaginatedMenuScreenBuilder val = new PaginatedMenuScreenBuilder(LocalizedText.op_Implicit("Join"), 8);
			MenuElement val2 = default(MenuElement);
			if (ConfigEntryFactory.GenerateStringElement((ConfigEntryBase)(object)config.Nickname, ref val2))
			{
				val.Add(val2);
			}
			MenuElement val3 = default(MenuElement);
			if (ConfigEntryFactory.GenerateStringElement((ConfigEntryBase)(object)config.Code, ref val3))
			{
				val.Add(val3);
			}
			MenuElement val4 = default(MenuElement);
			if (ConfigEntryFactory.GenerateStringElement((ConfigEntryBase)(object)config.Password, ref val4))
			{
				val.Add(val4);
			}
			MenuElement val5 = default(MenuElement);
			if (ConfigEntryFactory.GenerateKeyCodeElement((ConfigEntryBase)(object)config.ToggleUI, ref val5))
			{
				val.Add(val5);
			}
			return (AbstractMenuScreen)(object)val.Build();
		}

		private static AbstractMenuScreen CreateBoardConfig(BoardConfig config)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			PaginatedMenuScreenBuilder val = new PaginatedMenuScreenBuilder(LocalizedText.op_Implicit("Board"), 8);
			MenuElement val2 = default(MenuElement);
			if (ConfigEntryFactory.GenerateKeyCodeElement((ConfigEntryBase)(object)config.ToggleUI, ref val2))
			{
				val.Add(val2);
			}
			return (AbstractMenuScreen)(object)val.Build();
		}

		private static AbstractMenuScreen CreateExperimentalConfig(ExperimentalConfig config)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			PaginatedMenuScreenBuilder val = new PaginatedMenuScreenBuilder(LocalizedText.op_Implicit("Experimental"), 8);
			TextLabel val2 = new TextLabel(LocalizedText.op_Implicit("Theses settings are experimental and can cause performance issues"));
			((Graphic)val2.Text).color = Color.yellow;
			val2.Text.fontSize = 30;
			val.Add((MenuElement)(object)val2);
			MenuElement val3 = default(MenuElement);
			if (ConfigEntryFactory.GenerateBoolElement((ConfigEntryBase)(object)config.EvaluateOnHeroUpdate, ref val3))
			{
				val.Add(val3);
			}
			return (AbstractMenuScreen)(object)val.Build();
		}

		private static AbstractMenuScreen CreateAccessibilityConfig(AccessibilityConfig config)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			PaginatedMenuScreenBuilder val = new PaginatedMenuScreenBuilder(LocalizedText.op_Implicit("Accessibility"), 8);
			MenuElement val2 = default(MenuElement);
			if (ConfigEntryFactory.GenerateEnumChoiceElement((ConfigEntryBase)(object)config.BoardCellFont, ref val2))
			{
				val.Add(val2);
			}
			MenuElement val3 = default(MenuElement);
			if (ConfigEntryFactory.GenerateEnumChoiceElement((ConfigEntryBase)(object)config.BoardPosition, ref val3))
			{
				val.Add(val3);
			}
			MenuElement val4 = default(MenuElement);
			if (ConfigEntryFactory.GenerateEnumChoiceElement((ConfigEntryBase)(object)config.BoardScale, ref val4))
			{
				val.Add(val4);
			}
			MenuElement val5 = default(MenuElement);
			if (MenuElementGenerators.CreateIntSliderGenerator().Invoke((ConfigEntryBase)(object)config.BoardOpacity, ref val5))
			{
				val.Add(val5);
			}
			return (AbstractMenuScreen)(object)val.Build();
		}
	}
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("dev.warpersan.silksong.bingosync", "Silksong.BingoSync", "1.2.2")]
	public class Plugin : BaseUnityPlugin, IModMenuCustomMenu, IModMenuInterface
	{
		internal static readonly Controller Controller = new Controller();

		public const string Id = "dev.warpersan.silksong.bingosync";

		public static string Name => "Silksong.BingoSync";

		public static string Version => "1.2.2";

		public AbstractMenuScreen BuildCustomMenu()
		{
			return ConfigMenu.Create(Configuration.SafeInstance);
		}

		private void Awake()
		{
			Log.Logger = Log.LogCore;
			Configuration.Load(((BaseUnityPlugin)this).Config);
			Patch.ApplyAll();
			Log.Info("dev.warpersan.silksong.bingosync v" + Version + " has loaded!");
		}

		private void Start()
		{
			ConditionRegistry.RegisterAll();
		}
	}
}
namespace Silksong.BingoSync.UI.Menus
{
	internal class ConnectionMenu : MonoBehaviour
	{
		private enum State
		{
			Offline,
			Connecting,
			Online,
			Disconnecting
		}

		private State _state;

		private CanvasGroup? _canvasGroup;

		private Button? _actionButton;

		private JoinForm? _joinForm;

		private TeamPicker? _teamPicker;

		private void SetOnline()
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			_state = State.Online;
			_joinForm?.DisableInputs();
			if ((Object)(object)_teamPicker != (Object)null)
			{
				_teamPicker.EnableInputs();
				_teamPicker.SetTeam(Plugin.Controller.Team);
			}
		}

		private void SetOffline()
		{
			_state = State.Offline;
			_joinForm?.EnableInputs();
			if ((Object)(object)_teamPicker != (Object)null)
			{
				_teamPicker.DisableInputs();
				_teamPicker.SetTeam((Team)0);
			}
		}

		private void OnActionClicked()
		{
			State state = _state;
			if ((state == State.Connecting || state == State.Disconnecting) ? true : false)
			{
				Log.Warning($"State '{_state}' has no action assigned.");
			}
			else if (_state == State.Offline)
			{
				JoinRoom();
			}
			else if (_state == State.Online)
			{
				LeaveRoom();
			}
		}

		private void OnTeamSelected(Team team)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			if (_state != State.Online)
			{
				Log.Warning("Cannot change team without being online.");
			}
			else
			{
				ChangeTeam(team);
			}
		}

		private void ToggleVisibility()
		{
			if (!((Object)(object)_canvasGroup == (Object)null))
			{
				bool flag = _canvasGroup.alpha > 0f;
				_canvasGroup.alpha = (flag ? 0f : 1f);
				_canvasGroup.blocksRaycasts = !flag;
			}
		}

		private void Update()
		{
			switch (_state)
			{
			case State.Offline:
				_actionButton?.SetText("Join");
				break;
			case State.Connecting:
				_actionButton?.SetText("Connecting...");
				break;
			case State.Online:
				_actionButton?.SetText("Leave");
				break;
			case State.Disconnecting:
				_actionButton?.SetText("Disconnecting...");
				break;
			default:
				throw new ArgumentOutOfRangeException();
			}
		}

		private async Task JoinRoom()
		{
			if (_state != State.Offline)
			{
				throw new InvalidOperationException();
			}
			if ((Object)(object)_joinForm == (Object)null)
			{
				throw new NullReferenceException("No 'JoinForm' assigned.");
			}
			_joinForm.DisableInputs();
			JoinRoomSettings settings = _joinForm.GetSettings();
			try
			{
				_state = State.Connecting;
				if (!(await Plugin.Controller.Join(settings)))
				{
					SetOffline();
					Log.Error("Failed to join the room '" + settings.Code + "'.");
				}
				else
				{
					SetOnline();
				}
			}
			catch (Exception arg)
			{
				SetOffline();
				Log.Error($"Error while joining the room '{settings.Code}': {arg}");
			}
		}

		private async Task LeaveRoom()
		{
			if (_state != State.Online)
			{
				throw new InvalidOperationException();
			}
			_teamPicker?.DisableInputs();
			try
			{
				_state = State.Disconnecting;
				if (!(await Plugin.Controller.Exit()))
				{
					SetOnline();
					Log.Error("Failed to exit the room.");
				}
				else
				{
					SetOffline();
				}
			}
			catch (Exception arg)
			{
				SetOnline();
				Log.Error($"Error while joining the room: {arg}");
			}
		}

		private async Task ChangeTeam(Team team)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			if (_state != State.Online)
			{
				throw new InvalidOperationException();
			}
			Controller controller = Plugin.Controller;
			if (controller == null)
			{
				throw new NullReferenceException("No 'Controller' assigned.");
			}
			if ((Object)(object)_teamPicker == (Object)null)
			{
				throw new NullReferenceException("No 'TeamPicker' assigned.");
			}
			_teamPicker.DisableInputs();
			try
			{
				if (!(await controller.SetTeam(team)))
				{
					Log.Error("Failed to change team.");
				}
			}
			catch (Exception arg)
			{
				Log.Error($"Error while joining the room: {arg}");
			}
			_teamPicker.SetTeam(controller.Team);
			_teamPicker.EnableInputs();
		}

		public static ConnectionMenu Create(JoinRoomSettings settings)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("ConnectionMenu");
			ConnectionMenu connectionMenu = val.AddComponent<ConnectionMenu>();
			RectTransform val2 = val.AddComponent<RectTransform>();
			val2.anchorMin = Vector2.zero;
			val2.anchorMax = Vector2.one;
			val2.offsetMin = Vector2.zero;
			val2.offsetMax = Vector2.zero;
			VerticalLayoutGroup val3 = val.AddComponent<VerticalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)val3).spacing = 10f;
			((LayoutGroup)val3).childAlignment = (TextAnchor)7;
			((HorizontalOrVerticalLayoutGroup)val3).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)val3).childForceExpandWidth = true;
			((HorizontalOrVerticalLayoutGroup)val3).childControlHeight = false;
			((HorizontalOrVerticalLayoutGroup)val3).childForceExpandHeight = false;
			connectionMenu._canvasGroup = val.AddComponent<CanvasGroup>();
			JoinForm joinForm = JoinForm.Create();
			((Component)joinForm).transform.SetParent(((Component)val3).transform, false);
			joinForm.SetSettings(settings);
			connectionMenu._joinForm = joinForm;
			TeamPicker teamPicker = TeamPicker.Create(connectionMenu.OnTeamSelected);
			((Component)teamPicker).transform.SetParent(((Component)val3).transform, false);
			connectionMenu._teamPicker = teamPicker;
			Button button = Button.Create(connectionMenu.OnActionClicked);
			((Component)button).transform.SetParent(val.transform, false);
			connectionMenu._actionButton = button;
			CallOnInput callOnInput = val.AddComponent<CallOnInput>();
			callOnInput.SetInput(Configuration.SafeInstance.Join.ToggleUI, connectionMenu.ToggleVisibility);
			connectionMenu.SetOffline();
			return connectionMenu;
		}
	}
}
namespace Silksong.BingoSync.UI.Items
{
	internal class BingoCell : MonoBehaviour
	{
		private Text? _text;

		private Dictionary<Team, Image>? _teamMarks;

		public void SetSquare(Goal goal, Team teams)
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			Text? text = _text;
			if (text != null)
			{
				text.text = goal.Name;
			}
			if (_teamMarks == null)
			{
				return;
			}
			foreach (KeyValuePair<Team, Image> teamMark in _teamMarks)
			{
				teamMark.Deconstruct(out var key, out var value);
				Team val = key;
				Image val2 = value;
				bool active = ((Enum)teams).HasFlag((Enum)(object)val);
				((Component)val2).gameObject.SetActive(active);
			}
		}

		public void AddTeam(Team team)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			if (_teamMarks != null && _teamMarks.TryGetValue(team, out Image value))
			{
				((Component)value).gameObject.SetActive(true);
			}
		}

		public void RemoveTeam(Team team)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			if (_teamMarks != null && _teamMarks.TryGetValue(team, out Image value))
			{
				((Component)value).gameObject.SetActive(false);
			}
		}

		public static BingoCell Create()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Expected O, but got Unknown
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Expected O, but got Unknown
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Expected O, but got Unknown
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("BingoCell");
			val.AddComponent<RectTransform>();
			BingoCell bingoCell = val.AddComponent<BingoCell>();
			GameObject val2 = new GameObject("Background");
			val2.transform.SetParent(val.transform, false);
			Image val3 = val2.AddComponent<Image>();
			((Graphic)val3).color = new Color(0.1f, 0.1f, 0.1f, 1f);
			VerticalLayoutGroup val4 = val2.AddComponent<VerticalLayoutGroup>();
			((LayoutGroup)val4).childAlignment = (TextAnchor)4;
			Dictionary<Team, Image> dictionary = new Dictionary<Team, Image>();
			foreach (Team value in Enum.GetValues(typeof(Team)))
			{
				if ((int)value != 0)
				{
					GameObject val6 = new GameObject(((object)value/*cast due to .constrained prefix*/).ToString());
					val6.transform.SetParent(((Component)val4).transform, false);
					Image val7 = val6.AddComponent<Image>();
					((Graphic)val7).color = Colors.GetColor(value);
					dictionary.Add(value, val7);
				}
			}
			GameObject val8 = new GameObject("Darkener");
			val8.transform.SetParent(val.transform, false);
			Image val9 = val8.AddComponent<Image>();
			((Graphic)val9).color = new Color(0f, 0f, 0f, 0.4f);
			GameObject val10 = new GameObject("Text");
			val10.transform.SetParent(val.transform, false);
			RectTransform val11 = val10.AddComponent<RectTransform>();
			val11.anchorMin = Vector2.zero;
			val11.anchorMax = Vector2.one;
			val11.offsetMin = Vector2.one * 5f;
			val11.offsetMax = -Vector2.one * 5f;
			Text val12 = val10.AddComponent<Text>();
			val12.fontSize = 12;
			val12.text = "Placeholder";
			val12.alignment = (TextAnchor)3;
			((Graphic)val12).color = Color.white;
			val12.font = Fonts.Normal;
			AccessibilityTextFont accessibilityTextFont = val10.AddComponent<AccessibilityTextFont>();
			accessibilityTextFont.Bind(Configuration.SafeInstance.Accessibility.BoardCellFont);
			bingoCell._text = val12;
			bingoCell._teamMarks = dictionary;
			return bingoCell;
		}
	}
	internal class TeamPickerButton : MonoBehaviour
	{
		private Outline? _outline;

		private Action<Team>? _onClick;

		private Color _teamColor = Color.white;

		public Team Team { get; private set; }

		public void Select()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_outline != (Object)null)
			{
				((Shadow)_outline).effectColor = Color.white;
			}
		}

		public void Unselect()
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_outline != (Object)null)
			{
				((Shadow)_outline).effectColor = _teamColor;
			}
		}

		private void OnClick()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			_onClick?.Invoke(Team);
		}

		public static TeamPickerButton Create(Team team, Action<Team> onClick)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: 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_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Expected O, but got Unknown
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Expected O, but got Unknown
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("TeamPickerButton");
			val.AddComponent<RectTransform>();
			TeamPickerButton teamPickerButton = val.AddComponent<TeamPickerButton>();
			teamPickerButton.Team = team;
			teamPickerButton._onClick = onClick;
			Color val2 = (teamPickerButton._teamColor = team.GetColor());
			Image val3 = val.AddComponent<Image>();
			Color color = val2 * 0.6f;
			color.a = 1f;
			((Graphic)val3).color = color;
			Button val4 = val.AddComponent<Button>();
			((Selectable)val4).targetGraphic = (Graphic)(object)val3;
			((UnityEvent)val4.onClick).AddListener(new UnityAction(teamPickerButton.OnClick));
			ColorBlock colors = ((Selectable)val4).colors;
			((ColorBlock)(ref colors)).disabledColor = new Color(0.3f, 0.3f, 0.3f, 1f);
			((Selectable)val4).colors = colors;
			teamPickerButton._outline = ((Component)val4).gameObject.AddComponent<Outline>();
			GameObject val5 = new GameObject("Text");
			val5.transform.SetParent(val.transform, false);
			RectTransform val6 = val5.AddComponent<RectTransform>();
			val6.anchorMin = Vector2.zero;
			val6.anchorMax = Vector2.one;
			val6.offsetMin = Vector2.zero;
			val6.offsetMax = Vector2.zero;
			Text val7 = val5.AddComponent<Text>();
			val7.font = Fonts.Normal;
			val7.fontSize = 17;
			((Graphic)val7).color = Color.white;
			val7.alignment = (TextAnchor)4;
			val7.text = team.GetDisplayName();
			teamPickerButton.Unselect();
			return teamPickerButton;
		}
	}
}
namespace Silksong.BingoSync.UI.Containers
{
	public class BingoBoard : MonoBehaviour
	{
		private BingoCell[]? _cells;

		private void Awake()
		{
			Subscribe(Plugin.Controller);
		}

		private void DisplayCard(Card? card)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			if (card != null && _cells != null)
			{
				for (int i = 0; i < _cells.Length; i++)
				{
					Goal goalAt = card.GetGoalAt(i);
					Team teamsAt = card.GetTeamsAt(i);
					_cells[i].SetSquare(goalAt, teamsAt);
				}
			}
		}

		private void Subscribe(Controller controller)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Expected O, but got Unknown
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Expected O, but got Unknown
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Expected O, but got Unknown
			controller.OnCardUpdated += DisplayCard;
			EventDispatcher events = controller.Events;
			events.OnSelfSquareMarked += new MarkCallback(OnSquareMarked);
			events.OnOtherSquareMarked += new MarkCallback(OnSquareMarked);
			events.OnSelfSquareCleared += new ClearCallback(OnSquareCleared);
			events.OnOtherSquareCleared += new ClearCallback(OnSquareCleared);
		}

		private void OnSquareMarked(Player player, Square square, Team team)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			BingoCell[]? cells = _cells;
			if (cells != null)
			{
				cells[square.Index].AddTeam(team);
			}
		}

		private void OnSquareCleared(Player player, Square square, Team team)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			BingoCell[]? cells = _cells;
			if (cells != null)
			{
				cells[square.Index].RemoveTeam(team);
			}
		}

		public static BingoBoard Create()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("BingoBoard");
			RectTransform val2 = val.AddComponent<RectTransform>();
			val2.anchorMax = Vector2.one;
			val2.anchorMin = Vector2.one;
			val2.pivot = Vector2.one;
			AccessibilityElementPosition accessibilityElementPosition = val.AddComponent<AccessibilityElementPosition>();
			accessibilityElementPosition.Bind(Configuration.SafeInstance.Accessibility.BoardPosition);
			AccessibilityElementScale accessibilityElementScale = val.AddComponent<AccessibilityElementScale>();
			accessibilityElementScale.Bind(Configuration.SafeInstance.Accessibility.BoardScale);
			ContentSizeFitter val3 = val.AddComponent<ContentSizeFitter>();
			val3.horizontalFit = (FitMode)2;
			val3.verticalFit = (FitMode)2;
			Image val4 = val.AddComponent<Image>();
			((Graphic)val4).color = Color.black;
			BingoBoard bingoBoard = val.AddComponent<BingoBoard>();
			GridLayoutGroup val5 = val.AddComponent<GridLayoutGroup>();
			val5.cellSize = Vector2.one * 100f;
			val5.constraint = (Constraint)1;
			val5.constraintCount = 5;
			((LayoutGroup)val5).childAlignment = (TextAnchor)0;
			val5.spacing = Vector2.one * 5f;
			BingoCell[] array = new BingoCell[25];
			for (int i = 0; i < array.Length; i++)
			{
				BingoCell bingoCell = BingoCell.Create();
				((Component)bingoCell).transform.SetParent(((Component)val5).transform, false);
				array[i] = bingoCell;
			}
			bingoBoard._cells = array;
			CanvasGroup val6 = val.AddComponent<CanvasGroup>();
			val6.blocksRaycasts = false;
			AccessibilityOpacity accessibilityOpacity = val.AddComponent<AccessibilityOpacity>();
			accessibilityOpacity.Bind(Configuration.SafeInstance.Accessibility.BoardOpacity);
			return bingoBoard;
		}
	}
	internal class BoardContainer : MonoBehaviour
	{
		private BingoBoard? _board;

		private CallOnInput? _toggleInput;

		private void Awake()
		{
			Subscribe(Plugin.Controller.Events);
		}

		private void ToggleVisibility()
		{
			if (!((Object)(object)_board == (Object)null))
			{
				bool activeInHierarchy = ((Component)_board).gameObject.activeInHierarchy;
				SetVisibility(!activeInHierarchy);
			}
		}

		private void SetVisibility(bool isVisible)
		{
			if (!((Object)(object)_board == (Object)null))
			{
				((Component)_board).gameObject.SetActive(isVisible);
			}
		}

		private void EnableVisibility()
		{
			if ((Object)(object)_toggleInput != (Object)null)
			{
				((Behaviour)_toggleInput).enabled = true;
			}
			SetVisibility(isVisible: true);
		}

		private void DisableVisibility()
		{
			if ((Object)(object)_toggleInput != (Object)null)
			{
				((Behaviour)_toggleInput).enabled = false;
			}
			SetVisibility(isVisible: false);
		}

		private void Subscribe(EventDispatcher dispatcher)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			dispatcher.OnSelfConnected += (ConnectionCallback)delegate
			{
				EnableVisibility();
			};
			dispatcher.OnSelfDisconnected += (DisconnectionCallback)delegate
			{
				DisableVisibility();
			};
		}

		public static BoardContainer Create()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("BoardContainer");
			BoardContainer boardContainer = val.AddComponent<BoardContainer>();
			RectTransform val2 = val.AddComponent<RectTransform>();
			val2.anchorMin = Vector2.zero;
			val2.anchorMax = Vector2.one;
			val2.offsetMin = Vector2.zero;
			val2.offsetMax = Vector2.zero;
			CallOnInput callOnInput = val.AddComponent<CallOnInput>();
			callOnInput.SetInput(Configuration.SafeInstance.Board.ToggleUI, boardContainer.ToggleVisibility);
			boardContainer._toggleInput = callOnInput;
			BingoBoard bingoBoard = BingoBoard.Create();
			((Component)bingoBoard).transform.SetParent((Transform)(object)val2, false);
			boardContainer._board = bingoBoard;
			boardContainer.DisableVisibility();
			return boardContainer;
		}
	}
	internal class JoinForm : MonoBehaviour
	{
		private CanvasGroup? _canvasGroup;

		private TextField? _roomCodeInput;

		private TextField? _nicknameInput;

		private TextField? _passwordInput;

		public void SetSettings(JoinRoomSettings settings)
		{
			if ((Object)(object)_roomCodeInput != (Object)null)
			{
				_roomCodeInput.Text = settings.Code;
			}
			if ((Object)(object)_nicknameInput != (Object)null)
			{
				_nicknameInput.Text = settings.Nickname;
			}
			if ((Object)(object)_passwordInput != (Object)null)
			{
				_passwordInput.Text = settings.Password;
			}
		}

		public JoinRoomSettings GetSettings()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			JoinRoomSettings val = new JoinRoomSettings();
			if ((Object)(object)_roomCodeInput != (Object)null)
			{
				string text = _roomCodeInput.Text;
				string text2 = default(string);
				if (Network.TryGetRoomCode(text, ref text2))
				{
					text = text2;
				}
				val.Code = text;
			}
			if ((Object)(object)_nicknameInput != (Object)null)
			{
				val.Nickname = _nicknameInput.Text;
			}
			if ((Object)(object)_passwordInput != (Object)null)
			{
				val.Password = _passwordInput.Text;
			}
			return val;
		}

		public void EnableInputs()
		{
			if (!((Object)(object)_canvasGroup == (Object)null))
			{
				_canvasGroup.interactable = true;
			}
		}

		public void DisableInputs()
		{
			if (!((Object)(object)_canvasGroup == (Object)null))
			{
				_canvasGroup.interactable = false;
			}
		}

		public static JoinForm Create()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("JoinForm");
			JoinForm joinForm = val.AddComponent<JoinForm>();
			RectTransform val2 = val.AddComponent<RectTransform>();
			val2.pivot = new Vector2(0.5f, 0f);
			ContentSizeFitter val3 = val.AddComponent<ContentSizeFitter>();
			val3.verticalFit = (FitMode)2;
			VerticalLayoutGroup val4 = val.AddComponent<VerticalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)val4).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)val4).childForceExpandWidth = true;
			((HorizontalOrVerticalLayoutGroup)val4).childControlHeight = false;
			((HorizontalOrVerticalLayoutGroup)val4).childForceExpandHeight = false;
			((HorizontalOrVerticalLayoutGroup)val4).spacing = 10f;
			joinForm._canvasGroup = val.AddComponent<CanvasGroup>();
			TextField textField = TextField.Create("Room Code / Link", (ContentType)0);
			((Component)textField).transform.SetParent(val.transform, false);
			joinForm._roomCodeInput = textField;
			TextField textField2 = TextField.Create("Nickname", (ContentType)0);
			((Component)textField2).transform.SetParent(val.transform, false);
			joinForm._nicknameInput = textField2;
			TextField textField3 = TextField.Create("Password", (ContentType)7);
			((Component)textField3).transform.SetParent(val.transform, false);
			joinForm._passwordInput = textField3;
			return joinForm;
		}
	}
	internal class TeamPicker : MonoBehaviour
	{
		private CanvasGroup? _canvasGroup;

		private Dictionary<Team, TeamPickerButton>? _buttons;

		private Action<Team>? _onTeamSelected;

		private Team _team;

		public void SetTeam(Team team)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			if (TryGetButton(_team, out TeamPickerButton button))
			{
				button.Unselect();
			}
			if (TryGetButton(team, out TeamPickerButton button2))
			{
				button2.Select();
			}
			_team = team;
		}

		public void EnableInputs()
		{
			if (!((Object)(object)_canvasGroup == (Object)null))
			{
				_canvasGroup.interactable = true;
			}
		}

		public void DisableInputs()
		{
			if (!((Object)(object)_canvasGroup == (Object)null))
			{
				_canvasGroup.interactable = false;
			}
		}

		private bool TryGetButton(Team team, [NotNullWhen(true)] out TeamPickerButton? button)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			if (_buttons == null)
			{
				button = null;
				return false;
			}
			return _buttons.TryGetValue(team, out button);
		}

		private void OnTeamSelected(Team team)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			_onTeamSelected?.Invoke(team);
		}

		public static TeamPicker Create(Action<Team> onTeamSelected)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("TeamPicker");
			TeamPicker teamPicker = val.AddComponent<TeamPicker>();
			RectTransform val2 = val.AddComponent<RectTransform>();
			val2.pivot = new Vector2(0.5f, 0f);
			GridLayoutGroup val3 = val.AddComponent<GridLayoutGroup>();
			((LayoutGroup)val3).childAlignment = (TextAnchor)4;
			val3.cellSize = new Vector2(125f, 50f);
			val3.spacing = Vector2.one * 10f;
			ContentSizeFitter val4 = val.AddComponent<ContentSizeFitter>();
			val4.verticalFit = (FitMode)2;
			teamPicker._canvasGroup = val.AddComponent<CanvasGroup>();
			Dictionary<Team, TeamPickerButton> dictionary = new Dictionary<Team, TeamPickerButton>();
			List<Team> list = new List<Team>(4)
			{
				(Team)2,
				(Team)128,
				(Team)32,
				(Team)16
			};
			if (Configuration.SafeInstance.General.UseAdvancedTeams.Value)
			{
				list.Add((Team)512);
				list.Add((Team)256);
				list.Add((Team)1);
				list.Add((Team)8);
			}
			foreach (Team item in list)
			{
				TeamPickerButton teamPickerButton = TeamPickerButton.Create(item, teamPicker.OnTeamSelected);
				((Component)teamPickerButton).transform.SetParent(val.transform, false);
				dictionary[item] = teamPickerButton;
			}
			teamPicker._buttons = dictionary;
			teamPicker._onTeamSelected = onTeamSelected;
			return teamPicker;
		}
	}
}
namespace Silksong.BingoSync.UI.Constants
{
	internal static class Colors
	{
		public static Color GetColor(this Team team)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between Unknown and I4
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Invalid comparison between Unknown and I4
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Expected I4, but got Unknown
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Invalid comparison between Unknown and I4
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Invalid comparison between Unknown and I4
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Invalid comparison between Unknown and I4
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Invalid comparison between Unknown and I4
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Invalid comparison between Unknown and I4
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Invalid comparison between Unknown and I4
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			if ((int)team <= 32)
			{
				switch ((int)team)
				{
				default:
					if ((int)team != 16)
					{
						if ((int)team != 32)
						{
							break;
						}
						return new Color(0.22f, 0.75f, 0.47f);
					}
					return new Color(0.89f, 0.63f, 0f);
				case 4:
					return new Color(0.96f, 0.6f, 0.2f);
				case 2:
					return new Color(1f, 0.28f, 0.27f);
				case 8:
					return new Color(0.37f, 0.29f, 0.27f);
				case 1:
					return new Color(0.93f, 0.52f, 0.67f);
				case 0:
					return Color.black;
				case 3:
				case 5:
				case 6:
				case 7:
					break;
				}
			}
			else if ((int)team <= 128)
			{
				if ((int)team == 64)
				{
					return new Color(0.71f, 0.71f, 0.71f);
				}
				if ((int)team == 128)
				{
					return new Color(0f, 0.71f, 1f);
				}
			}
			else
			{
				if ((int)team == 256)
				{
					return new Color(0.16f, 0.33f, 0.53f);
				}
				if ((int)team == 512)
				{
					return new Color(0.51f, 0.17f, 0.75f);
				}
			}
			throw new ArgumentOutOfRangeException("team", team, null);
		}

		public static string GetDisplayName(this Team team)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between Unknown and I4
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Invalid comparison between Unknown and I4
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Expected I4, but got Unknown
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Invalid comparison between Unknown and I4
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Invalid comparison between Unknown and I4
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Invalid comparison between Unknown and I4
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Invalid comparison between Unknown and I4
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Invalid comparison between Unknown and I4
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Invalid comparison between Unknown and I4
			if ((int)team <= 32)
			{
				switch ((int)team)
				{
				default:
					if ((int)team != 16)
					{
						if ((int)team != 32)
						{
							break;
						}
						return "Mossberry";
					}
					return "Flintgem";
				case 2:
					return "Rosary";
				case 4:
					return "Flintstone";
				case 1:
					return "Voltridian";
				case 8:
					return "Pilgrim";
				case 0:
					return "???";
				case 3:
				case 5:
				case 6:
				case 7:
					break;
				}
			}
			else if ((int)team <= 128)
			{
				if ((int)team == 64)
				{
					return "Growstone";
				}
				if ((int)team == 128)
				{
					return "Plasmium";
				}
			}
			else
			{
				if ((int)team == 256)
				{
					return "Magnetite";
				}
				if ((int)team == 512)
				{
					return "Pollip";
				}
			}
			throw new ArgumentOutOfRangeException("team", team, null);
		}
	}
	internal static class Fonts
	{
		private static readonly Dictionary<string, Font> CachedFonts = new Dictionary<string, Font>();

		public static Font? Normal => GetFont("TrajanPro-Regular");

		public static Font? Bold => GetFont("TrajanPro-Bold");

		public static Font? Arial => GetFont("ARIAL");

		public static Font? Default => Font.GetDefault();

		private static Font? GetFont(string name)
		{
			if (CachedFonts.TryGetValue(name, out Font value))
			{
				return value;
			}
			Font[] array = Resources.FindObjectsOfTypeAll<Font>();
			foreach (Font val in array)
			{
				CachedFonts[((Object)val).name] = val;
			}
			return CachedFonts.GetValueOrDefault(name);
		}
	}
}
namespace Silksong.BingoSync.UI.Components
{
	[RequireComponent(typeof(RectTransform))]
	internal class AccessibilityElementPosition : SettingUpdateNotifier<AccessibilityConfig.ElementPosition>
	{
		private RectTransform? _rectTransform;

		protected override void OnSettingChanged(AccessibilityConfig.ElementPosition value)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_rectTransform == (Object)null))
			{
				switch (value)
				{
				case AccessibilityConfig.ElementPosition.TopLeft:
					_rectTransform.anchorMax = new Vector2(0f, 1f);
					_rectTransform.anchorMin = new Vector2(0f, 1f);
					_rectTransform.pivot = new Vector2(0f, 1f);
					break;
				case AccessibilityConfig.ElementPosition.TopRight:
					_rectTransform.anchorMax = Vector2.one;
					_rectTransform.anchorMin = Vector2.one;
					_rectTransform.pivot = Vector2.one;
					break;
				case AccessibilityConfig.ElementPosition.BottomLeft:
					_rectTransform.anchorMax = Vector2.zero;
					_rectTransform.anchorMin = Vector2.zero;
					_rectTransform.pivot = Vector2.zero;
					break;
				case AccessibilityConfig.ElementPosition.BottomRight:
					_rectTransform.anchorMax = new Vector2(1f, 0f);
					_rectTransform.anchorMin = new Vector2(1f, 0f);
					_rectTransform.pivot = new Vector2(1f, 0f);
					break;
				default:
					throw new ArgumentOutOfRangeException("value", value, null);
				}
			}
		}

		private void Awake()
		{
			_rectTransform = ((Component)this).GetComponent<RectTransform>();
		}
	}
	[RequireComponent(typeof(RectTransform))]
	internal class AccessibilityElementScale : SettingUpdateNotifier<AccessibilityConfig.ElementScale>
	{
		private RectTransform? _rectTransform;

		protected override void OnSettingChanged(AccessibilityConfig.ElementScale value)
		{
			//IL_0032: 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_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_rectTransform == (Object)null))
			{
				RectTransform rectTransform = _rectTransform;
				((Transform)rectTransform).localScale = Vector2.op_Implicit((Vector2)(value switch
				{
					AccessibilityConfig.ElementScale.VerySmall => Vector2.one * 0.5f, 
					AccessibilityConfig.ElementScale.Small => Vector2.one * 0.75f, 
					AccessibilityConfig.ElementScale.Normal => Vector2.one, 
					AccessibilityConfig.ElementScale.Large => Vector2.one * 1.25f, 
					AccessibilityConfig.ElementScale.VeryLarge => Vector2.one * 1.5f, 
					_ => throw new ArgumentOutOfRangeException("value", value, null), 
				}));
			}
		}

		private void Awake()
		{
			_rectTransform = ((Component)this).GetComponent<RectTransform>();
		}
	}
	[RequireComponent(typeof(CanvasGroup))]
	internal class AccessibilityOpacity : SettingUpdateNotifier<int>
	{
		private CanvasGroup? _canvasGroup;

		protected override void OnSettingChanged(int value)
		{
			if (!((Object)(object)_canvasGroup == (Object)null))
			{
				_canvasGroup.alpha = Mathf.Clamp((float)value / 100f, 0f, 1f);
			}
		}

		private void Awake()
		{
			_canvasGroup = ((Component)this).GetComponent<CanvasGroup>();
		}
	}
	[RequireComponent(typeof(Text))]
	internal class AccessibilityTextFont : SettingUpdateNotifier<AccessibilityConfig.TextFont>
	{
		private Text? _text;

		protected override void OnSettingChanged(AccessibilityConfig.TextFont value)
		{
			if (!((Object)(object)_text == (Object)null))
			{
				Text text = _text;
				text.font = (Font)(value switch
				{
					AccessibilityConfig.TextFont.Normal => Fonts.Normal, 
					AccessibilityConfig.TextFont.Bold => Fonts.Bold, 
					AccessibilityConfig.TextFont.Arial => Fonts.Arial, 
					AccessibilityConfig.TextFont.Default => Fonts.Default, 
					_ => throw new ArgumentOutOfRangeException("value", value, null), 
				});
			}
		}

		private void Awake()
		{
			_text = ((Component)this).GetComponent<Text>();
		}
	}
	internal class Button : MonoBehaviour
	{
		private Action? _onClick;

		private Text? _label;

		public void SetText(string text)
		{
			Text? label = _label;
			if (label != null)
			{
				label.text = text;
			}
		}

		private void OnClick()
		{
			_onClick?.Invoke();
		}

		public static Button Create(Action onClick)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Expected O, but got Unknown
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Expected O, but got Unknown
			GameObject val = new GameObject("Button");
			RectTransform val2 = val.AddComponent<RectTransform>();
			val2.anchorMin = Vector2.zero;
			val2.anchorMax = Vector2.one;
			val2.sizeDelta = new Vector2(300f, 50f);
			Image val3 = val.AddComponent<Image>();
			((Graphic)val3).color = new Color(0f, 0f, 0f, 0.6f);
			Button val4 = val.AddComponent<Button>();
			((Selectable)val4).targetGraphic = (Graphic)(object)val3;
			GameObject val5 = new GameObject("Text");
			val5.transform.SetParent(val.transform, false);
			RectTransform val6 = val5.AddComponent<RectTransform>();
			val6.anchorMin = Vector2.zero;
			val6.anchorMax = Vector2.one;
			val6.offsetMin = Vector2.zero;
			val6.offsetMax = Vector2.zero;
			Text val7 = val5.AddComponent<Text>();
			val7.font = Fonts.Normal;
			val7.fontSize = 18;
			((Graphic)val7).color = Color.white;
			val7.alignment = (TextAnchor)4;
			Button button = val.AddComponent<Button>();
			button._onClick = onClick;
			button._label = val7;
			((UnityEvent)val4.onClick).AddListener(new UnityAction(button.OnClick));
			return button;
		}
	}
	internal class CallOnInput : MonoBehaviour
	{
		private Func<KeyCode>? _key;

		private Action? _onInput;

		public void SetInput(ConfigEntry<KeyCode> entry, Action? onInput)
		{
			_key = () => entry.Value;
			_onInput = onInput;
		}

		private void Update()
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			if (_key != null)
			{
				KeyCode val = _key();
				if (Input.GetKeyDown(val))
				{
					_onInput?.Invoke();
				}
			}
		}
	}
	internal class TextField : MonoBehaviour
	{
		private InputField? _inputField;

		public string Text
		{
			get
			{
				if ((Object)(object)_inputField == (Object)null)
				{
					return string.Empty;
				}
				return _inputField.text;
			}
			set
			{
				if (!((Object)(object)_inputField == (Object)null))
				{
					_inputField.text = value;
				}
			}
		}

		public static TextField Create(string placeholder = "", ContentType type = (ContentType)0)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Expected O, but got Unknown
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: 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_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Expected O, but got Unknown
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0211: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("TextField");
			TextField textField = val.AddComponent<TextField>();
			RectTransform val2 = val.AddComponent<RectTransform>();
			val2.anchorMin = new Vector2(0f, 0.5f);
			val2.anchorMax = new Vector2(1f, 0.5f);
			val2.sizeDelta = new Vector2(300f, 40f);
			Image val3 = val.AddComponent<Image>();
			((Graphic)val3).color = new Color(0f, 0f, 0f, 0.6f);
			GameObject val4 = new GameObject("Text");
			val4.transform.SetParent(val.transform, false);
			RectTransform val5 = val4.AddComponent<RectTransform>();
			val5.anchorMin = Vector2.zero;
			val5.anchorMax = Vector2.one;
			val5.offsetMin = new Vector2(10f, 5f);
			val5.offsetMax = new Vector2(-10f, 5f);
			Text val6 = val4.AddComponent<Text>();
			val6.font = Fonts.Normal;
			val6.fontSize = 18;
			((Graphic)val6).color = Color.white;
			val6.alignment = (TextAnchor)3;
			val6.supportRichText = false;
			GameObject val7 = new GameObject("Placeholder");
			val7.transform.SetParent(val.transform, false);
			RectTransform val8 = val7.AddComponent<RectTransform>();
			val8.anchorMin = Vector2.zero;
			val8.anchorMax = Vector2.one;
			val8.offsetMin = new Vector2(10f, 0f);
			val8.offsetMax = new Vector2(-10f, 0f);
			Text val9 = val7.AddComponent<Text>();
			val9.font = val6.font;
			val9.fontSize = val6.fontSize;
			((Graphic)val9).color = new Color(1f, 1f, 1f, 0.5f);
			val9.alignment = (TextAnchor)3;
			val9.text = placeholder;
			val9.fontStyle = (FontStyle)2;
			InputField val10 = val.AddComponent<InputField>();
			val10.textComponent = val6;
			val10.placeholder = (Graphic)(object)val9;
			((Selectable)val10).targetGraphic = (Graphic)(object)val3;
			val10.contentType = type;
			textField._inputField = val10;
			return textField;
		}
	}
}
namespace Silksong.BingoSync.UI.Abstract
{
	internal abstract class SettingUpdateNotifier<T> : MonoBehaviour
	{
		private ConfigEntry<T>? _config;

		public void Bind(ConfigEntry<T> config)
		{
			Unbind();
			_config = config;
			_config.SettingChanged += OnRawSettingChanged;
			SettingChanged(_config.Value);
		}

		public void Unbind()
		{
			ConfigEntry<T>? config = _config;
			if (config != null)
			{
				config.SettingChanged -= OnRawSettingChanged;
			}
			_config = null;
		}

		private void OnRawSettingChanged(object sender, EventArgs e)
		{
			SettingChangedEventArgs e2 = (SettingChangedEventArgs)(object)((e is SettingChangedEventArgs) ? e : null);
			if (e2 != null && e2.ChangedSetting is ConfigEntry<T> val)
			{
				SettingChanged(val.Value);
			}
		}

		private void SettingChanged(T value)
		{
			OnSettingChanged(value);
		}

		protected abstract void OnSettingChanged(T value);

		protected virtual void OnDestroy()
		{
			Unbind();
		}
	}
}
namespace Silksong.BingoSync.Patches
{
	[HarmonyPatch(typeof(GameManager))]
	internal class GameManager_Patches
	{
		private static bool hasInitialized;

		[HarmonyPostfix]
		[HarmonyPatch("Start")]
		private static void Start_Postfix(GameManager __instance)
		{
			if (hasInitialized)
			{
				return;
			}
			string absolutePath = Silksong.BingoSync.Helpers.Path.GetAbsolutePath("Goals/");
			GoalPool val = GoalLoader.LoadPoolFromFolder(absolutePath);
			List<object> list = new List<object>();
			foreach (Goal item in val)
			{
				list.Add(new
				{
					name = item.Name
				});
			}
			Log.Info(JsonConvert.SerializeObject((object)list));
			Plugin.Controller.Pool = val;
			Log.Info($"Loaded '{val.Count}' goals.");
			hasInitialized = true;
		}
	}
	[HarmonyPatch(typeof(HeroController))]
	internal class HeroController_Patches
	{
		[HarmonyPrefix]
		[HarmonyPatch("FixedUpdate")]
		private static void FixedUpdate_Prefix(HeroController __instance)
		{
			Configuration instance = Configuration.Instance;
			if (instance != null && instance.Experimental.EvaluateOnHeroUpdate.Value)
			{
				Plugin.Controller.Evaluate();
			}
		}
	}
	[HarmonyPatch(typeof(PlayerData))]
	internal class PlayerData_Patches
	{
		[HarmonyPostfix]
		[HarmonyPatch("SetBool")]
		private static void SetBool_Postfix()
		{
			Plugin.Controller.Evaluate();
		}
	}
	[HarmonyPatch(typeof(ToolItemManager))]
	internal class ToolItemManager_Patches
	{
		[HarmonyPostfix]
		[HarmonyPatch("ReportCrestUnlocked")]
		private static void ReportCrestUnlocked_Postfix()
		{
			Plugin.Controller.Evaluate();
		}
	}
	[HarmonyPatch(typeof(UIManager))]
	internal class UIManager_Patches
	{
		private static Canvas? _bingoCanvas;

		[HarmonyPostfix]
		[HarmonyPatch("Awake")]
		private static void Awake_Postfix(UIManager __instance)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_bingoCanvas != (Object)null))
			{
				GameObject val = new GameObject("BingoSync.Canvas");
				Object.DontDestroyOnLoad((Object)(object)val);
				Canvas val2 = val.AddComponent<Canvas>();
				val2.renderMode = (RenderMode)0;
				CanvasScaler val3 = val.AddComponent<CanvasScaler>();
				val3.referenceResolution = __instance.canvasScaler.referenceResolution;
				val3.uiScaleMode = (ScaleMode)1;
				val3.screenMatchMode = (ScreenMatchMode)1;
				val.AddComponent<GraphicRaycaster>();
				_bingoCanvas = val2;
				CreateConnectionMenu(val.transform);
				BoardContainer boardContainer = BoardContainer.Create();
				((Component)boardContainer).transform.SetParent(val.transform, false);
			}
		}

		private static void CreateConnectionMenu(Transform parent)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_002a: 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_0054: 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_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Expected O, but got Unknown
			GameObject val = new GameObject("ConnectionMenu-Container");
			val.transform.SetParent(parent, false);
			RectTransform val2 = val.AddComponent<RectTransform>();
			val2.anchorMin = new Vector2(0.75f, 0f);
			val2.anchorMax = new Vector2(1f, 0.5f);
			val2.offsetMin = new Vector2(-20f, 0f);
			val2.offsetMax = new Vector2(0f, 20f);
			val2.pivot = new Vector2(1f, 0f);
			JoinConfig joinConfig = Configuration.Instance?.Join;
			JoinRoomSettings settings = new JoinRoomSettings
			{
				Nickname = (joinConfig?.Nickname.Value ?? ""),
				Code = (joinConfig?.Code.Value ?? ""),
				Password = (joinConfig?.Password.Value ?? "")
			};
			ConnectionMenu connectionMenu = ConnectionMenu.Create(settings);
			((Component)connectionMenu).transform.SetParent(val.transform, false);
			RectTransform val3 = default(RectTransform);
			if (((Component)connectionMenu).TryGetComponent<RectTransform>(ref val3))
			{
				Canvas.ForceUpdateCanvases();
				LayoutRebuilder.ForceRebuildLayoutImmediate(val3);
			}
		}
	}
}
namespace Silksong.BingoSync.Networking
{
	internal class LoggingHandler : DelegatingHandler
	{
		public LoggingHandler(HttpMessageHandler innerHandler)
			: base(innerHandler)
		{
		}

		protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
		{
			string arg = "";
			if (request.Content != null)
			{
				arg = await request.Content.ReadAsStringAsync();
			}
			Log.Debug($"Request:\n{request}\n{arg}");
			HttpResponseMessage response = await base.SendAsync(request, cancellationToken);
			string arg2 = "";
			if (response.Content != null)
			{
				arg2 = await response.Content.ReadAsStringAsync();
			}
			Log.Debug($"Response:\n{response}\n{arg2}");
			return response;
		}
	}
}
namespace Silksong.BingoSync.Helpers
{
	internal static class GoalLoader
	{
		public static GoalPool LoadPoolFromFolder(string folder)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			GoalPool val = new GoalPool();
			if (!Directory.Exists(folder))
			{
				Log.Warning("Folder '" + folder + "' does not exist.");
				return val;
			}
			string[] files = Directory.GetFiles(folder, "*.json", SearchOption.AllDirectories);
			string[] array = files;
			foreach (string text in array)
			{
				try
				{
					GoalSet val2 = LoadSetFromFile(text);
					Goal[] goals = val2.Goals;
					foreach (Goal val3 in goals)
					{
						val.TryAdd(val3);
					}
				}
				catch (Exception arg)
				{
					Log.Error($"Error while loading '{text}': {arg}");
				}
			}
			return val;
		}

		public static GoalSet LoadSetFromFile(string file)
		{
			string text = File.ReadAllText(file);
			GoalSet val = JsonConvert.DeserializeObject<GoalSet>(text);
			if (val == (GoalSet)null)
			{
				throw new InvalidOperationException("Must parse a valid 'GoalSet'.");
			}
			return val;
		}
	}
	internal static class Log
	{
		private static readonly Lazy<ManualLogSource> Logger = new Lazy<ManualLogSource>((Func<ManualLogSource>)(() => Logger.CreateLogSource("dev.warpersan.silksong.bingosync")));

		public static void LogCore(LogLevel level, string message)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected I4, but got Unknown
			switch ((int)level)
			{
			case 0:
				Debug(message);
				break;
			case 2:
				Warning(message);
				break;
			case 3:
				Error(message);
				break;
			default:
				Info(message);
				break;
			}
		}

		public static void Debug(string? message)
		{
			Logger.Value.LogDebug((object)message);
		}

		public static void Info(string? message)
		{
			Logger.Value.LogInfo((object)message);
		}

		public static void Warning(string? message)
		{
			Logger.Value.LogWarning((object)message);
		}

		public static void Error(string? message)
		{
			Logger.Value.LogError((object)message);
		}
	}
	internal static class Patch
	{
		public static void ApplyAll()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			Harmony val = new Harmony("dev.warpersan.silksong.bingosync");
			val.PatchAll(typeof(UIManager_Patches));
			val.PatchAll(typeof(PlayerData_Patches));
			val.PatchAll(typeof(ToolItemManager_Patches));
			val.PatchAll(typeof(HeroController_Patches));
			val.PatchAll(typeof(GameManager_Patches));
			Log.Debug("All patches applied.");
		}
	}
	internal static class Path
	{
		public static string GetPluginFolder()
		{
			string location = Assembly.GetExecutingAssembly().Location;
			string directoryName = System.IO.Path.GetDirectoryName(location);
			return directoryName ?? string.Empty;
		}

		public static string GetAbsolutePath(string relativePath)
		{
			string pluginFolder = GetPluginFolder();
			return System.IO.Path.Combine(pluginFolder, relativePath);
		}
	}
}
namespace Silksong.BingoSync.Factories
{
	[ConditionFactory("has_completed_wish_count")]
	internal sealed class HasCompletedWishCountCondition : ParameterizedConditionFactory<HasCompletedWishCountCondition.Parameters>
	{
		public sealed class Parameters
		{
			[JsonProperty("amount")]
			[JsonRequired]
			[Description("Minimum number of conditions that must be met")]
			public uint Amount { get; init; }

			[JsonProperty("type")]
			[Description("Type of the wish to keep")]
			public WishType? Type { get; init; }
		}

		private static ICondition CreateCondition(Wish wish)
		{
			return (ICondition)(object)new HasCompletedWishCondition
			{
				Wish = wish
			};
		}

		private static IEnumerable<Wish> GetWishes(Parameters parameters)
		{
			foreach (Wish value in Enum.GetValues(typeof(Wish)))
			{
				if (parameters.Type.HasValue)
				{
					WishType wishType = value.GetWishType();
					if (parameters.Type.Value != wishType)
					{
						continue;
					}
				}
				yield return value;
			}
		}

		protected override ICondition Generate(Parameters parameters)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Expected O, but got Unknown
			List<ICondition> conditions = GetWishes(parameters).Select(CreateCondition).ToList();
			SomeCondition val = new SomeCondition();
			val.set_Amount(parameters.Amount);
			val.set_Conditions((IReadOnlyCollection<ICondition>)conditions);
			return (ICondition)val;
		}
	}
	[ConditionFactory("has_found_flea_count")]
	internal sealed class HasFoundFleaCountCondition : ParameterizedConditionFactory<HasFoundFleaCountCondition.Parameters>
	{
		public sealed class Parameters
		{
			[JsonProperty("amount")]
			[JsonRequired]
			[Description("Minimum number of conditions that must be met")]
			public uint Amount { get; init; }

			[JsonProperty("area")]
			[Description("Area of the fleas to keep")]
			public Area? Area { get; init; }

			[JsonProperty("include_unique")]
			[Description("Defines if the unique fleas must be included")]
			public bool? IncludeUnique { get; init; }
		}

		private static ICondition CreateCondition(Flea flea)
		{
			return (ICondition)(object)new HasFoundFleaCondition
			{
				Flea = flea
			};
		}

		private static IEnumerable<Flea> GetFleas(Parameters parameters)
		{
			foreach (Flea value in Enum.GetValues(typeof(Flea)))
			{
				if (parameters.Area.HasValue)
				{
					Area area = value.GetArea();
					if (parameters.Area.Value != area)
					{
						continue;
					}
				}
				if (!parameters.IncludeUnique.HasValue || !value.IsUnique() || parameters.IncludeUnique.Value)
				{
					yield return value;
				}
			}
		}

		protected override ICondition Generate(Parameters parameters)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Expected O, but got Unknown
			List<ICondition> conditions = GetFleas(parameters).Select(CreateCondition).ToList();
			SomeCondition val = new SomeCondition();
			val.set_Amount(parameters.Amount);
			val.set_Conditions((IReadOnlyCollection<ICondition>)conditions);
			return (ICondition)val;
		}
	}
	[ConditionFactory("has_obtained_tool_count")]
	internal sealed class HasObtainedToolCountCondition : ParameterizedConditionFactory<HasObtainedToolCountCondition.Parameters>
	{
		public sealed class Parameters
		{
			[JsonProperty("amount")]
			[JsonRequired]
			[Description("Minimum number of conditions that must be met")]
			public uint Amount { get; init; }

			[JsonProperty("type")]
			[Description("Type of the tool to keep")]
			public ToolType? Type { get; init; }
		}

		private static ICondition CreateCondition(Tool tool)
		{
			return (ICondition)(object)new HasObtainedToolCondition
			{
				Tool = tool
			};
		}

		private static IEnumerable<Tool> GetTools(Parameters parameters)
		{
			foreach (Tool value in Enum.GetValues(typeof(Tool)))
			{
				if (parameters.Type.HasValue)
				{
					ToolType toolType = value.GetToolType();
					if (parameters.Type.Value != toolType)
					{
						continue;
					}
				}
				yield return value;
			}
		}

		protected override ICondition Generate(Parameters parameters)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Expected O, but got Unknown
			List<ICondition> conditions = GetTools(parameters).Select(CreateCondition).ToList();
			SomeCondition val = new SomeCondition();
			val.set_Amount(parameters.Amount);
			val.set_Conditions((IReadOnlyCollection<ICondition>)conditions);
			return (ICondition)val;
		}
	}
}
namespace Silksong.BingoSync.Extensions
{
	public static class PlayerDataExtensions
	{
		public static bool HasObtainedAncestralArt(this PlayerData data, AncestralArt art)
		{
			return art switch
			{
				AncestralArt.SwiftStep => data.hasDash, 
				AncestralArt.ClingGrip => data.hasWalljump, 
				AncestralArt.Needolin => data.hasNeedolin, 
				AncestralArt.Clawline => data.hasHarpoonDash, 
				AncestralArt.SilkSoar => data.hasSuperJump, 
				AncestralArt.Sylphsong => data.HasSeenEvaHeal, 
				_ => throw new InvalidCheckException<AncestralArt>(art), 
			};
		}

		public static bool HasObtainedMap(this PlayerData data, Area area)
		{
			return area switch
			{
				Area.TheAbyss => data.HasAbyssMap, 
				Area.Bellhart => data.HasBellhartMap, 
				Area.Bilewater => data.HasSwampMap, 
				Area.BlastedSteps => data.HasJudgeStepsMap, 
				Area.BoneBottom => data.HasMossGrottoMap, 
				Area.TheCradle => data.HasCradleMap, 
				Area.DeepDocks => data.HasDocksMap, 
				Area.FarFields => data.HasWildsMap, 
				Area.Greymoor => data.HasGreymoorMap, 
				Area.HuntersMarch => data.HasHuntersNestMap, 
				Area.TheMarrow => data.HasBoneforestMap, 
				Area.TheMist => false, 
				Area.MossGrotto => false, 
				Area.MountFay => data.HasPeakMap, 
				Area.PutrifiedDucts => data.HasAqueductMap, 
				Area.RedMemory => false, 
				Area.SandsOfKarak => data.HasCoralMap, 
				Area.Shellwood => data.HasShellwoodMap, 
				Area.SinnersRoad => data.HasDustpensMap, 
				Area.TheSlab => data.HasSlabMap, 
				Area.Underworks => data.HasCitadelUnderstoreMap, 
				Area.Verdania => data.HasCloverMap, 
				Area.WeavenestAtla => data.HasWeavehomeMap, 
				Area.WispThicket => false, 
				Area.Wormways => data.HasCrawlMap, 
				Area.ChoralChambers => data.HasHallsMap, 
				Area.CogworkCore => data.HasCogMap, 
				Area.GrandGate => data.HasSongGateMap, 
				Area.HighHalls => data.HasHangMap, 
				Area.Memorium => data.HasArboriumMap, 
				Area.WhisperingVaults => data.HasLibraryMap, 
				Area.Whiteward => data.HasWardMap, 
				_ => throw new InvalidCheckException<Area>(area), 
			};
		}

		public static bool HasKilledBoss(this PlayerData data, Boss boss)
		{
			return boss switch
			{
				Boss.BellBeast => data.defeatedBellBeast, 
				Boss.FourthChorus => data.defeatedSongGolem, 
				Boss.GreatConchflies => data.defeatedCoralDrillers, 
				Boss.Lace1 => data.defeatedLace1, 
				Boss.LastJudge => data.defeatedLastJudge, 
				Boss.Moorwing => data.defeatedVampireGnatBoss, 
				Boss.MossMother => data.defeatedMossMother, 
				Boss.MossMothers => data.HasJournalEntry(Boss.MossMothers), 
				Boss.Phantom => data.defeatedPhantom, 
				Boss.SavageBeastfly1 => data.defeatedBoneFlyerGiant, 
				Boss.SisterSplinter => data.defeatedSplinterQueen, 
				Boss.SkullTyrant1 => data.skullKingDefeated, 
				Boss.SkullTyrant2 => data.HasJournalEntry(Boss.SkullTyrant2), 
				Boss.Widow => data.spinnerDefeated, 
				Boss.Broodmother => data.defeatedBroodMother, 
				Boss.CogworkDancers => data.defeatedCogworkDancers, 
				Boss.DisgracedChefLugoli => data.defeatedRoachkeeperChef, 
				Boss.FatherOfTheFlame => data.defeatedWispPyreEffigy, 
				Boss.FirstSinner => data.defeatedFirstWeaver, 
				Boss.Forebrothers => data.defeatedDockForemen, 
				Boss.Garmond => data.HasJournalEntry(Boss.Garmond), 
				Boss.GrandMotherSilk => data.HasCompletedEnding(Ending.WeaverQueen) || data.HasCompletedEnding(Ending.SnaredSilk) || data.HasCompletedEnding(Ending.TwistedChild), 
				Boss.Groal => data.DefeatedSwampShaman, 
				Boss.Lace2 => data.defeatedLaceTower, 
				Boss.RagingConchfly => data.defeatedCoralDrillerSolo, 
				Boss.SavageBeastfly2 => data.defeatedBoneFlyerGiantGolemScene, 
				Boss.SecondSentinel => data.defeatedSongChevalierBoss, 
				Boss.Shakra => data.HasJournalEntry(Boss.Shakra), 
				Boss.TheUnravelled => data.wardBossDefeated, 
				Boss.Trobbio => data.defeatedTrobbio, 
				Boss.Voltvyrm => data.defeatedZapCoreEnemy, 
				Boss.BellEater => data.HasJournalEntry(Boss.BellEater), 
				Boss.CloverDancers => data.defeatedCloverDancers, 
				Boss.Crawfather => data.defeatedCrowCourt, 
				Boss.CrustKingKhann => data.defeatedCoralKing, 
				Boss.GurrTheOutcast => data.defeatedAntTrapper, 
				Boss.LostGarmond => data.garmondBlackThreadDefeated, 
				Boss.LostLace => data.HasCompletedEnding(Ending.SisterOfTheVoid), 
				Boss.Nyleth => data.defeatedFlowerQueen, 
				Boss.Palestag => data.defeatedWhiteCloverstag, 
				Boss.Pinstress => data.HasJournalEntry(Boss.Pinstress), 
				Boss.PlasmifiedZango => data.BlueScientistDead, 
				Boss.ShrineGuardianSeth => data.defeatedSeth, 
				Boss.SkarrsingerKarmelita => data.defeatedAntQueen, 
				Boss.TormentedTrobbio => data.defeatedTormentedTrobbio, 
				Boss.Watcher => data.defeatedGreyWarrior, 
				_ => throw new InvalidCheckException<Boss>(boss), 
			};
		}

		private static string GetCrestId(Crest crest)
		{
			return crest switch
			{
				Crest.Hunter => "Hunter", 
				Crest.HunterEvolved => "Hunter_v2", 
				Crest.HunterFullyEvolved => "Hunter_v3", 
				Crest.Reaper => "Reaper", 
				Crest.Wanderer => "Wanderer", 
				Crest.Beast => "Warrior", 
				Crest.Cursed => "Cursed", 
				Crest.Witch => "Witch", 
				Crest.Architect => "Toolmaster", 
				Crest.Shaman => "Spell", 
				Crest.Cloakless => "Cloakless", 
				_ => throw new InvalidCheckException<Crest>(crest), 
			};
		}

		private static Data? GetCrestData(this PlayerData data, Crest crest)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			string crestId = GetCrestId(crest);
			return ((SerializableNamedList<Data, NamedData>)(object)data.ToolEquips).GetData(crestId);
		}

		public static bool HasObtainedCrest(this PlayerData data, Crest crest)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			Data? crestData = data.GetCrestData(crest);
			if (!crestData.HasValue)
			{
				return false;
			}
			return crestData.Value.IsUnlocked;
		}

		public static bool HasCompletedEnding(this PlayerData data, Ending ending)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			return ending switch
			{
				Ending.WeaverQueen => ((Enum)data.CompletedEndings).HasFlag((Enum)(object)(CompletionState)1), 
				Ending.SnaredSilk => ((Enum)data.CompletedEndings).HasFlag((Enum)(object)(CompletionState)4), 
				Ending.TwistedChild => ((Enum)data.CompletedEndings).HasFlag((Enum)(object)(CompletionState)2), 
				Ending.SisterOfTheVoid => ((Enum)data.CompletedEndings).HasFlag((Enum)(object)(CompletionState)8), 
				Ending.PassingOfTheAge => data.MushroomQuestCompleted, 
				_ => throw new InvalidCheckException<Ending>(ending), 
			};
		}

		public static bool HasFoundFlea(this PlayerData data, Flea flea)
		{
			return flea switch
			{
				Flea.AboveMarrowBellways => data.SavedFlea_Bone_06, 
				Flea.BehindDeepDocksBellways => data.SavedFlea_Dock_16, 
				Flea.LeftOfSwiftStep => data.SavedFlea_Bone_East_05, 
				Flea.BehindDeepDocksFurnaceGauntlet => data.SavedFlea_Dock_03d, 
				Flea.BehindSkarrgard => data.SavedFlea_Ant_03, 
				Flea.BehindHunterBoobyTrap => data.SavedFlea_Bone_East_17b, 
				Flea.NextToPilgrimsRest => data.SavedFlea_Bone_East_10_Church, 
				Flea.CarriedByAknid => data.SavedFlea_Crawl_06, 
				Flea.AboveCrawLake => data.SavedFlea_Greymoor_15b, 
				Flea.TopOfGreymoorLeftTower => data.SavedFlea_Greymoor_06, 
				Flea.Kratt => data.CaravanLechSaved, 
				Flea.AboveBellhart => data.SavedFlea_Belltown_04, 
				Flea.InGahliaPit => data.SavedFlea_Shellwood_03, 
				Flea.AboveGrindle => data.SavedFlea_Coral_35, 
				Flea.TrappedInSinnersRoad => data.SavedFlea_Dust_12, 
				Flea.GuardedBySnitchflies => data.SavedFlea_Shadow_28, 
				Flea.BesideExhaustOrgan => data.SavedFlea_Dust_09, 
				Flea.AboveSecretBilewaterBench => data.SavedFlea_Shadow_10, 
				Flea.AfterWispThicket => data.SavedFlea_Under_23, 
				Flea.AcrossCogworkHaulersRoom => data.SavedFlea_Under_21, 
				Flea.AfterChoralChambersPlatforming => data.SavedFlea_Song_14, 
				Flea.AfterVerticalSawbladesRoom => data.SavedFlea_Song_11, 
				Flea.HugeFlea => data.tamedGiantFlea, 
				Flea.JailedInSlab => data.SavedFlea_Slab_Cell, 
				Flea.AboveSlabBench => data.SavedFlea_Slab_06, 
				Flea.FrozenInIce => data.SavedFlea_Peak_05c, 
				Flea.UnderVoltnest => data.SavedFlea_Coral_24, 
				Flea.Vog => data.MetTroupeHunterWild, 
				Flea.RightOfSongclave => data.SavedFlea_Library_09, 
				Flea.RightOfBoxPuzzle => data.SavedFlea_Library_01, 
				_ => throw new InvalidCheckException<Flea>(flea), 
			};
		}

		public static Area GetArea(this Flea flea)
		{
			return flea switch
			{
				Flea.AboveMarrowBellways => Area.TheMarrow, 
				Flea.BehindDeepDocksBellways => Area.DeepDocks, 
				Flea.LeftOfSwiftStep => Area.DeepDocks, 
				Flea.BehindDeepDocksFurnaceGauntlet => Area.DeepDocks, 
				Flea.BehindSkarrgard => Area.HuntersMarch, 
				Flea.BehindHunterBoobyTrap => Area.FarFields