Decompiled source of Silksong BingoSync v1.2.1

plugins/Silksong.BingoSync.dll

Decompiled 3 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.IO;
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.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.Configurations;
using Silksong.BingoSync.Data;
using Silksong.BingoSync.Exceptions;
using Silksong.BingoSync.Extensions;
using Silksong.BingoSync.Helpers;
using Silksong.BingoSync.Patches;
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.1.0")]
[assembly: AssemblyInformationalVersion("1.2.1+ba48522cc26b3a1d273431498be59bf018289fee")]
[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 Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace BepInEx
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	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")]
	internal sealed class PatcherAutoPluginAttribute : Attribute
	{
		public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
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 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_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Expected O, but got Unknown
			Events = new EventDispatcher();
			SubscribeToEvents(Events);
			_tracker = new GoalTracker();
			_tracker.OnGoalMarked += new GoalChangedCallback(OnGoalMarked);
			_tracker.OnGoalCleared += new GoalChangedCallback(OnGoalCleared);
			_session = new Session(Events);
		}

		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_0017: Unknown result type (might be due to invalid IL or missing references)
			Card? card = _card;
			if (card != null)
			{
				card.Mark(square.Slot.Index, team);
			}
			this.OnCardUpdated?.Invoke(_card);
		}

		private void OnSquareCleared(Player player, Square square, Team team)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			Card? card = _card;
			if (card != null)
			{
				card.Unmark(square.Slot.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);
			_session.Dispose();
		}
	}
	internal static class ConfigMenu
	{
		public static AbstractMenuScreen Create(Configuration configuration)
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Expected O, but got Unknown
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Expected O, but got Unknown
			AbstractMenuScreen[] array = (AbstractMenuScreen[])(object)new AbstractMenuScreen[4]
			{
				CreateGeneralConfig(configuration.General),
				CreateJoinConfig(configuration.Join),
				CreateBoardConfig(configuration.Board),
				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.GenerateKeyCodeElement((ConfigEntryBase)(object)config.ToggleUI, ref val3))
			{
				val.Add(val3);
			}
			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();
		}
	}
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("dev.warpersan.silksong.bingosync", "Silksong.BingoSync", "1.2.1")]
	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.1";

		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()
		{
			ConditionAttribute.AddAll();
			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));
			Controller.Pool = val;
			Log.Info($"Loaded '{val.Count}' goals.");
		}
	}
}
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);
			}
		}

		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 = "OwO";
			val12.alignment = (TextAnchor)3;
			((Graphic)val12).color = Color.white;
			val12.font = Fonts.Normal;
			bingoCell._text = val12;
			bingoCell._teamMarks = dictionary;
			return bingoCell;
		}
	}
	internal class TeamPickerButton : MonoBehaviour
	{
		private Outline? _outline;

		private Action<Team>? _onClick;

		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)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_outline != (Object)null)
			{
				((Shadow)_outline).effectColor = Team.GetColor();
			}
		}

		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_002e: 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_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Expected O, but got Unknown
			//IL_0071: 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_008e: 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_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Expected O, but got Unknown
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: 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;
			Image val2 = val.AddComponent<Image>();
			Color black = Color.black;
			black.a = 0.6f;
			((Graphic)val2).color = black;
			Button val3 = val.AddComponent<Button>();
			((Selectable)val3).targetGraphic = (Graphic)(object)val2;
			((UnityEvent)val3.onClick).AddListener(new UnityAction(teamPickerButton.OnClick));
			ColorBlock colors = ((Selectable)val3).colors;
			((ColorBlock)(ref colors)).disabledColor = new Color(0.3f, 0.3f, 0.3f, 1f);
			((Selectable)val3).colors = colors;
			Outline outline = ((Component)val3).gameObject.AddComponent<Outline>();
			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 = Vector2.zero;
			val5.offsetMax = Vector2.zero;
			Text val6 = val4.AddComponent<Text>();
			val6.font = Fonts.Normal;
			val6.fontSize = 17;
			((Graphic)val6).color = Color.white;
			val6.alignment = (TextAnchor)4;
			val6.text = team.GetDisplayName();
			teamPickerButton._outline = outline;
			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_0017: Unknown result type (might be due to invalid IL or missing references)
			BingoCell[]? cells = _cells;
			if (cells != null)
			{
				cells[square.Slot.Index].AddTeam(team);
			}
		}

		private void OnSquareCleared(Player player, Square square, Team team)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			BingoCell[]? cells = _cells;
			if (cells != null)
			{
				cells[square.Slot.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_0050: 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_0076: 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_00a4: 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;
			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;
			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 Lazy<(Font? Bold, Font? Normal)> TrajanFonts = new Lazy<(Font, Font)>(delegate
		{
			Font item = null;
			Font item2 = null;
			Font[] array = Resources.FindObjectsOfTypeAll<Font>();
			foreach (Font val in array)
			{
				if (!((Object)(object)val == (Object)null))
				{
					string name = ((Object)val).name;
					if (!(name == "TrajanPro-Bold"))
					{
						if (name == "TrajanPro-Regular")
						{
							item2 = val;
						}
					}
					else
					{
						item = val;
					}
				}
			}
			return (Bold: item, Normal: item2);
		});

		public static Font? Normal => TrajanFonts.Value.Normal;

		public static Font? Bold => TrajanFonts.Value.Bold;
	}
}
namespace Silksong.BingoSync.UI.Components
{
	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.Patches
{
	[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_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_00b8: 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);
			JoinRoomSettings settings = new JoinRoomSettings
			{
				Nickname = (Configuration.Instance?.Join.Nickname.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.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));
			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.Extensions
{
	public static class PlayerDataExtensions
	{
		public static bool HasAncestralArt(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 IsBossKilled(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.IsEndingCompleted(Ending.WeaverQueen) || data.IsEndingCompleted(Ending.SnaredSilk) || data.IsEndingCompleted(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.IsEndingCompleted(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 HasCrest(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 IsEndingCompleted(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), 
			};
		}

		private static KillData GetKillData(this PlayerData data, string key)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			return data.EnemyJournalKillData.GetKillData(key);
		}

		private static int GetKillCount(this PlayerData data, string key)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			return data.GetKillData(key).Kills;
		}

		private static bool HasJournalEntry(this PlayerData data, string key)
		{
			return data.GetKillCount(key) > 0;
		}

		public static bool HasJournalEntry(this PlayerData data, Boss boss)
		{
			return boss switch
			{
				Boss.Shakra => data.HasJournalEntry("Shakra"), 
				Boss.BellBeast => throw new NotImplementedException(), 
				Boss.FourthChorus => throw new NotImplementedException(), 
				Boss.GreatConchflies => throw new NotImplementedException(), 
				Boss.Lace1 => throw new NotImplementedException(), 
				Boss.LastJudge => throw new NotImplementedException(), 
				Boss.Moorwing => throw new NotImplementedException(), 
				Boss.MossMother => data.HasJournalEntry("Mossbone Mother"), 
				Boss.MossMothers => data.GetKillCount("Mossbone Mother") >= 3, 
				Boss.Phantom => throw new NotImplementedException(), 
				Boss.SavageBeastfly1 => throw new NotImplementedException(), 
				Boss.SisterSplinter => throw new NotImplementedException(), 
				Boss.SkullTyrant1 => data.HasJournalEntry("Skull King"), 
				Boss.SkullTyrant2 => data.GetKillCount("Skull King") >= 2, 
				Boss.Widow => throw new NotImplementedException(), 
				Boss.Broodmother => throw new NotImplementedException(), 
				Boss.CogworkDancers => throw new NotImplementedException(), 
				Boss.DisgracedChefLugoli => throw new NotImplementedException(), 
				Boss.FatherOfTheFlame => throw new NotImplementedException(), 
				Boss.FirstSinner => throw new NotImplementedException(), 
				Boss.Forebrothers => throw new NotImplementedException(), 
				Boss.Garmond => data.HasJournalEntry("Garmond"), 
				Boss.GrandMotherSilk => throw new NotImplementedException(), 
				Boss.Groal => throw new NotImplementedException(), 
				Boss.Lace2 => throw new NotImplementedException(), 
				Boss.RagingConchfly => throw new NotImplementedException(), 
				Boss.SavageBeastfly2 => throw new NotImplementedException(), 
				Boss.SecondSentinel => throw new NotImplementedException(), 
				Boss.TheUnravelled => throw new NotImplementedException(), 
				Boss.Trobbio => throw new NotImplementedException(), 
				Boss.Voltvyrm => throw new NotImplementedException(), 
				Boss.BellEater => data.HasJournalEntry("Giant Centipede"), 
				Boss.CloverDancers => throw new NotImplementedException(), 
				Boss.Crawfather => throw new NotImplementedException(), 
				Boss.CrustKingKhann => throw new NotImplementedException(), 
				Boss.GurrTheOutcast => throw new NotImplementedException(), 
				Boss.LostGarmond => throw new NotImplementedException(), 
				Boss.LostLace => throw new NotImplementedException(), 
				Boss.Nyleth => throw new NotImplementedException(), 
				Boss.Palestag => throw new NotImplementedException(), 
				Boss.Pinstress => data.HasJournalEntry("Pinstress Boss"), 
				Boss.PlasmifiedZango => throw new NotImplementedException(), 
				Boss.ShrineGuardianSeth => throw new NotImplementedException(), 
				Boss.SkarrsingerKarmelita => throw new NotImplementedException(), 
				Boss.TormentedTrobbio => throw new NotImplementedException(), 
				Boss.Watcher => throw new NotImplementedException(), 
				_ => throw new InvalidCheckException<Boss>(boss), 
			};
		}

		private static string GetMementoId(Memento memento)
		{
			return memento switch
			{
				Memento.Sprintmaster => "Sprintmaster Memento", 
				Memento.Guardian => "Memento Seth", 
				Memento.Hero => "Memento Garmond", 
				Memento.Hunter => "Hunter Memento", 
				Memento.Grey => "Grey Memento", 
				Memento.Surface => "Memento Surface", 
				Memento.Craw => "Crowman Memento", 
				Memento.EncrustedHeart => "Coral Heart", 
				Memento.PollenHeart => "Flower Heart", 
				Memento.HunterHeart => "Hunter Heart", 
				Memento.ConjoinedHeart => "Clover Heart", 
				_ => throw new InvalidCheckException<Memento>(memento), 
			};
		}

		private static Data? GetMementoData(this PlayerData data, Memento memento)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			string mementoId = GetMementoId(memento);
			return ((SerializableNamedList<Data, NamedData>)(object)data.MementosDeposited).GetData(mementoId);
		}

		public static bool HasMemento(this PlayerData data, Memento memento)
		{
			return memento switch
			{
				Memento.Sprintmaster => data.CollectedMementoSprintmaster, 
				Memento.Guardian => data.FleaGamesMementoGiven, 
				Memento.Hero => throw new NotImplementedException(), 
				Memento.Hunter => data.nuuMementoAwarded, 
				Memento.Grey => data.CollectedMementoGrey, 
				Memento.Surface => throw new NotImplementedException(), 
				Memento.Craw => data.PickedUpCrowMemento, 
				Memento.EncrustedHeart => data.CollectedHeartCoral, 
				Memento.PollenHeart => data.CollectedHeartFlower, 
				Memento.HunterHeart => data.CollectedHeartHunter, 
				Memento.ConjoinedHeart => data.CollectedHeartClover, 
				_ => throw new InvalidCheckException<Memento>(memento), 
			};
		}

		public static bool HasDepositedMemento(this PlayerData data, Memento memento)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			Data? mementoData = data.GetMementoData(memento);
			if (!mementoData.HasValue)
			{
				return false;
			}
			return mementoData.Value.IsDeposited;
		}

		private static int GetNeedleUpgradeIndex(Needle needle)
		{
			return needle switch
			{
				Needle.Needle => 0, 
				Needle.SharpenedNeedle => 1, 
				Needle.ShiningNeedle => 2, 
				Needle.HivesteelNeedle => 3, 
				Needle.PaleSteelNeedle => 4, 
				_ => throw new InvalidCheckException<Needle>(needle), 
			};
		}

		public static bool HasObtainedNeedle(this PlayerData data, Needle needle)
		{
			int needleUpgradeIndex = GetNeedleUpgradeIndex(needle);
			return data.nailUpgrades >= needleUpgradeIndex;
		}

		private static string GetSilkSkillId(SilkSkill skill)
		{
			return skill switch
			{
				SilkSkill.Silkspear => "Silk Spear", 
				SilkSkill.ThreadStorm => "Thread Sphere", 
				SilkSkill.CrossStitch => "Parry", 
				SilkSkill.Sharpdart => "Silk Charge", 
				SilkSkill.RuneRage => "Silk Bomb", 
				SilkSkill.PaleNails => "Silk Boss Needle", 
				_ => throw new InvalidCheckException<SilkSkill>(skill), 
			};
		}

		private static Data? GetSilkSkillData(this PlayerData data, SilkSkill skill)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			string silkSkillId = GetSilkSkillId(skill);
			return ((SerializableNamedList<Data, NamedData>)(object)data.Tools).GetData(silkSkillId);
		}

		public static bool HasSilkSkill(this PlayerData data, SilkSkill skill)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			Data? silkSkillData = data.GetSilkSkillData(skill);
			if (!silkSkillData.HasValue)
			{
				return false;
			}
			return silkSkillData.Value.IsUnlocked;
		}

