Decompiled source of Better Chess v0.5.0

plugins/com.github.Kirshoo.BetterChess.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using UnityEngine;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("com.github.Kirshoo.BetterChess")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.5.0.0")]
[assembly: AssemblyInformationalVersion("0.5.0+66ccaadcd642341ab182462874927ae6278227a1")]
[assembly: AssemblyProduct("com.github.Kirshoo.BetterChess")]
[assembly: AssemblyTitle("BetterChess")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.5.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
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 BetterChess
{
	internal class ChessLogic
	{
		private static ChessManager manager = ChessManager.Instance;

		private const string DefaultFEN = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1";

		private static void PlacePiece(PieceType type, bool isWhite, BoardPosition position)
		{
			string text = (isWhite ? "White" : "Black");
			manager.CreatePieceOnBoard(type, isWhite, position);
		}

		private static void PlacePawn(bool isWhite, BoardPosition position)
		{
			PlacePiece(PieceType.Pawn, isWhite, position);
		}

		private static void PlaceRook(bool isWhite, BoardPosition position)
		{
			PlacePiece(PieceType.Rook, isWhite, position);
		}

		private static void PlaceKnight(bool isWhite, BoardPosition position)
		{
			PlacePiece(PieceType.Knight, isWhite, position);
		}

		private static void PlaceBishop(bool isWhite, BoardPosition position)
		{
			PlacePiece(PieceType.Bishop, isWhite, position);
		}

		private static void PlaceQueen(bool isWhite, BoardPosition position)
		{
			PlacePiece(PieceType.Queen, isWhite, position);
		}

		private static void PlaceKing(bool isWhite, BoardPosition position)
		{
			PlacePiece(PieceType.King, isWhite, position);
		}

		private static void PlaceFENPiece(char c, BoardPosition position)
		{
			switch (c)
			{
			case 'P':
			case 'p':
				PlacePawn(c == 'P', position);
				break;
			case 'R':
			case 'r':
				PlaceRook(c == 'R', position);
				break;
			case 'N':
			case 'n':
				PlaceKnight(c == 'N', position);
				break;
			case 'B':
			case 'b':
				PlaceBishop(c == 'B', position);
				break;
			case 'K':
			case 'k':
				PlaceKing(c == 'K', position);
				break;
			case 'Q':
			case 'q':
				PlaceQueen(c == 'Q', position);
				break;
			}
		}

		public static void SetBoardStateToFEN(string fen)
		{
			string text = fen.Split(' ', 2)[0];
			string[] array = text.Split("/", 8);
			if (array.Length != 8)
			{
				Plugin.Log.LogError((object)$"[ChessLogic] Unable to load state from FEN: amount of ranks doesnt match (have {array.Length} want {8})");
				return;
			}
			int num = 0;
			foreach (string item in array.Reverse())
			{
				int num2 = 0;
				string text2 = item;
				foreach (char c in text2)
				{
					if (c >= '1' && c <= '8')
					{
						num2 += c - 49 + 1;
						continue;
					}
					PlaceFENPiece(c, new BoardPosition(num, num2));
					num2++;
				}
				num++;
			}
		}

		public static void ResetBoardPosition(string FEN)
		{
			if (string.IsNullOrEmpty(FEN))
			{
				Plugin.Log.LogWarning((object)"Attempting to use an empty FEN. Fallback to default...");
				FEN = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1";
			}
			manager.RemoveAllPieces();
			SetBoardStateToFEN(FEN);
		}
	}
	public class ChessManager
	{
		private readonly List<ChessPiece> pieces = new List<ChessPiece>();

		private static ChessManager? _instance;

		private bool boardLoaded;

		private Vector3 boardPosition = Vector3.zero;

		private Quaternion boardRotation = Quaternion.identity;

		private Vector3 boardScale = Vector3.zero;

		private Vector3 boardOriginOffset = new Vector3(2.8f, 0f, 2.8f);

		public static ChessManager Instance
		{
			get
			{
				if (_instance == null)
				{
					_instance = new ChessManager();
				}
				return _instance;
			}
		}

		public void Init()
		{
			MovableChessboardWrapper.Init();
			if (!MovableChessboardWrapper.enabled || !MovableChessboardWrapper.IsAvailable)
			{
				Plugin.Log.LogInfo((object)"[ChessManager] MovableChessboard mod not loaded, continue running in standalone mode");
				return;
			}
			Plugin.Log.LogInfo((object)"[ChessManager] Found MoveableChessboard! Subscribing to the events.");
			MovableChessboardWrapper.SubscirbeToBoardLoaded(OnBoardLoaded);
			MovableChessboardWrapper.SubscirbeToPositionChanged(OnBoardMoved);
			MovableChessboardWrapper.SubscirbeToRotationChanged(OnBoardRotated);
			MovableChessboardWrapper.SubscirbeToScaleChanged(OnBoardScaled);
		}

		private void OnBoardLoaded()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: 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_0042: Unknown result type (might be due to invalid IL or missing references)
			boardPosition = MovableChessboardWrapper.GetBoardPosition();
			boardRotation = MovableChessboardWrapper.GetBoardRotation();
			boardScale = MovableChessboardWrapper.GetBoardScale();
			Plugin.Log.LogDebug((object)$"[ChessManager] Loaded position: {boardPosition}; rotation: {boardRotation}; scale: {boardScale}");
			LoadChessSetPieces();
		}

		private void OnBoardMoved(Vector3 newPosition)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: 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_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			Plugin.Log.LogDebug((object)$"[ChessManager] Updating position of {pieces.Count} pieces.");
			Vector3 deltaMovement = newPosition - boardPosition;
			foreach (ChessPiece piece in pieces)
			{
				Util.ApplyBoardMovement(piece.ObjectReference.transform, deltaMovement);
				piece.ViewReference.RPC("SetKinematicRPC", (RpcTarget)3, new object[3]
				{
					true,
					piece.ObjectReference.transform.position,
					piece.ObjectReference.transform.rotation
				});
			}
			boardPosition = newPosition;
		}

		private void OnBoardRotated(Quaternion newRotation)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: 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_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			Plugin.Log.LogDebug((object)$"[ChessManager] Updating rotation of {pieces.Count} pieces.");
			Quaternion rotation = newRotation * Quaternion.Inverse(boardRotation);
			foreach (ChessPiece piece in pieces)
			{
				Util.RotateAroundPivot(piece.ObjectReference.transform, boardPosition, rotation);
				piece.ViewReference.RPC("SetKinematicRPC", (RpcTarget)3, new object[3]
				{
					true,
					piece.ObjectReference.transform.position,
					piece.ObjectReference.transform.rotation
				});
			}
			boardRotation = newRotation;
		}

		private void OnBoardScaled(Vector3 newScale)
		{
			//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)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: 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_00c2: Unknown result type (might be due to invalid IL or missing references)
			Plugin.Log.LogDebug((object)$"[ChessManager] Updating scale of {pieces.Count} pieces.");
			foreach (ChessPiece piece in pieces)
			{
				Util.ApplyBoardScale(piece.ObjectReference.transform, boardPosition, boardScale, newScale);
				piece.ViewReference.RPC("SetKinematicRPC", (RpcTarget)3, new object[3]
				{
					true,
					piece.ObjectReference.transform.position,
					piece.ObjectReference.transform.rotation
				});
			}
			boardScale = newScale;
		}

		private void LoadBoardPosition()
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: 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_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: 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_0093: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = GameObject.Find("Chess");
			if ((Object)(object)val == (Object)null)
			{
				Plugin.Log.LogError((object)"[ChessManager] Unable to initialize board position: cannot find ChessSet object.");
				return;
			}
			Transform val2 = val.transform.Find("Plane");
			if ((Object)(object)val2 == (Object)null)
			{
				Plugin.Log.LogError((object)"[ChessManager] Unable to initialize board position: cannot find chessboard object.");
				return;
			}
			boardPosition = val2.position;
			boardRotation = val2.rotation;
			boardScale = val2.localScale;
			Plugin.Log.LogDebug((object)$"[ChessManager] Found chessboard at {boardPosition} with rotation of {boardRotation} and scale of {boardScale}");
		}

		private void LoadChessSetPieces()
		{
			GameObject val = GameObject.Find("Chess");
			if ((Object)(object)val == (Object)null)
			{
				Plugin.Log.LogError((object)"[ChessManager] Unable to initialize board position: cannot find ChessSet object.");
				return;
			}
			ChessStabilizer[] componentsInChildren = val.GetComponentsInChildren<ChessStabilizer>();
			ChessStabilizer[] array = componentsInChildren;
			foreach (ChessStabilizer val2 in array)
			{
				RegisterPiece(((Component)val2).gameObject);
			}
			Plugin.Log.LogDebug((object)$"[ChessManager] Added a total of {componentsInChildren.Length} chess pieces!");
			Plugin.Log.LogDebug((object)$"[ChessManager] Tracking {pieces.Count} pieces!");
		}

		public Vector3 GetChessBoardPosition()
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			if (!MovableChessboardWrapper.enabled && !boardLoaded)
			{
				boardLoaded = true;
				LoadBoardPosition();
				LoadChessSetPieces();
			}
			return boardPosition;
		}

		public Vector3 GetChessBoardOrigin()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			return GetChessBoardPosition() - boardOriginOffset;
		}

		public Quaternion GetChessBoardRotation()
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			if (!MovableChessboardWrapper.enabled && !boardLoaded)
			{
				LoadBoardPosition();
				LoadChessSetPieces();
				boardLoaded = true;
			}
			return boardRotation;
		}

		public Vector3 GetChessBoardScale()
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			if (!MovableChessboardWrapper.enabled && !boardLoaded)
			{
				LoadBoardPosition();
				LoadChessSetPieces();
				boardLoaded = true;
			}
			return boardScale;
		}

		public static string GetPiecePrefab(PieceType type, bool isWhite)
		{
			StringBuilder stringBuilder = new StringBuilder();
			switch (type)
			{
			case PieceType.Pawn:
				stringBuilder.Append("C_Pawn");
				break;
			case PieceType.Knight:
				stringBuilder.Append("C_Knight");
				break;
			case PieceType.Bishop:
				stringBuilder.Append("C_Bishop");
				break;
			case PieceType.Rook:
				stringBuilder.Append("C_Rook");
				break;
			case PieceType.Queen:
				stringBuilder.Append("C_Queen");
				break;
			case PieceType.King:
				stringBuilder.Append("C_King");
				break;
			default:
				Plugin.Log.LogError((object)"Unable to deduce prefab name: PieceType is None");
				return "";
			}
			stringBuilder.Append(" " + (isWhite ? "W" : "B"));
			return stringBuilder.ToString();
		}

		public static bool TryGetPiecePrefab(PieceType type, bool isWhite, out string prefabName)
		{
			prefabName = GetPiecePrefab(type, isWhite);
			if (string.IsNullOrEmpty(prefabName))
			{
				return false;
			}
			return true;
		}

		public void CreatePiece(PieceType type, bool isWhite, Vector3 position, Quaternion rotation)
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: 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_00f9: Unknown result type (might be due to invalid IL or missing references)
			if (!PhotonNetwork.IsMasterClient)
			{
				Plugin.Log.LogError((object)$"[ChessManager] Unable to create '{type}' piece: host privileges required.");
				return;
			}
			if (!TryGetPiecePrefab(type, isWhite, out string prefabName))
			{
				Plugin.Log.LogError((object)$"[ChessManager] Unable to create '{type}' piece: unable to deduce prefab name.");
				return;
			}
			position += new Vector3(0f, 2f, 0f);
			PhotonView component = PhotonNetwork.InstantiateItemRoom(prefabName, position, rotation).GetComponent<PhotonView>();
			if ((Object)(object)component == (Object)null)
			{
				Plugin.Log.LogWarning((object)("[ChessManager] Created '" + prefabName + "', but unable to get photon view component."));
				return;
			}
			pieces.Add(new ChessPiece(((Component)component).gameObject));
			component.RPC("SetKinematicRPC", (RpcTarget)3, new object[3]
			{
				false,
				((Component)component).transform.position,
				((Component)component).transform.rotation
			});
			Plugin.Log.LogDebug((object)$"[ChessManager] Successfully created '{prefabName}' at {position}");
		}

		public void CreatePieceOnBoard(PieceType type, bool isWhite, BoardPosition position)
		{
			//IL_0001: 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_002a: 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_0049: 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_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			Vector3 position2 = GetChessBoardOrigin() + new Vector3((float)position.File * 0.8f, 0f, (float)position.Rank * 0.8f);
			Quaternion rotation = Quaternion.Euler(0f, isWhite ? 0f : 180f, 0f);
			CreatePiece(type, isWhite, position2, rotation);
		}

		public void RemoveAllPieces()
		{
			if (!PhotonNetwork.IsMasterClient)
			{
				Plugin.Log.LogError((object)"[ChessManager] Unable to remove pieces: host privileges required.");
				return;
			}
			int count = pieces.Count;
			foreach (ChessPiece piece in pieces)
			{
				PhotonNetwork.Destroy(piece.ObjectReference);
			}
			pieces.Clear();
			Plugin.Log.LogDebug((object)$"[ChessManager] Destroyed a total of {count} pieces!");
		}

		internal void RegisterPiece(GameObject piece)
		{
			pieces.Add(new ChessPiece(piece));
		}
	}
	public class BoardPosition
	{
		public const int BoardSize = 8;

		public const float GridSize = 0.8f;

		public int Rank;

		public int File;

		public BoardPosition(Vector3 position, Vector3 origin)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = position - origin;
			File = Mathf.RoundToInt(val.x / 0.8f);
			Rank = Mathf.RoundToInt(val.z / 0.8f);
		}

		public BoardPosition(int rank, int file)
		{
			Rank = rank;
			File = file;
		}

		private bool WithinBounds(int x, int y)
		{
			if (x >= 0 && x < 8 && y >= 0)
			{
				return y < 8;
			}
			return false;
		}

		public override string ToString()
		{
			if (!WithinBounds(File, Rank))
			{
				return "??";
			}
			return $"{(char)(97 + File)}{(char)(49 + Rank)}";
		}
	}
	public class ChessPiece
	{
		public GameObject ObjectReference;

		public PhotonView ViewReference;

		public Vector3 Position;

		public PieceType Type;

		public bool IsWhite;

		public BoardPosition PositionOnBoard;

		private ChessManager manager;

		public ChessPiece(GameObject gameObject, Vector3 position, PieceType type, bool isWhite)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: 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)
			ObjectReference = gameObject;
			ViewReference = gameObject.GetComponent<PhotonView>();
			Position = position;
			Type = type;
			IsWhite = isWhite;
			manager = ChessManager.Instance;
			PositionOnBoard = new BoardPosition(Position, manager.GetChessBoardPosition());
		}

		public ChessPiece(GameObject chessPiece)
			: this(chessPiece, chessPiece.transform.position, NameToType(((Object)chessPiece).name), NameToColor(((Object)chessPiece).name))
		{
		}//IL_0008: Unknown result type (might be due to invalid IL or missing references)


		public static PieceType NameToType(string name)
		{
			name = name.ToLowerInvariant();
			string text = name;
			if (name.Contains("pawn"))
			{
				return PieceType.Pawn;
			}
			if (name.Contains("knight"))
			{
				return PieceType.Knight;
			}
			if (name.Contains("bishop"))
			{
				return PieceType.Bishop;
			}
			if (name.Contains("rook"))
			{
				return PieceType.Rook;
			}
			if (name.Contains("queen"))
			{
				return PieceType.Queen;
			}
			if (name.Contains("king"))
			{
				return PieceType.King;
			}
			return PieceType.None;
		}

		public static bool NameToColor(string name)
		{
			string[] array = name.Split(' ', 2);
			if (array.Length < 2)
			{
				return true;
			}
			if (!array[1].Contains('B'))
			{
				return true;
			}
			return false;
		}
	}
	public enum PieceType
	{
		None,
		Pawn,
		Knight,
		Bishop,
		Rook,
		Queen,
		King
	}
	public static class MovableChessboardWrapper
	{
		private static bool initialized;

		private static bool available;

		private static bool? _enabled;

		private static object? _managerInstance;

		private static EventInfo? _onBoardLoaded;

		private static EventInfo? _onPositionChanged;

		private static EventInfo? _onRotationChanged;

		private static EventInfo? _onScaleChanged;

		public static bool IsAvailable => available;

		public static bool enabled
		{
			get
			{
				if (!_enabled.HasValue)
				{
					_enabled = Chainloader.PluginInfos.ContainsKey("com.github.Kirshoo.MovableChessboard");
				}
				return _enabled.Value;
			}
		}

		public static void Init()
		{
			if (initialized)
			{
				return;
			}
			initialized = true;
			Assembly assembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly a) => a.GetName().Name == "com.github.Kirshoo.MovableChessboard");
			if (assembly == null)
			{
				Plugin.Log.LogWarning((object)"Unable to find com.github.Kirshoo.MovableChessboard assembly...");
				available = false;
				return;
			}
			Type type = assembly.GetType("MovableChessboard.BoardManager");
			if (type == null)
			{
				Plugin.Log.LogWarning((object)"Unable to find BoardManager of MovableChessboard namespace...");
				available = false;
				return;
			}
			_managerInstance = type.GetProperty("Instance", BindingFlags.Static | BindingFlags.Public)?.GetValue(null);
			if (_managerInstance == null)
			{
				Plugin.Log.LogWarning((object)"Unable to get Instance of BoardManager...");
				available = false;
				return;
			}
			_managerInstance.GetType().GetMethod("Init").Invoke(_managerInstance, null);
			_onBoardLoaded = type.GetEvent("OnBoardLoaded");
			_onPositionChanged = type.GetEvent("OnBoardChangedPosition");
			_onRotationChanged = type.GetEvent("OnBoardChangedRotation");
			_onScaleChanged = type.GetEvent("OnBoardChangedScale");
			available = true;
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		public static void SubscirbeToPositionChanged(Action<Vector3> callback)
		{
			if (!enabled || !initialized || _onPositionChanged == null)
			{
				Plugin.Log.LogError((object)"[MCWrapper] Failed to subscribe to position changed event.");
				Plugin.Log.LogDebug((object)$"[MCWrapper] Enabled? {enabled}; Initialized? {initialized}; HasEvent? {_onPositionChanged != null}");
			}
			else
			{
				Delegate handler = Delegate.CreateDelegate(_onPositionChanged.EventHandlerType, callback.Target, callback.Method);
				_onPositionChanged.AddEventHandler(_managerInstance, handler);
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		public static void SubscirbeToRotationChanged(Action<Quaternion> callback)
		{
			if (!enabled || !initialized || _onRotationChanged == null)
			{
				Plugin.Log.LogError((object)"[MCWrapper] Failed to subscribe to rotation changed event.");
				Plugin.Log.LogDebug((object)$"[MCWrapper] Enabled? {enabled}; Initialized? {initialized}; HasEvent? {_onRotationChanged != null}");
			}
			else
			{
				Delegate handler = Delegate.CreateDelegate(_onRotationChanged.EventHandlerType, callback.Target, callback.Method);
				_onRotationChanged.AddEventHandler(_managerInstance, handler);
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		public static void SubscirbeToScaleChanged(Action<Vector3> callback)
		{
			if (!enabled || !initialized || _onScaleChanged == null)
			{
				Plugin.Log.LogError((object)"[MCWrapper] Failed to subscribe to scale changed event.");
				Plugin.Log.LogDebug((object)$"[MCWrapper] Enabled? {enabled}; Initialized? {initialized}; HasEvent? {_onScaleChanged != null}");
			}
			else
			{
				Delegate handler = Delegate.CreateDelegate(_onScaleChanged.EventHandlerType, callback.Target, callback.Method);
				_onScaleChanged.AddEventHandler(_managerInstance, handler);
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		public static void SubscirbeToBoardLoaded(Action callback)
		{
			if (enabled && initialized && !(_onBoardLoaded == null))
			{
				Delegate handler = Delegate.CreateDelegate(_onBoardLoaded.EventHandlerType, callback.Target, callback.Method);
				_onBoardLoaded.AddEventHandler(_managerInstance, handler);
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		public static GameObject? GetBoard()
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Expected O, but got Unknown
			if (!enabled || _managerInstance == null)
			{
				Plugin.Log.LogWarning((object)"Ignoring attempt at accessing board: Wrapper is not enabled.");
				return null;
			}
			MethodInfo method = _managerInstance.GetType().GetMethod("GetBoard");
			return (GameObject)method.Invoke(_managerInstance, null);
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		public static Vector3 GetBoardPosition()
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			if (!enabled || _managerInstance == null)
			{
				Plugin.Log.LogWarning((object)"Ignoring attempt at accessing board position: Wrapper is not enabled.");
				return Vector3.zero;
			}
			MethodInfo method = _managerInstance.GetType().GetMethod("GetBoardPosition");
			return (Vector3)method.Invoke(_managerInstance, null);
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		public static Quaternion GetBoardRotation()
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			if (!enabled || _managerInstance == null)
			{
				Plugin.Log.LogWarning((object)"Ignoring attempt at accessing board rotation: Wrapper is not enabled.");
				return Quaternion.identity;
			}
			MethodInfo method = _managerInstance.GetType().GetMethod("GetBoardRotation");
			return (Quaternion)method.Invoke(_managerInstance, null);
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		public static Vector3 GetBoardScale()
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			if (!enabled || _managerInstance == null)
			{
				Plugin.Log.LogWarning((object)"Ignoring attempt at accessing board scale: Wrapper is not enabled.");
				return Vector3.zero;
			}
			MethodInfo method = _managerInstance.GetType().GetMethod("GetBoardScale");
			return (Vector3)method.Invoke(_managerInstance, null);
		}
	}
	internal class PieceMovement
	{
	}
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("com.github.Kirshoo.BetterChess", "BetterChess", "0.5.0")]
	public class Plugin : BaseUnityPlugin
	{
		internal static ConfigEntry<float> LerpSpeed;

		internal static ConfigEntry<int> BoardOffsetGrids;

		internal static ConfigEntry<KeyCode> ResetButton;

		internal static ConfigEntry<string> DefaultPosition;

		public const string Id = "com.github.Kirshoo.BetterChess";

		internal static ManualLogSource Log { get; private set; }

		public static string Name => "BetterChess";

		public static string Version => "0.5.0";

		private void Awake()
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			BindConfig();
			new Harmony("com.github.Kirshoo.BetterChess").PatchAll(typeof(PieceSnappingPatch));
			Log.LogInfo((object)("Plugin " + Name + " is loaded!"));
		}

		private void BindConfig()
		{
			BoardOffsetGrids = ((BaseUnityPlugin)this).Config.Bind<int>("Snapping", "BoardOffsetGrids", 2, "Range outside chessboard where snapping will affect the pieces. \r\nRepresented in terms of grids cells.\r\nIf set to 0 or lower, will only snap pieces within the chessboard.");
			if (BoardOffsetGrids.Value < 0)
			{
				BoardOffsetGrids.Value = 0;
			}
			LerpSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Snapping", "SnapSpeed", 2f, "Speed at which pieces are snapped to their positions within the grid.\r\nAllowed range: 0.5 - 5");
			if ((double)LerpSpeed.Value < 0.5)
			{
				LerpSpeed.Value = 0.5f;
			}
			else if (LerpSpeed.Value > 5f)
			{
				LerpSpeed.Value = 5f;
			}
			ResetButton = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("General", "ResetButton", (KeyCode)99, "Button that resets the chessboard state located in airport.\r\nWhen first loaded to the airport, press this button TWICE to ensure proper initialization.");
			DefaultPosition = ((BaseUnityPlugin)this).Config.Bind<string>("General", "DefaultBoardState", "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1", "Represents default state which board will reset to, when ResetButton is pressed.\r\nValue is in FEN notation. You can see more information about it on this wiki page:\r\nhttps://en.wikipedia.org/wiki/Forsyth%E2%80%93Edwards_Notation");
		}

		private void Start()
		{
			ChessManager.Instance.Init();
		}

		private void Update()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			if (Input.GetKeyDown(ResetButton.Value))
			{
				if (!Util.IsInAirport())
				{
					Log.LogInfo((object)"Cannot reset the state of chessboard whilst not being in Airport");
				}
				else if (!PhotonNetwork.IsMasterClient)
				{
					Log.LogInfo((object)"Only HOST can reset chessboard state");
				}
				else
				{
					ChessLogic.ResetBoardPosition(DefaultPosition.Value);
				}
			}
		}
	}
	internal class PieceSnappingPatch
	{
		[CompilerGenerated]
		private sealed class <SnapToGridLerp>d__9 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public ChessStabilizer chessPiece;

			public PhotonView view;

			private Transform <piece>5__2;

			private Collider <col>5__3;

			private Vector3 <start>5__4;

			private Vector3 <target>5__5;

			private float <t>5__6;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <SnapToGridLerp>d__9(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<piece>5__2 = null;
				<col>5__3 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_005b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0060: Unknown result type (might be due to invalid IL or missing references)
				//IL_0068: Unknown result type (might be due to invalid IL or missing references)
				//IL_006d: Unknown result type (might be due to invalid IL or missing references)
				//IL_007d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0095: Unknown result type (might be due to invalid IL or missing references)
				//IL_009c: 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_00bf: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
				//IL_00de: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
				//IL_0104: Unknown result type (might be due to invalid IL or missing references)
				//IL_0109: Unknown result type (might be due to invalid IL or missing references)
				//IL_013a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0140: Unknown result type (might be due to invalid IL or missing references)
				//IL_014b: Unknown result type (might be due to invalid IL or missing references)
				//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
				//IL_01da: Unknown result type (might be due to invalid IL or missing references)
				//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
				{
					<>1__state = -1;
					<piece>5__2 = ((Component)chessPiece).transform;
					<col>5__3 = ((Component)<piece>5__2).GetComponent<Collider>();
					if ((Object)(object)<col>5__3 != (Object)null)
					{
						<col>5__3.enabled = false;
					}
					Vector3 chessBoardOrigin = ChessManager.Instance.GetChessBoardOrigin();
					<start>5__4 = <piece>5__2.position;
					float num = Mathf.Clamp(Mathf.Round((<start>5__4.x - chessBoardOrigin.x) / 0.8f) * 0.8f + chessBoardOrigin.x, chessBoardOrigin.x, chessBoardOrigin.x + 5.6f);
					float num2 = Mathf.Clamp(Mathf.Round((<start>5__4.z - chessBoardOrigin.z) / 0.8f) * 0.8f + chessBoardOrigin.z, chessBoardOrigin.z, chessBoardOrigin.z + 5.6f);
					<target>5__5 = new Vector3(num, <start>5__4.y, num2);
					<t>5__6 = 0f;
					break;
				}
				case 1:
					<>1__state = -1;
					break;
				}
				if (<t>5__6 < 1f)
				{
					<t>5__6 += Time.fixedDeltaTime * 2f;
					<piece>5__2.position = Vector3.Lerp(<start>5__4, <target>5__5, <t>5__6);
					chessPiece.groundTimer = <t>5__6;
					<>2__current = null;
					<>1__state = 1;
					return true;
				}
				if ((Object)(object)<col>5__3 != (Object)null)
				{
					<col>5__3.enabled = true;
				}
				view.RPC("SetKinematicRPC", (RpcTarget)3, new object[3]
				{
					true,
					<target>5__5,
					Quaternion.Euler(0f, <piece>5__2.eulerAngles.y, 0f)
				});
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		private const float LerpSpeed = 2f;

		private const float SnapTimeOffset = 1f;

		internal static readonly Vector3 boardMinOffset = new Vector3((float)Plugin.BoardOffsetGrids.Value * 0.8f, 0f, (float)Plugin.BoardOffsetGrids.Value * 0.8f);

		internal static readonly Vector3 boardMaxOffset = new Vector3((float)(7 + Plugin.BoardOffsetGrids.Value) * 0.8f, 0f, (float)(7 + Plugin.BoardOffsetGrids.Value) * 0.8f);

		private static readonly HashSet<ChessStabilizer> snappedPieces = new HashSet<ChessStabilizer>();

		private static void ClearUpSnappedCollection()
		{
			snappedPieces.RemoveWhere((ChessStabilizer component) => (Object)(object)component == (Object)null);
		}

		private static bool ReadyToSnap(Rigidbody rb, ChessStabilizer stabilizer)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: 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_0053: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)rb == (Object)null) && !rb.isKinematic && !(stabilizer.groundTimer < 1f))
			{
				Vector3 val = rb.linearVelocity;
				if (!(((Vector3)(ref val)).sqrMagnitude >= 0.8f))
				{
					val = rb.angularVelocity;
					if (!(((Vector3)(ref val)).sqrMagnitude >= 0.8f))
					{
						return !(Vector3.Angle(((Component)stabilizer).transform.up, Vector3.up) >= 2.5f);
					}
				}
			}
			return false;
		}

		[HarmonyPatch(typeof(ChessStabilizer), "FixedUpdate")]
		[HarmonyPostfix]
		private static void SnapPiece(ChessStabilizer __instance)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			if (!PhotonNetwork.IsMasterClient)
			{
				return;
			}
			Rigidbody rig = __instance.item.rig;
			if (ReadyToSnap(rig, __instance) && WithinBoardArea(((Component)__instance).transform.position))
			{
				ClearUpSnappedCollection();
				if (!snappedPieces.Contains(__instance))
				{
					snappedPieces.Add(__instance);
					((MonoBehaviour)__instance).StartCoroutine(SnapToGridLerp(__instance, ((Component)__instance).gameObject.GetComponent<PhotonView>()));
				}
			}
		}

		private static bool WithinBoardArea(Vector3 position)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: 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)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: 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)
			Vector3 chessBoardOrigin = ChessManager.Instance.GetChessBoardOrigin();
			if (position.x >= chessBoardOrigin.x - boardMinOffset.x && position.x < chessBoardOrigin.x + boardMaxOffset.x && position.z >= chessBoardOrigin.z - boardMinOffset.z)
			{
				return position.z < chessBoardOrigin.z + boardMaxOffset.z;
			}
			return false;
		}

		[IteratorStateMachine(typeof(<SnapToGridLerp>d__9))]
		private static IEnumerator SnapToGridLerp(ChessStabilizer chessPiece, PhotonView view)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <SnapToGridLerp>d__9(0)
			{
				chessPiece = chessPiece,
				view = view
			};
		}
	}
	internal static class Util
	{
		private const string AirportSceneName = "Airport";

		internal static bool IsInAirport()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			Scene activeScene = SceneManager.GetActiveScene();
			return ((Scene)(ref activeScene)).name == "Airport";
		}

		internal static void ApplyBoardMovement(Transform obj, Vector3 deltaMovement)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			Transform transform = ((Component)obj).transform;
			transform.position += deltaMovement;
		}

		internal static void RotateAroundPivot(Transform obj, Vector3 pivot, Quaternion rotation)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: 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_002a: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = obj.position - pivot;
			val = rotation * val;
			obj.position = pivot + val;
			obj.rotation = rotation * obj.rotation;
		}

		internal static void ApplyBoardScale(Transform obj, Vector3 center, Vector3 oldScale, Vector3 newScale)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: 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_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: 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_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = default(Vector3);
			((Vector3)(ref val))..ctor(newScale.x / oldScale.x, newScale.y / oldScale.y, newScale.z / oldScale.z);
			Vector3 val2 = obj.position - center;
			val2 = Vector3.Scale(val2, val);
			obj.position = center + val2;
			obj.localScale = Vector3.Scale(obj.localScale, val);
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}