		private static string GetToolId(Tool tool)
		{
			return tool switch
			{
				Tool.StraightPin => "Straight Pin", 
				Tool.ThreefoldPin => "Tri Pin", 
				Tool.StingShard => "Sting Shard", 
				Tool.Tacks => "Tack", 
				Tool.Longpin => "Harpoon", 
				Tool.Curveclaw => "Curve Claws", 
				Tool.Curvesickle => "Curve Claws Upgraded", 
				Tool.ThrowingRing => "Shakra Ring", 
				Tool.Pimpillo => "Pimpilo", 
				Tool.Conchcutter => "Conch Drill", 
				Tool.WeaverSilkshot => "WebShot Weaver", 
				Tool.ForgeSilkshot => "WebShot Forge", 
				Tool.ArchitectSilkshot => "WebShot Architect", 
				Tool.DelversDrill => "Screw Attack", 
				Tool.CogworkWheel => "Cogwork Saw", 
				Tool.Cogfly => "Cogwork Flier", 
				Tool.RosaryCannon => "Rosary Cannon", 
				Tool.Voltvessels => "Lightning Rod", 
				Tool.Flintslate => "Flintstone", 
				Tool.SnareSetter => "Silk Snare", 
				Tool.FleaBrew => "Flea Brew", 
				Tool.PlasmiumPhial => "Lifeblood Syringe", 
				Tool.NeedlePhial => "Extractor", 
				Tool.DruidsEye => "Mosscreep Tool 1", 
				Tool.DruidsEyes => "Mosscreep Tool 2", 
				Tool.MagmaBell => "Lava Charm", 
				Tool.WardingBell => "Bell Bind", 
				Tool.PollipPouch => "Poison Pouch", 
				Tool.FracturedMask => "Fractured Mask", 
				Tool.Multibinder => "Multibind", 
				Tool.Weavelight => "White Ring", 
				Tool.SawtoothCirclet => "Brolly Spike", 
				Tool.InjectorBand => "Quickbind", 
				Tool.SpoolExtender => "Spool Extender", 
				Tool.ReserveBind => "Reserve Bind", 
				Tool.ClawMirror => "Dazzle Bind", 
				Tool.ClawMirrors => "Dazzle Bind Upgraded", 
				Tool.MemoryCrystal => "Revenge Crystal", 
				Tool.SnitchPick => "Thief Claw", 
				Tool.VoltFilament => "Zap Imbuement", 
				Tool.QuickSling => "Quick Sling", 
				Tool.WreathOfPurity => "Maggot Charm", 
				Tool.Longclaw => "Longneedle", 
				Tool.WispfireLantern => "Wisp Lantern", 
				Tool.EggOfFlealia => "Flea Charm", 
				Tool.PinBadge => "Pinstress Tool", 
				Tool.Compass => "Compass", 
				Tool.ShardPendant => "Bone Necklace", 
				Tool.MagnetiteBrooch => "Rosary Magnet", 
				Tool.WeightedBelt => "Weighted Anklet", 
				Tool.BarbedBracelet => "Barbed Wire", 
				Tool.DeadBugsPurse => "Dead Mans Purse", 
				Tool.ShellSatchel => "Shell Satchel", 
				Tool.MagnetiteDice => "Magnetite Dice", 
				Tool.Scuttlebrace => "Scuttlebrace", 
				Tool.AscendantsGrip => "Wallcling", 
				Tool.SpiderStrings => "Musician Charm", 
				Tool.SilkspeedAnklets => "Sprintmaster", 
				Tool.ThiefsMark => "Thief Charm", 
				_ => throw new InvalidCheckException<Tool>(tool), 
			};
		}

		private static Data? GetToolData(this PlayerData data, Tool tool)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			string toolId = GetToolId(tool);
			return ((SerializableNamedList<Data, NamedData>)(object)data.Tools).GetData(toolId);
		}

		public static bool HasTool(this PlayerData data, Tool tool)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			Data? toolData = data.GetToolData(tool);
			if (!toolData.HasValue)
			{
				return false;
			}
			return toolData.Value.IsUnlocked;
		}

		public static bool HasVesticrest(this PlayerData data, Vesticrest vesticrest)
		{
			return vesticrest switch
			{
				Vesticrest.Basic => data.UnlockedExtraYellowSlot, 
				Vesticrest.Upgraded => data.UnlockedExtraBlueSlot, 
				_ => throw new InvalidCheckException<Vesticrest>(vesticrest), 
			};
		}
	}
}
namespace Silksong.BingoSync.Exceptions
{
	public class InvalidCheckException<T> : InvalidOperationException
	{
		public InvalidCheckException(T data)
			: base($"No {typeof(T)} check is implemented for the value '{data}'.")
		{
		}
	}
}
namespace Silksong.BingoSync.Data
{
	[JsonConverter(typeof(StringEnumConverter))]
	public enum AncestralArt
	{
		[EnumMember(Value = "swift_step")]
		SwiftStep,
		[EnumMember(Value = "cling_grip")]
		ClingGrip,
		[EnumMember(Value = "needolin")]
		Needolin,
		[EnumMember(Value = "clawline")]
		Clawline,
		[EnumMember(Value = "silk_soar")]
		SilkSoar,
		[EnumMember(Value = "sylphsong")]
		Sylphsong
	}
	[JsonConverter(typeof(StringEnumConverter))]
	public enum Boss
	{
		[EnumMember(Value = "bell_beast")]
		BellBeast,
		[EnumMember(Value = "fourth_chorus")]
		FourthChorus,
		[EnumMember(Value = "great_conchflies")]
		GreatConchflies,
		[EnumMember(Value = "lace_1")]
		Lace1,
		[EnumMember(Value = "last_judge")]
		LastJudge,
		[EnumMember(Value = "moorwing")]
		Moorwing,
		[EnumMember(Value = "moss_mother")]
		MossMother,
		[EnumMember(Value = "moss_mothers")]
		MossMothers,
		[EnumMember(Value = "phantom")]
		Phantom,
		[EnumMember(Value = "savage_beastfly_1")]
		SavageBeastfly1,
		[EnumMember(Value = "sister_splinter")]
		SisterSplinter,
		[EnumMember(Value = "skull_tyrant_1")]
		SkullTyrant1,
		[EnumMember(Value = "skull_tyrant_2")]
		SkullTyrant2,
		[EnumMember(Value = "widow")]
		Widow,
		[EnumMember(Value = "broodmother")]
		Broodmother,
		[EnumMember(Value = "cogwork_dancers")]
		CogworkDancers,
		[EnumMember(Value = "disgraced_chef_lugoli")]
		DisgracedChefLugoli,
		[EnumMember(Value = "father_of_the_flame")]
		FatherOfTheFlame,
		[EnumMember(Value = "first_sinner")]
		FirstSinner,
		[EnumMember(Value = "forebrothers")]
		Forebrothers,
		[EnumMember(Value = "garmond")]
		Garmond,
		[EnumMember(Value = "grand_mother_silk")]
		GrandMotherSilk,
		[EnumMember(Value = "groal_the_great")]
		Groal,
		[EnumMember(Value = "lace_2")]
		Lace2,
		[EnumMember(Value = "raging_conchfly")]
		RagingConchfly,
		[EnumMember(Value = "savage_beastfly_2")]
		SavageBeastfly2,
		[EnumMember(Value = "second_sentinel")]
		SecondSentinel,
		[EnumMember(Value = "shakra")]
		Shakra,
		[EnumMember(Value = "the_unravelled")]
		TheUnravelled,
		[EnumMember(Value = "trobbio")]
		Trobbio,
		[EnumMember(Value = "voltvyrm")]
		Voltvyrm,
		[EnumMember(Value = "bell_eater")]
		BellEater,
		[EnumMember(Value = "clover_dancers")]
		CloverDancers,
		[EnumMember(Value = "crawfather")]
		Crawfather,
		[EnumMember(Value = "crust_king_khann")]
		CrustKingKhann,
		[EnumMember(Value = "gurr_the_outcast")]
		GurrTheOutcast,
		[EnumMember(Value = "lost_garmond")]
		LostGarmond,
		[EnumMember(Value = "lost_lace")]
		LostLace,
		[EnumMember(Value = "nyleth")]
		Nyleth,
		[EnumMember(Value = "palestag")]
		Palestag,
		[EnumMember(Value = "pinstress")]
		Pinstress,
		[EnumMember(Value = "plasmified_zango")]
		PlasmifiedZango,
		[EnumMember(Value = "shrine_guardian_seth")]
		ShrineGuardianSeth,
		[EnumMember(Value = "skarrsinger_karmelita")]
		SkarrsingerKarmelita,
		[EnumMember(Value = "tormented_trobbio")]
		TormentedTrobbio,
		[EnumMember(Value = "watcher_at_the_edge")]
		Watcher
	}
	[JsonConverter(typeof(StringEnumConverter))]
	public enum Crest
	{
		[EnumMember(Value = "hunter")]
		Hunter,
		[EnumMember(Value = "hunter_evolved")]
		HunterEvolved,
		[EnumMember(Value = "hunter_fully_evolved")]
		HunterFullyEvolved,
		[EnumMember(Value = "reaper")]
		Reaper,
		[EnumMember(Value = "wanderer")]
		Wanderer,
		[EnumMember(Value = "beast")]
		Beast,
		[EnumMember(Value = "cursed")]
		Cursed,
		[EnumMember(Value = "witch")]
		Witch,
		[EnumMember(Value = "architect")]
		Architect,
		[EnumMember(Value = "shaman")]
		Shaman,
		[EnumMember(Value = "cloakless")]
		Cloakless
	}
	[JsonConverter(typeof(StringEnumConverter))]
	public enum Ending
	{
		[EnumMember(Value = "weaver_queen")]
		WeaverQueen,
		[EnumMember(Value = "snared_silk")]
		SnaredSilk,
		[EnumMember(Value = "twisted_child")]
		TwistedChild,
		[EnumMember(Value = "sister_of_the_void")]
		SisterOfTheVoid,
		[EnumMember(Value = "passing_of_the_age")]
		PassingOfTheAge
	}
	[JsonConverter(typeof(StringEnumConverter))]
	public enum Memento
	{
		[EnumMember(Value = "sprintmaster")]
		Sprintmaster,
		[EnumMember(Value = "guardian")]
		Guardian,
		[EnumMember(Value = "hero")]
		Hero,
		[EnumMember(Value = "hunter")]
		Hunter,
		[EnumMember(Value = "grey")]
		Grey,
		[EnumMember(Value = "surface")]
		Surface,
		[EnumMember(Value = "craw")]
		Craw,
		[EnumMember(Value = "encrusted_heart")]
		EncrustedHeart,
		[EnumMember(Value = "pollen_heart")]
		PollenHeart,
		[EnumMember(Value = "hunter_heart")]
		HunterHeart,
		[EnumMember(Value = "conjoined_heart")]
		ConjoinedHeart
	}
	[JsonConverter(typeof(StringEnumConverter))]
	public enum Needle
	{
		[EnumMember(Value = "needle")]
		Needle,
		[EnumMember(Value = "sharpened_needle")]
		SharpenedNeedle,
		[EnumMember(Value = "shining_needle")]
		ShiningNeedle,
		[EnumMember(Value = "hivesteel_needle")]
		HivesteelNeedle,
		[EnumMember(Value = "pale_steel_needle")]
		PaleSteelNeedle
	}
	[JsonConverter(typeof(StringEnumConverter))]
	public enum SilkSkill
	{
		[EnumMember(Value = "silkspear")]
		Silkspear,
		[EnumMember(Value = "thread_storm")]
		ThreadStorm,
		[EnumMember(Value = "cross_stitch")]
		CrossStitch,
		[EnumMember(Value = "sharpdart")]
		Sharpdart,
		[EnumMember(Value = "rune_rage")]
		RuneRage,
		[EnumMember(Value = "pale_nails")]
		PaleNails
	}
	[JsonConverter(typeof(StringEnumConverter))]
	public enum Tool
	{
		[EnumMember(Value = "straight_pin")]
		StraightPin,
		[EnumMember(Value = "threefold_pin")]
		ThreefoldPin,
		[EnumMember(Value = "sting_shard")]
		StingShard,
		[EnumMember(Value = "tacks")]
		Tacks,
		[EnumMember(Value = "longpin")]
		Longpin,
		[EnumMember(Value = "curveclaw")]
		Curveclaw,
		[EnumMember(Value = "curvesickle")]
		Curvesickle,
		[EnumMember(Value = "throwing_ring")]
		ThrowingRing,
		[EnumMember(Value = "pimpillo")]
		Pimpillo,
		[EnumMember(Value = "conchcutter")]
		Conchcutter,
		[EnumMember(Value = "weaver_silkshot")]
		WeaverSilkshot,
		[EnumMember(Value = "architect_silkshot")]
		ArchitectSilkshot,
		[EnumMember(Value = "forge_silkshot")]
		ForgeSilkshot,
		[EnumMember(Value = "delvers_drill")]
		DelversDrill,
		[EnumMember(Value = "cogwork_wheel")]
		CogworkWheel,
		[EnumMember(Value = "cogfly")]
		Cogfly,
		[EnumMember(Value = "rosary_cannon")]
		RosaryCannon,
		[EnumMember(Value = "voltvessels")]
		Voltvessels,
		[EnumMember(Value = "flintslate")]
		Flintslate,
		[EnumMember(Value = "snare_setter")]
		SnareSetter,
		[EnumMember(Value = "flea_brew")]
		FleaBrew,
		[EnumMember(Value = "plasmium_phial")]
		PlasmiumPhial,
		[EnumMember(Value = "needle_phial")]
		NeedlePhial,
		[EnumMember(Value = "druids_eye")]
		DruidsEye,
		[EnumMember(Value = "druids_eyes")]
		DruidsEyes,
		[EnumMember(Value = "magma_bell")]
		MagmaBell,
		[EnumMember(Value = "warding_bell")]
		WardingBell,
		[EnumMember(Value = "pollip_pouch")]
		PollipPouch,
		[EnumMember(Value = "fractured_mask")]
		FracturedMask,
		[EnumMember(Value = "multibinder")]
		Multibinder,
		[EnumMember(Value = "weavelight")]
		Weavelight,
		[EnumMember(Value = "sawtooth_circlet")]
		SawtoothCirclet,
		[EnumMember(Value = "injector_band")]
		InjectorBand,
		[EnumMember(Value = "spool_extender")]
		SpoolExtender,
		[EnumMember(Value = "reserve_bind")]
		ReserveBind,
		[EnumMember(Value = "claw_mirror")]
		ClawMirror,
		[EnumMember(Value = "claw_mirrors")]
		ClawMirrors,
		[EnumMember(Value = "memory_crystal")]
		MemoryCrystal,
		[EnumMember(Value = "snitch_pick")]
		SnitchPick,
		[EnumMember(Value = "volt_filament")]
		VoltFilament,
		[EnumMember(Value = "quick_sling")]
		QuickSling,
		[EnumMember(Value = "wreath_of_purity")]
		WreathOfPurity,
		[EnumMember(Value = "longclaw")]
		Longclaw,
		[EnumMember(Value = "wispfire_lantern")]
		WispfireLantern,
		[EnumMember(Value = "egg_of_flealia")]
		EggOfFlealia,
		[EnumMember(Value = "pin_badge")]
		PinBadge,
		[EnumMember(Value = "compass")]
		Compass,
		[EnumMember(Value = "shard_pendant")]
		ShardPendant,
		[EnumMember(Value = "magnetite_brooch")]
		MagnetiteBrooch,
		[EnumMember(Value = "weighted_belt")]
		WeightedBelt,
		[EnumMember(Value = "barbed_bracelet")]
		BarbedBracelet,
		[EnumMember(Value = "dead_bugs_purse")]
		DeadBugsPurse,
		[EnumMember(Value = "shell_satchel")]
		ShellSatchel,
		[EnumMember(Value = "magnetite_dice")]
		MagnetiteDice,
		[EnumMember(Value = "scuttlebrace")]
		Scuttlebrace,
		[EnumMember(Value = "ascendants_grip")]
		AscendantsGrip,
		[EnumMember(Value = "spider_strings")]
		SpiderStrings,
		[EnumMember(Value = "silkspeed_anklets")]
		SilkspeedAnklets,
		[EnumMember(Value = "thiefs_mark")]
		ThiefsMark
	}
	[JsonConverter(typeof(StringEnumConverter))]
	public enum Vesticrest
	{
		[EnumMember(Value = "basic")]
		Basic,
		[EnumMember(Value = "upgraded")]
		Upgraded
	}
}
namespace Silksong.BingoSync.Configurations
{
	internal class BoardConfig
	{
		private const string SECTION = "Board";

		public readonly ConfigEntry<KeyCode> ToggleUI;

		public BoardConfig(ConfigFile cfg)
		{
			ToggleUI = cfg.Bind<KeyCode>("Board", "ToggleBoard", (KeyCode)98, "Defines the keybind to toggle the board");
		}
	}
	internal class Configuration
	{
		public readonly GeneralConfig General;

		public readonly BoardConfig Board;

		public readonly JoinConfig Join;

		public readonly ExperimentalConfig Experimental;

		public static Configuration? Instance { get; private set; }

		public static Configuration SafeInstance
		{
			get
			{
				if (Instance == null)
				{
					throw new InvalidOperationException("Tried to access 'Configuration' before it was loaded.");
				}
				return Instance;
			}
		}

		private Configuration(ConfigFile cfg)
		{
			General = new GeneralConfig(cfg);
			Board = new BoardConfig(cfg);
			Join = new JoinConfig(cfg);
			Experimental = new ExperimentalConfig(cfg);
		}

		public static void Load(ConfigFile cfg)
		{
			Instance = new Configuration(cfg);
		}
	}
	internal class ExperimentalConfig
	{
		private const string SECTION = "Experimental";

		public readonly ConfigEntry<bool> EvaluateOnHeroUpdate;

		public ExperimentalConfig(ConfigFile cfg)
		{
			EvaluateOnHeroUpdate = cfg.Bind<bool>("Experimental", "evaluateOnHeroUpdate", false, "Defines if the goals should be checked on each frame the player is loaded");
		}
	}
	internal class GeneralConfig
	{
		private const string SECTION = "General";

		public readonly ConfigEntry<bool> UseAdvancedTeams;

		public GeneralConfig(ConfigFile cfg)
		{
			UseAdvancedTeams = cfg.Bind<bool>("General", "AddMoreTeams", false, "Defines if 4 extra teams are added upon loading");
		}
	}
	internal class JoinConfig
	{
		private const string SECTION = "Join";

		public readonly ConfigEntry<string> Nickname;

		public readonly ConfigEntry<KeyCode> ToggleUI;

		public JoinConfig(ConfigFile cfg)
		{
			Nickname = cfg.Bind<string>("Join", "DefaultNickname", "", "Defines the default nickname in the join panel");
			ToggleUI = cfg.Bind<KeyCode>("Join", "ToggleJoinUI", (KeyCode)104, "Defines the keybind to toggle the join panel");
		}
	}
}
namespace Silksong.BingoSync.Conditions
{
	internal sealed class HasCompletedEndingCondition : ICondition
	{
		private readonly Ending _ending;

		[Condition("has_completed_ending")]
		public HasCompletedEndingCondition(ConditionData data)
		{
			_ending = data.GetRequiredParameter<Ending>("ending");
		}

		public bool IsMet()
		{
			return PlayerData.instance.IsEndingCompleted(_ending);
		}
	}
	internal sealed class HasDepositedMementoCondition : ICondition
	{
		private readonly Memento _memento;

		[Condition("has_deposited_memento")]
		public HasDepositedMementoCondition(ConditionData data)
		{
			_memento = data.GetRequiredParameter<Memento>("memento");
		}

		public bool IsMet()
		{
			return PlayerData.instance.HasDepositedMemento(_memento);
		}
	}
	internal sealed class HasKilledBossCondition : ICondition
	{
		private readonly Boss _boss;

		[Condition("has_killed_boss")]
		public HasKilledBossCondition(ConditionData data)
		{
			_boss = data.GetRequiredParameter<Boss>("boss");
		}

		public bool IsMet()
		{
			return PlayerData.instance.IsBossKilled(_boss);
		}
	}
	internal sealed class HasObtainedAncestralArt : ICondition
	{
		private readonly AncestralArt _art;

		[Condition("has_obtained_ancestral_art")]
		public HasObtainedAncestralArt(ConditionData data)
		{
			_art = data.GetRequiredParameter<AncestralArt>("art");
		}

		public bool IsMet()
		{
			return PlayerData.instance.HasAncestralArt(_art);
		}
	}
	internal sealed class HasObtainedCrestCondition : ICondition
	{
		private readonly Crest _crest;

		[Condition("has_obtained_crest")]
		public HasObtainedCrestCondition(ConditionData data)
		{
			_crest = data.GetRequiredParameter<Crest>("crest");
		}

		public bool IsMet()
		{
			return PlayerData.instance.HasCrest(_crest);
		}
	}
	internal sealed class HasObtainedMementoCondition : ICondition
	{
		private readonly Memento _memento;

		[Condition("has_obtained_memento")]
		public HasObtainedMementoCondition(ConditionData data)
		{
			_memento = data.GetRequiredParameter<Memento>("memento");
		}

		public bool IsMet()
		{
			return PlayerData.instance.HasMemento(_memento);
		}
	}
	internal sealed class HasObtainedNeedleCondition : ICondition
	{
		private readonly Needle _needle;

		[Condition("has_obtained_needle")]
		public HasObtainedNeedleCondition(ConditionData data)
		{
			_needle = data.GetRequiredParameter<Needle>("needle");
		}

		public bool IsMet()
		{
			return PlayerData.instance.HasObtainedNeedle(_needle);
		}
	}
	internal sealed class HasObtainedSilkSkillCondition : ICondition
	{
		private readonly SilkSkill _skill;

		[Condition("has_obtained_silk_skill")]
		public HasObtainedSilkSkillCondition(ConditionData data)
		{
			_skill = data.GetRequiredParameter<SilkSkill>("skill");
		}

		public bool IsMet()
		{
			return PlayerData.instance.HasSilkSkill(_skill);
		}
	}
	internal sealed class HasObtainedToolCondition : ICondition
	{
		private readonly Tool _tool;

		[Condition("has_obtained_tool")]
		public HasObtainedToolCondition(ConditionData data)
		{
			_tool = data.GetRequiredParameter<Tool>("tool");
		}

		public bool IsMet()
		{
			return PlayerData.instance.HasTool(_tool);
		}
	}
	internal sealed class HasObtainedVesticrestCondition : ICondition
	{
		private readonly Vesticrest _vesticrest;

		[Condition("has_obtained_vesticrest")]
		public HasObtainedVesticrestCondition(ConditionData data)
		{
			_vesticrest = data.GetRequiredParameter<Vesticrest>("vesticrest");
		}

		public bool IsMet()
		{
			return PlayerData.instance.HasVesticrest(_vesticrest);
		}
	}
}

plugins/BingoAPI.dll

Decompiled 3 weeks 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.Http.Headers;
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;
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.3.0")]
[assembly: AssemblyInformationalVersion("0.1.3-alpha+05041a50d4823d4c32c4fcae9420886e16396084")]
[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 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);
		}
	}
	[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;
		}
	}
}
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
{
	[EditorBrowsable(EditorBrowsableState.Never)]
	[ExcludeFromCodeCoverage]
	[Embedded]
	internal static class IsExternalInit
	{
	}
	[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;
		}
	}
	[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.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.Method, Inherited = false)]
	[ExcludeFromCodeCoverage]
	[Embedded]
	internal sealed class ModuleInitializerAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
	[EditorBrowsable(EditorBrowsableState.Never)]
	[ExcludeFromCodeCoverage]
	[Embedded]
	internal sealed class RequiresLocationAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Class, Inherited = false)]
	[ExcludeFromCodeCoverage]
	[Embedded]
	internal sealed class CompilerLoweringPreserveAttribute : Attribute
	{
	}
	[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 = true, AllowMultiple = false)]
	[ExcludeFromCodeCoverage]
	[Embedded]
	internal sealed class ParamCollectionAttribute : Attribute
	{
	}
	[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 | 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
	{
	}
	[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, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	[Embedded]
	internal sealed class CallerArgumentExpressionAttribute : Attribute
	{
		public string ParameterName { get; }

		public CallerArgumentExpressionAttribute(string parameterName)
		{
			ParameterName = parameterName;
		}
	}
	[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;
		}
	}
}
namespace System.Diagnostics.CodeAnalysis
{
	[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
	[ExcludeFromCodeCoverage]
	[Embedded]
	internal sealed class DoesNotReturnIfAttribute : Attribute
	{
		public bool ParameterValue { get; }

		public DoesNotReturnIfAttribute(bool parameterValue)
		{
			ParameterValue = parameterValue;
		}
	}
	[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.Property | AttributeTargets.Field | AttributeTargets.Parameter, Inherited = false)]
	[ExcludeFromCodeCoverage]
	[Embedded]
	internal sealed class AllowNullAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
	[ExcludeFromCodeCoverage]
	[Embedded]
	internal sealed class MaybeNullWhenAttribute : Attribute
	{
		public bool ReturnValue { get; }

		public MaybeNullWhenAttribute(bool returnValue)
		{
			ReturnValue = returnValue;
		}
	}
	[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	[Embedded]
	internal sealed class UnscopedRefAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue, Inherited = false)]
	[ExcludeFromCodeCoverage]
	[Embedded]
	internal sealed class MaybeNullAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
	[ExcludeFromCodeCoverage]
	[Embedded]
	internal sealed class ConstantExpectedAttribute : Attribute
	{
		public object? Min { get; set; }

		public object? Max { get; set; }
	}
	[AttributeUsage(AttributeTargets.Method, Inherited = false)]
	[ExcludeFromCodeCoverage]
	[Embedded]
	internal sealed class DoesNotReturnAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, Inherited = false)]
	[ExcludeFromCodeCoverage]
	[Embedded]
	internal sealed class DisallowNullAttribute : Attribute
	{
	}
	[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.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 | AttributeTargets.ReturnValue, Inherited = false)]
	[ExcludeFromCodeCoverage]
	[Embedded]
	internal sealed class NotNullAttribute : Attribute
	{
	}
	[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, 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.Parameter, Inherited = false)]
	[ExcludeFromCodeCoverage]
	[Embedded]
	internal sealed class NotNullWhenAttribute : Attribute
	{
		public bool ReturnValue { get; }

		public NotNullWhenAttribute(bool returnValue)
		{
			ReturnValue = returnValue;
		}
	}
	[AttributeUsage(AttributeTargets.Constructor, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	[Embedded]
	internal sealed class SetsRequiredMembersAttribute : Attribute
	{
	}
}
namespace Microsoft.CodeAnalysis
{
	[Embedded]
	[AttributeUsage(AttributeTargets.All)]
	[ExcludeFromCodeCoverage]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace BingoAPI.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;
		}
	}
	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 HttpClient _client;

		private readonly BingoApiClient _api;

		private readonly BingoSocketClient _socket = new BingoSocketClient();

		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)
		{
			_dispatcher = dispatcher;
			_client = new HttpClient(new LoggingHandler(new HttpClientHandler()));
			_client.Timeout = TimeSpan.FromSeconds(30.0);
			_client.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue("BingoAPI", "1.0.0"));
			_client.BaseAddress = new Uri("https://bingosync.com");
			_api = new BingoApiClient(_client);
		}

		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
			{
				Square[] array = await _api.GetSquares(_roomCode, ct);
				Log.Info($"Got {array.Length} squares for room '{_roomCode}'.");
				return new Card(array, pool);
			}
			catch (Exception arg)
			{
				Log.Error($"Failed to get squares for room '{_roomCode}': {arg}");
				return null;
			}
		}

		public async Task<Square[]?> GetSquares(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
			{
				Square[] array = await _api.GetSquares(_roomCode, ct);
				Log.Info($"Got {array.Length} squares for room '{_roomCode}'.");
				return array;
			}
			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()
		{
			_client.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))]
	public 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 ConditionConverter : JsonConverter<ICondition>
	{
		private const string ACTION_KEY = "action";

		public override bool CanWrite => false;

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

		public override ICondition ReadJson(JsonReader reader, Type objectType, ICondition? existingValue, bool hasExistingValue, JsonSerializer serializer)
		{
			//IL_0026: 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));
			}
			ConditionData data = new ConditionData(val);
			return ConditionRegistry.Create(text, data);
		}
	}
	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 Dictionary<string, Team> TeamMappings = new Dictionary<string, Team>(StringComparer.OrdinalIgnoreCase)
		{
			["pink"] = Team.Pink,
			["red"] = Team.Red,
			["orange"] = Team.Orange,
			["brown"] = Team.Brown,
			["yellow"] = Team.Yellow,
			["green"] = Team.Green,
			["teal"] = Team.Teal,
			["blue"] = Team.Blue,
			["navy"] = Team.Navy,
			["purple"] = Team.Purple,
			["blank"] = Team.None
		};

		public override void WriteJson(JsonWriter writer, Team value, JsonSerializer serializer)
		{
			List<string> list = new List<string>();
			foreach (KeyValuePair<string, Team> teamMapping in TeamMappings)
			{
				if (teamMapping.Value != Team.None && value.HasFlag(teamMapping.Value))
				{
					list.Add(teamMapping.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.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<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;

		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(new Uri("wss://sockets.bingosync.com/broadcast"), 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();
			try
			{
				if (_socket.State == WebSocketState.Open)
				{
					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 (ObjectDisposedException)
				{
				}
				catch (Exception ex4)
				{
					Log.Error("Receive loop failed during disconnect: " + ex4.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;

		internal Card(Square[] squares, GoalPool pool)
		{
			_squares = new CardSquare[squares.Length];
			foreach (Square square in squares)
			{
				int index = square.Slot.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; }

		[JsonProperty("slot")]
		[JsonRequired]
		public required SlotIndex Slot { get; init; }

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

		[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
	{
		None = 0,
		Pink = 1,
		Red = 2,
		Orange = 4,
		Brown = 8,
		Yellow = 0x10,
		Green = 0x20,
		Teal = 0x40,
		Blue = 0x80,
		Navy = 0x100,
		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
{
	[AttributeUsage(AttributeTargets.Constructor | AttributeTargets.Method)]
	public class ConditionAttribute : Attribute
	{
		private record FactoryEntry
		{
			public required string Action { get; init; }

			public required Func<ConditionData, ICondition> Factory { get; init; }

			public required string SourceName { get; init; }

			[CompilerGenerated]
			[SetsRequiredMembers]
			protected FactoryEntry(FactoryEntry original)
			{
				Action = original.Action;
				Factory = original.Factory;
				SourceName = original.SourceName;
			}

			public FactoryEntry()
			{
			}
		}

		public readonly string Action;

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

		public static void AddAll()
		{
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			foreach (Assembly assembly in assemblies)
			{
				AddAll(assembly);
			}
		}

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

		public static void AddAll(Type type)
		{
			IEnumerable<FactoryEntry> enumerable = GetFactoryMethods(type).Concat(GetFactoryConstructors(type));
			foreach (FactoryEntry item in enumerable)
			{
				Log.Debug("Trying to add '" + item.Action + "' from '" + item.SourceName + "'.");
				ConditionRegistry.TryAdd(item.Action, item.Factory);
			}
		}

		private static IEnumerable<FactoryEntry> GetFactoryMethods(Type type)
		{
			MethodInfo[] methods = type.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			MethodInfo[] array = methods;
			foreach (MethodInfo method in array)
			{
				ConditionAttribute customAttribute = method.GetCustomAttribute<ConditionAttribute>();
				if (customAttribute == null)
				{
					continue;
				}
				if (!typeof(ICondition).IsAssignableFrom(method.ReturnType))
				{
					Log.Warning("Method '" + method.Name + "' must return 'ICondition'.");
					continue;
				}
				ParameterInfo[] parameters = method.GetParameters();
				if (parameters.Length != 1 || parameters[0].ParameterType != typeof(ConditionData))
				{
					Log.Warning("Method '" + method.Name + "' must only take 'ConditionData'.");
					continue;
				}
				yield return new FactoryEntry
				{
					Action = customAttribute.Action,
					Factory = (ConditionData data) => (ICondition)method.Invoke(null, new object[1] { data }),
					SourceName = method.Name
				};
			}
		}

		private static IEnumerable<FactoryEntry> GetFactoryConstructors(Type type)
		{
			ConstructorInfo[] constructors = type.GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			ConstructorInfo[] array = constructors;
			foreach (ConstructorInfo ctor in array)
			{
				ConditionAttribute customAttribute = ctor.GetCustomAttribute<ConditionAttribute>();
				if (customAttribute == null || !typeof(ICondition).IsAssignableFrom(type))
				{
					continue;
				}
				ParameterInfo[] parameters = ctor.GetParameters();
				if (parameters.Length != 1 || parameters[0].ParameterType != typeof(ConditionData))
				{
					Log.Warning("Constructor '" + type.Name + "' must only take 'ConditionData'.");
					continue;
				}
				yield return new FactoryEntry
				{
					Action = customAttribute.Action,
					Factory = (ConditionData data) => (ICondition)ctor.Invoke(new object[1] { data }),
					SourceName = (type.FullName ?? type.Name)
				};
			}
		}
	}
	public sealed class ConditionData
	{
		private readonly JObject _json;

		internal ConditionData(JObject json)
		{
			_json = json;
		}

		private bool TryGetParameter<T>(string key, out T? value)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Invalid comparison between Unknown and I4
			value = default(T);
			JToken obj = _json["params"];
			JObject val = (JObject)(object)((obj is JObject) ? obj : null);
			if (val == null)
			{
				return false;
			}
			JToken val2 = default(JToken);
			if (!val.TryGetValue(key, ref val2))
			{
				return false;
			}
			if ((int)val2.Type == 10)
			{
				return false;
			}
			value = val2.ToObject<T>();
			return value != null;
		}

		public T GetRequiredParameter<T>(string key) where T : notnull
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			if (!TryGetParameter<T>(key, out T value) || value == null)
			{
				throw new JsonException($"Failed to find '{key}' of type '{typeof(T)}'.");
			}
			return value;
		}

		public T GetOptionalParameter<T>(string key, T defaultValue) where T : notnull
		{
			if (!TryGetParameter<T>(key, out T value))
			{
				return defaultValue;
			}
			T val = value;
			if (val == null)
			{
				return defaultValue;
			}
			return val;
		}
	}
	public static class ConditionRegistry
	{
		private static readonly Dictionary<string, Func<ConditionData, ICondition>> Factories = new Dictionary<string, Func<ConditionData, ICondition>>(StringComparer.OrdinalIgnoreCase);

		public static void TryAdd(string action, Func<ConditionData, ICondition> factory)
		{
			if (!Factories.ContainsKey(action))
			{
				Factories.Add(action, factory);
			}
		}

		internal static ICondition Create(string action, ConditionData data)
		{
			if (!Factories.TryGetValue(action, out Func<ConditionData, ICondition> value))
			{
				throw new InvalidOperationException("No condition registered under the action '" + action + "'.");
			}
			return value(data);
		}
	}
	[JsonConverter(typeof(ConditionConverter))]
	public interface ICondition
	{
		bool IsMet();
	}
}
namespace BingoAPI.Conditions.BuiltIn
{
	internal sealed class AndCondition : ICondition
	{
		private readonly ICondition[] _conditions;

		[Condition("AND")]
		public AndCondition(ConditionData data)
		{
			_conditions = data.GetRequiredParameter<ICondition[]>("conditions");
		}

		public bool IsMet()
		{
			return _conditions.All((ICondition condition) => condition.IsMet());
		}
	}
	internal sealed class NotCondition : ICondition
	{
		private readonly ICondition _condition;

		[Condition("NOT")]
		public NotCondition(ConditionData data)
		{
			_condition = data.GetRequiredParameter<ICondition>("condition");
		}

		public bool IsMet()
		{
			return !_condition.IsMet();
		}
	}
	internal sealed class OrCondition : ICondition
	{
		private readonly ICondition[] _conditions;

		[Condition("OR")]
		public OrCondition(ConditionData data)
		{
			_conditions = data.GetRequiredParameter<ICondition[]>("conditions");
		}

		public bool IsMet()
		{
			return _conditions.Any((ICondition condition) => condition.IsMet());
		}
	}
	internal sealed class SomeCondition : ICondition
	{
		private readonly ICondition[] _conditions;

		private readonly uint _amount;

		[Condition("SOME")]
		public SomeCondition(ConditionData data)
		{
			_conditions = data.GetRequiredParameter<ICondition[]>("conditions");
			_amount = data.GetOptionalParameter("amount", 1u);
		}

		public bool IsMet()
		{
			if (_conditions.Length < _amount)
			{
				return false;
			}
			int num = 0;
			ICondition[] conditions = _conditions;
			foreach (ICondition condition in conditions)
			{
				if (condition.IsMet())
				{
					num++;
					if (num >= _amount)
					{
						return true;
					}
				}
			}
			return false;
		}
	}
}