Decompiled source of Scoreboard v1.0.0

Scoreboard.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 BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Photon.Pun;
using Photon.Realtime;
using TMPro;
using UnboundLib;
using UnboundLib.Extensions;
using UnboundLib.GameModes;
using UnboundLib.Networking;
using UnboundLib.Utils;
using UnboundLib.Utils.UI;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = "")]
[assembly: AssemblyVersion("0.0.0.0")]
namespace Scoreboard;

internal sealed class PlayerStats
{
	public int PlayerId;

	public int Kills;

	public float Damage;

	public int Shots;

	public int Hits;

	public float DamageTaken;

	public int LastStanding;

	public float Accuracy
	{
		get
		{
			if (Shots <= 0)
			{
				return -1f;
			}
			return Math.Min(1f, (float)Hits / (float)Shots);
		}
	}

	public float Impact => (float)Kills * 100f + Damage;

	public PlayerStats Clone()
	{
		return new PlayerStats
		{
			PlayerId = PlayerId,
			Kills = Kills,
			Damage = Damage,
			Shots = Shots,
			Hits = Hits,
			DamageTaken = DamageTaken,
			LastStanding = LastStanding
		};
	}
}
internal sealed class BoardData
{
	public int Round;

	public int Fights;

	public bool Enabled = true;

	public float Duration = 5f;

	public bool FromHost;

	public bool IsFinal;

	public bool FinalEnabled = true;

	public float FinalDuration = 8f;

	public readonly List<PlayerStats> Players = new List<PlayerStats>();

	public int MvpId
	{
		get
		{
			PlayerStats playerStats = null;
			foreach (PlayerStats player in Players)
			{
				if (!(player.Impact <= 0f) && (playerStats == null || Better(player, playerStats)))
				{
					playerStats = player;
				}
			}
			return playerStats?.PlayerId ?? (-1);
		}
	}

	private static bool Better(PlayerStats a, PlayerStats b)
	{
		if (Math.Abs(a.Impact - b.Impact) > 0.01f)
		{
			return a.Impact > b.Impact;
		}
		if (a.Kills != b.Kills)
		{
			return a.Kills > b.Kills;
		}
		if (Math.Abs(a.Accuracy - b.Accuracy) > 0.0001f)
		{
			return a.Accuracy > b.Accuracy;
		}
		return a.PlayerId < b.PlayerId;
	}

	public List<PlayerStats> Sorted()
	{
		return (from p in Players
			orderby p.Impact descending, p.Kills descending, p.Accuracy descending, p.PlayerId
			select p).ToList();
	}

	internal object[] Pack()
	{
		int count = Players.Count;
		int[] array = new int[count];
		int[] array2 = new int[count];
		float[] array3 = new float[count];
		int[] array4 = new int[count];
		int[] array5 = new int[count];
		float[] array6 = new float[count];
		int[] array7 = new int[count];
		for (int i = 0; i < count; i++)
		{
			PlayerStats playerStats = Players[i];
			array[i] = playerStats.PlayerId;
			array2[i] = playerStats.Kills;
			array3[i] = playerStats.Damage;
			array4[i] = playerStats.Shots;
			array5[i] = playerStats.Hits;
			array6[i] = playerStats.DamageTaken;
			array7[i] = playerStats.LastStanding;
		}
		return new object[13]
		{
			Round, Fights, Enabled, Duration, array, array2, array3, array4, array5, array6,
			array7, FinalEnabled, FinalDuration
		};
	}

	internal static BoardData Unpack(int round, int fights, bool enabled, float duration, int[] ids, int[] kills, float[] dmg, int[] shots, int[] hits, float[] taken, int[] standing, bool finalEnabled, float finalDuration)
	{
		BoardData boardData = new BoardData
		{
			Round = round,
			Fights = fights,
			Enabled = enabled,
			Duration = duration,
			FromHost = true,
			FinalEnabled = finalEnabled,
			FinalDuration = finalDuration
		};
		int num = ((ids != null) ? ids.Length : 0);
		for (int i = 0; i < num; i++)
		{
			boardData.Players.Add(new PlayerStats
			{
				PlayerId = ids[i],
				Kills = At(kills, i),
				Damage = At(dmg, i),
				Shots = At(shots, i),
				Hits = At(hits, i),
				DamageTaken = At(taken, i),
				LastStanding = At(standing, i)
			});
		}
		return boardData;
	}

	private static T At<T>(T[] arr, int i)
	{
		if (arr == null || i >= arr.Length)
		{
			return default(T);
		}
		return arr[i];
	}
}
internal static class BoardSync
{
	private const float MinDuration = 2f;

	private const float MaxDuration = 15f;

	private const float ExtraTimeout = 6f;

	private const float MaxFinalDuration = 20f;

	private const float FinalDataGrace = 0.75f;

	private const int FinalKeyOffset = 100000;

	private static int round;

	private static int lastShownRound;

	private static readonly Dictionary<int, BoardData> hostBoards = new Dictionary<int, BoardData>();

	private static readonly Dictionary<int, BoardData> localBoards = new Dictionary<int, BoardData>();

	private static readonly HashSet<int> released = new HashSet<int>();

	private static float lastReleaseAt = -999f;

	private static readonly HashSet<int> modActors = new HashSet<int>();

	private static string modActorsRoom;

	private static int finalToken;

	internal static bool Waiting { get; private set; }

	internal static void Register()
	{
		GameModeManager.AddHook("GameStart", (Func<IGameModeHandler, IEnumerator>)OnGameStart, 800);
		GameModeManager.AddHook("PointEnd", (Func<IGameModeHandler, IEnumerator>)OnPointEnd, 0);
		GameModeManager.AddHook("RoundEnd", (Func<IGameModeHandler, IEnumerator>)OnRoundEnd, 800);
		GameModeManager.AddHook("PickStart", (Func<IGameModeHandler, IEnumerator>)OnPickStart, 800);
		GameModeManager.AddHook("GameEnd", (Func<IGameModeHandler, IEnumerator>)OnGameEnd, 800);
	}

	private static IEnumerator OnGameStart(IGameModeHandler gm)
	{
		GameStarted();
		yield break;
	}

	private static void GameStarted()
	{
		try
		{
			round = 0;
			lastShownRound = 0;
			hostBoards.Clear();
			localBoards.Clear();
			released.Clear();
			StatTracker.Reset();
			SayHello();
		}
		catch (Exception ex)
		{
			Scoreboard.Log.LogError((object)ex);
		}
	}

	private static IEnumerator OnPointEnd(IGameModeHandler gm)
	{
		StatTracker.FightEnded();
		yield break;
	}

	private static IEnumerator OnRoundEnd(IGameModeHandler gm)
	{
		RoundEnded();
		yield break;
	}

	private static void RoundEnded()
	{
		try
		{
			if (IsSandbox())
			{
				return;
			}
			round++;
			BoardData boardData = StatTracker.TakeSnapshot(round);
			localBoards[round] = boardData;
			SayHello();
			if (IsHost())
			{
				string missing = null;
				boardData.Enabled = Scoreboard.Enabled.Value && EveryoneHasMod(out missing);
				boardData.Duration = Mathf.Clamp(Scoreboard.Duration.Value, 2f, 15f);
				if (Scoreboard.Enabled.Value && !boardData.Enabled)
				{
					Scoreboard.Log.LogWarning((object)("Scoreboard skipped this round: " + missing + " doesn't have the Scoreboard mod."));
				}
				boardData.FinalEnabled = Scoreboard.ShowFinal.Value && missing == null && EveryoneHasMod(out var _);
				boardData.FinalDuration = Mathf.Clamp(Scoreboard.FinalDuration.Value, 2f, 20f);
				NetworkingManager.RPC(typeof(BoardSync), "RPCA_Board", boardData.Pack());
			}
		}
		catch (Exception arg)
		{
			Scoreboard.Log.LogError((object)$"RoundEnd: {arg}");
		}
	}

	private static IEnumerator OnPickStart(IGameModeHandler gm)
	{
		int thisRound = 0;
		bool host = false;
		bool flag = false;
		bool flag2 = false;
		float duration = 5f;
		float timeout = 0f;
		BoardData boardData = null;
		try
		{
			if (!IsSandbox() && round != 0 && round != lastShownRound)
			{
				thisRound = round;
				lastShownRound = round;
				host = IsHost();
				hostBoards.TryGetValue(thisRound, out var value);
				localBoards.TryGetValue(thisRound, out var value2);
				if (host)
				{
					boardData = value2;
					bool num = boardData?.Enabled ?? false;
					flag2 = num;
					flag = num;
					duration = boardData?.Duration ?? 5f;
					if (!flag)
					{
						Release(thisRound);
					}
				}
				else if (value != null)
				{
					boardData = value;
					flag = (flag2 = value.Enabled);
					duration = value.Duration;
				}
				else if (!HostHasMod())
				{
					Scoreboard.Log.LogInfo((object)"Host doesn't have Scoreboard; skipping.");
				}
				else
				{
					Scoreboard.Log.LogWarning((object)"Host's scoreboard didn't arrive; showing this client's own stats.");
					boardData = value2;
					flag = true;
					flag2 = boardData != null && Scoreboard.Enabled.Value;
					duration = Mathf.Clamp(Scoreboard.Duration.Value, 2f, 15f);
				}
				duration = Mathf.Clamp(duration, 2f, 15f);
				timeout = duration + 6f;
				if (flag2 && boardData != null)
				{
					ScoreboardUI.Show(boardData, duration);
				}
			}
		}
		catch (Exception arg)
		{
			Scoreboard.Log.LogError((object)$"PickStart: {arg}");
			if (host)
			{
				SafeRelease(thisRound);
			}
			flag = false;
		}
		if (!flag)
		{
			yield break;
		}
		Waiting = true;
		float start = Time.realtimeSinceStartup;
		while (true)
		{
			float num2 = Time.realtimeSinceStartup - start;
			if (host)
			{
				if (num2 >= duration)
				{
					SafeRelease(thisRound);
					break;
				}
			}
			else
			{
				if (IsReleased(thisRound) || lastReleaseAt >= start - 2f || !InGame())
				{
					break;
				}
				if (IsHost())
				{
					SafeRelease(thisRound);
					break;
				}
				if (num2 >= timeout)
				{
					Scoreboard.Log.LogWarning((object)"Timed out waiting for the host; continuing to the card pick.");
					break;
				}
			}
			yield return null;
		}
		Waiting = false;
		ScoreboardUI.SafeHide();
	}

	private static IEnumerator OnGameEnd(IGameModeHandler gm)
	{
		if (RwfEndScreen.Active)
		{
			Waiting = false;
			ScoreboardUI.SafeHide();
			yield break;
		}
		int key = 0;
		int lastRound = 0;
		bool host = false;
		bool flag = false;
		bool show = false;
		bool shown = false;
		float duration = 8f;
		float timeout = 0f;
		try
		{
			Waiting = false;
			ScoreboardUI.SafeHide();
			if (!IsSandbox() && round > 0)
			{
				lastRound = round;
				key = 100000 + round;
				host = IsHost();
				float num = Mathf.Clamp(Scoreboard.FinalDuration.Value, 2f, 20f);
				if (host)
				{
					localBoards.TryGetValue(round, out var value);
					string missing;
					bool num2 = value?.FinalEnabled ?? (Scoreboard.ShowFinal.Value && EveryoneHasMod(out missing));
					bool flag2 = num2;
					show = num2;
					flag = flag2;
					duration = value?.FinalDuration ?? num;
					if (!flag)
					{
						Release(key);
					}
				}
				else
				{
					BoardData boardData = LatestHostBoard();
					if (boardData != null)
					{
						bool flag2;
						show = (flag2 = boardData.FinalEnabled);
						flag = flag2;
						duration = boardData.FinalDuration;
					}
					else if (HostHasMod())
					{
						flag = true;
						show = Scoreboard.ShowFinal.Value;
						duration = num;
					}
				}
				duration = Mathf.Clamp(duration, 2f, 20f);
				timeout = duration + 6f;
			}
		}
		catch (Exception arg)
		{
			Scoreboard.Log.LogError((object)$"GameEnd: {arg}");
			if (host)
			{
				SafeRelease(key);
			}
			flag = false;
		}
		if (!flag)
		{
			yield break;
		}
		Waiting = true;
		float start = Time.realtimeSinceStartup;
		while (true)
		{
			float num3 = Time.realtimeSinceStartup - start;
			if (show && !shown && (host || HasHostBoard(lastRound) || num3 >= 0.75f))
			{
				shown = true;
				ShowTotals(lastRound, Mathf.Max(1f, duration - num3));
			}
			if (host)
			{
				if (num3 >= duration)
				{
					SafeRelease(key);
					break;
				}
			}
			else
			{
				if (IsReleased(key) || lastReleaseAt >= start - 2f || !InGame())
				{
					break;
				}
				if (IsHost())
				{
					SafeRelease(key);
					break;
				}
				if (num3 >= timeout)
				{
					Scoreboard.Log.LogWarning((object)"Timed out waiting for the host after the game totals.");
					break;
				}
			}
			yield return null;
		}
		Waiting = false;
		ScoreboardUI.SafeHide();
	}

	internal static bool HostFinalSettings(out float duration)
	{
		duration = Mathf.Clamp(Scoreboard.FinalDuration.Value, 2f, 20f);
		try
		{
			return Scoreboard.ShowFinal.Value && round > 0 && !IsSandbox();
		}
		catch
		{
			return false;
		}
	}

	internal static void BroadcastFinal(float duration)
	{
		try
		{
			NetworkingManager.RPC(typeof(BoardSync), "RPCA_ShowFinal", new object[2] { round, duration });
		}
		catch (Exception arg)
		{
			Scoreboard.Log.LogError((object)$"Couldn't send game totals: {arg}");
		}
	}

	[UnboundRPC]
	public static void RPCA_ShowFinal(int r, float duration)
	{
		try
		{
			int token = ++finalToken;
			((MonoBehaviour)Scoreboard.Instance).StartCoroutine(ShowFinalRoutine(r, Mathf.Clamp(duration, 2f, 20f), token));
		}
		catch (Exception ex)
		{
			Scoreboard.Log.LogError((object)ex);
		}
	}

	private static IEnumerator ShowFinalRoutine(int r, float duration, int token)
	{
		float start = Time.realtimeSinceStartup;
		while (!HasHostBoard(r) && Time.realtimeSinceStartup - start < 0.75f)
		{
			yield return null;
		}
		float num = duration - (Time.realtimeSinceStartup - start);
		ShowTotals(r, Mathf.Max(1f, num));
		yield return (object)new WaitForSecondsRealtime(Mathf.Max(0f, num));
		if (token == finalToken)
		{
			ScoreboardUI.SafeHide();
		}
	}

	private static void ShowTotals(int lastRound, float seconds)
	{
		try
		{
			BoardData boardData = BuildTotals(lastRound);
			if (boardData.Players.Count > 0)
			{
				ScoreboardUI.Show(boardData, seconds);
			}
		}
		catch (Exception arg)
		{
			Scoreboard.Log.LogError((object)$"Game totals failed: {arg}");
		}
	}

	private static BoardData BuildTotals(int lastRound)
	{
		BoardData boardData = new BoardData
		{
			Round = lastRound,
			Fights = 0,
			IsFinal = true,
			FromHost = true
		};
		Dictionary<int, PlayerStats> dictionary = new Dictionary<int, PlayerStats>();
		for (int i = 1; i <= lastRound; i++)
		{
			if (!hostBoards.TryGetValue(i, out var value))
			{
				if (!localBoards.TryGetValue(i, out value))
				{
					continue;
				}
				boardData.FromHost = false;
			}
			boardData.Fights += value.Fights;
			foreach (PlayerStats player in value.Players)
			{
				if (!dictionary.TryGetValue(player.PlayerId, out var value2))
				{
					value2 = new PlayerStats
					{
						PlayerId = player.PlayerId
					};
					dictionary[player.PlayerId] = value2;
					boardData.Players.Add(value2);
				}
				value2.Kills += player.Kills;
				value2.Damage += player.Damage;
				value2.Shots += player.Shots;
				value2.Hits += player.Hits;
				value2.DamageTaken += player.DamageTaken;
				value2.LastStanding += player.LastStanding;
			}
		}
		return boardData;
	}

	private static BoardData LatestHostBoard()
	{
		BoardData boardData = null;
		foreach (KeyValuePair<int, BoardData> hostBoard in hostBoards)
		{
			if (boardData == null || hostBoard.Key > boardData.Round)
			{
				boardData = hostBoard.Value;
			}
		}
		return boardData;
	}

	private static bool HasHostBoard(int r)
	{
		try
		{
			return hostBoards.ContainsKey(r);
		}
		catch
		{
			return true;
		}
	}

	[UnboundRPC]
	public static void RPCA_Board(int round, int fights, bool enabled, float duration, int[] ids, int[] kills, float[] dmg, int[] shots, int[] hits, float[] taken, int[] standing, bool finalEnabled, float finalDuration)
	{
		try
		{
			hostBoards[round] = BoardData.Unpack(round, fights, enabled, duration, ids, kills, dmg, shots, hits, taken, standing, finalEnabled, finalDuration);
		}
		catch (Exception arg)
		{
			Scoreboard.Log.LogError((object)$"Bad board message: {arg}");
		}
	}

	[UnboundRPC]
	public static void RPCA_Release(int round)
	{
		try
		{
			released.Add(round);
			lastReleaseAt = Time.realtimeSinceStartup;
		}
		catch
		{
		}
	}

	[UnboundRPC]
	public static void RPCA_Hello(int actor, string version)
	{
		try
		{
			SyncRoom();
			if (modActors.Add(actor) && PhotonNetwork.LocalPlayer != null && actor != PhotonNetwork.LocalPlayer.ActorNumber)
			{
				SayHello();
			}
		}
		catch
		{
		}
	}

	private static void Release(int r)
	{
		NetworkingManager.RPC(typeof(BoardSync), "RPCA_Release", new object[1] { r });
	}

	private static void SafeRelease(int r)
	{
		try
		{
			Release(r);
		}
		catch (Exception arg)
		{
			Scoreboard.Log.LogError((object)$"Release failed: {arg}");
		}
	}

	private static void SayHello()
	{
		try
		{
			SyncRoom();
			Player localPlayer = PhotonNetwork.LocalPlayer;
			int num = ((localPlayer != null) ? localPlayer.ActorNumber : (-1));
			modActors.Add(num);
			if (!PhotonNetwork.OfflineMode && PhotonNetwork.InRoom)
			{
				NetworkingManager.RPC_Others(typeof(BoardSync), "RPCA_Hello", new object[2] { num, "1.0.0" });
			}
		}
		catch
		{
		}
	}

	private static bool IsReleased(int r)
	{
		try
		{
			return released.Contains(r);
		}
		catch
		{
			return true;
		}
	}

	private static bool IsHost()
	{
		try
		{
			return PhotonNetwork.OfflineMode || !PhotonNetwork.InRoom || PhotonNetwork.IsMasterClient;
		}
		catch
		{
			return true;
		}
	}

	private static bool InGame()
	{
		try
		{
			return PhotonNetwork.OfflineMode || PhotonNetwork.InRoom;
		}
		catch
		{
			return false;
		}
	}

	private static bool IsSandbox()
	{
		try
		{
			return GameModeManager.CurrentHandlerID == "Sandbox";
		}
		catch
		{
			return false;
		}
	}

	private static void SyncRoom()
	{
		string text = null;
		try
		{
			Room currentRoom = PhotonNetwork.CurrentRoom;
			text = ((currentRoom != null) ? currentRoom.Name : null);
		}
		catch
		{
		}
		if (text != modActorsRoom)
		{
			modActorsRoom = text;
			modActors.Clear();
		}
	}

	private static bool HostHasMod()
	{
		try
		{
			if (PhotonNetwork.OfflineMode || !PhotonNetwork.InRoom)
			{
				return true;
			}
			SyncRoom();
			Player masterClient = PhotonNetwork.MasterClient;
			return masterClient != null && modActors.Contains(masterClient.ActorNumber);
		}
		catch
		{
			return false;
		}
	}

	private static bool EveryoneHasMod(out string missing)
	{
		missing = null;
		try
		{
			if (PhotonNetwork.OfflineMode || !PhotonNetwork.InRoom)
			{
				return true;
			}
			SyncRoom();
			List<Player> list = PhotonNetwork.PlayerList.Where((Player p) => !modActors.Contains(p.ActorNumber)).ToList();
			if (list.Count == 0)
			{
				return true;
			}
			missing = string.Join(", ", list.Select((Player p) => (!string.IsNullOrEmpty(p.NickName)) ? p.NickName : ("Player " + p.ActorNumber)));
			return false;
		}
		catch
		{
			missing = "someone";
			return false;
		}
	}
}
internal static class RwfEndScreen
{
	private static MethodInfo openMethod;

	private static bool bypass;

	internal static bool Active { get; private set; }

	internal static void TryPatch(Harmony harmony)
	{
		//IL_005d: Unknown result type (might be due to invalid IL or missing references)
		//IL_006b: Expected O, but got Unknown
		try
		{
			Type type = AccessTools.TypeByName("RWF.UI.PopUpMenu");
			openMethod = ((type != null) ? AccessTools.Method(type, "Open", (Type[])null, (Type[])null) : null);
			if (openMethod == null)
			{
				Scoreboard.Log.LogInfo((object)"RoundsWithFriends end menu not found; game totals use the game-end hook.");
				return;
			}
			harmony.Patch((MethodBase)openMethod, new HarmonyMethod(typeof(RwfEndScreen), "OpenPrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			Active = true;
		}
		catch (Exception arg)
		{
			Active = false;
			Scoreboard.Log.LogError((object)$"Couldn't hook the RoundsWithFriends end menu: {arg}");
		}
	}

	private static bool OpenPrefix(object __instance, List<string> choices, Action<string> callback)
	{
		try
		{
			if (bypass)
			{
				return true;
			}
			if (choices == null || !choices.Contains("REMATCH"))
			{
				return true;
			}
			if (!BoardSync.HostFinalSettings(out var duration))
			{
				return true;
			}
			((MonoBehaviour)Scoreboard.Instance).StartCoroutine(HoldMenu(__instance, new List<string>(choices), callback, duration));
			return false;
		}
		catch (Exception arg)
		{
			Scoreboard.Log.LogError((object)$"End menu hold failed, opening it normally: {arg}");
			return true;
		}
	}

	private static IEnumerator HoldMenu(object menu, List<string> choices, Action<string> callback, float duration)
	{
		BoardSync.BroadcastFinal(duration);
		yield return (object)new WaitForSecondsRealtime(duration);
		ScoreboardUI.SafeHide();
		OpenNow(menu, choices, callback);
	}

	private static void OpenNow(object menu, List<string> choices, Action<string> callback)
	{
		bypass = true;
		try
		{
			openMethod.Invoke(menu, new object[2] { choices, callback });
		}
		catch (Exception arg)
		{
			Scoreboard.Log.LogError((object)$"Couldn't reopen the end menu: {arg}");
		}
		finally
		{
			bypass = false;
		}
	}
}
internal static class StatTracker
{
	[HarmonyPatch(typeof(HealthHandler), "DoDamage")]
	private static class DoDamagePatch
	{
		private static void Prefix(CharacterData ___data, out float __state)
		{
			__state = float.NaN;
			try
			{
				if ((Object)(object)___data != (Object)null && !___data.dead)
				{
					__state = ___data.health;
				}
			}
			catch
			{
			}
		}

		private static void Postfix(CharacterData ___data, Player damagingPlayer, float __state)
		{
			try
			{
				if (float.IsNaN(__state) || !Tracking || (Object)(object)___data == (Object)null)
				{
					return;
				}
				Player player = ___data.player;
				if ((Object)(object)player == (Object)null)
				{
					return;
				}
				float num = __state - Mathf.Max(___data.health, 0f);
				if (num > 0f && num < 100000f)
				{
					bool num2 = IsOpponent(damagingPlayer, player);
					bool flag = (Object)(object)damagingPlayer == (Object)null;
					if (num2 || flag)
					{
						Get(player.playerID).DamageTaken += num;
					}
					if (num2)
					{
						Get(damagingPlayer.playerID).Damage += num;
						lastEnemyHit[player.playerID] = new KeyValuePair<int, float>(damagingPlayer.playerID, Time.time);
					}
				}
			}
			catch
			{
			}
		}
	}

	[HarmonyPatch(typeof(HealthHandler), "RPCA_Die")]
	private static class DiePatch
	{
		private static void Prefix(CharacterData ___data)
		{
			CountKill(___data);
		}
	}

	[HarmonyPatch(typeof(HealthHandler), "RPCA_Die_Phoenix")]
	private static class DiePhoenixPatch
	{
		private static void Prefix(CharacterData ___data)
		{
			CountKill(___data);
		}
	}

	[HarmonyPatch(typeof(Gun), "BulletInit")]
	private static class BulletInitPatch
	{
		private static void Postfix(Gun __instance)
		{
			try
			{
				if (Tracking && !((Object)(object)__instance == (Object)null) && !((Object)(object)__instance.player == (Object)null))
				{
					Get(__instance.player.playerID).Shots++;
				}
			}
			catch
			{
			}
		}
	}

	[HarmonyPatch(typeof(ProjectileHit), "RPCA_DoHit")]
	private static class DoHitPatch
	{
		private static void Prefix(ProjectileHit __instance, int viewID, bool wasBlocked)
		{
			try
			{
				if (!Tracking || wasBlocked || viewID == -1 || (Object)(object)__instance == (Object)null)
				{
					return;
				}
				Player ownPlayer = __instance.ownPlayer;
				if ((Object)(object)ownPlayer == (Object)null)
				{
					return;
				}
				PhotonView photonView = PhotonNetwork.GetPhotonView(viewID);
				if (!((Object)(object)photonView == (Object)null))
				{
					Player victim = ((Component)photonView).GetComponent<Player>() ?? ((Component)photonView).GetComponentInParent<Player>();
					if (IsOpponent(ownPlayer, victim) && countedProjectiles.Add(((Object)__instance).GetInstanceID()))
					{
						Get(ownPlayer.playerID).Hits++;
					}
				}
			}
			catch
			{
			}
		}
	}

	private static readonly Dictionary<int, PlayerStats> stats = new Dictionary<int, PlayerStats>();

	private static readonly HashSet<int> countedProjectiles = new HashSet<int>();

	private static readonly Dictionary<int, KeyValuePair<int, float>> lastEnemyHit = new Dictionary<int, KeyValuePair<int, float>>();

	private static int fights;

	private const float KillCreditWindow = 5f;

	internal static bool Tracking
	{
		get
		{
			try
			{
				return (Object)(object)GameManager.instance != (Object)null && GameManager.instance.isPlaying && GameModeManager.CurrentHandlerID != "Sandbox";
			}
			catch
			{
				return false;
			}
		}
	}

	internal static void Reset()
	{
		stats.Clear();
		countedProjectiles.Clear();
		lastEnemyHit.Clear();
		fights = 0;
	}

	internal static void FightEnded()
	{
		try
		{
			if (Tracking)
			{
				foreach (Player player in PlayerManager.instance.players)
				{
					if ((Object)(object)player != (Object)null && (Object)(object)player.data != (Object)null && !player.data.dead)
					{
						Get(player.playerID).LastStanding++;
					}
				}
			}
		}
		catch
		{
		}
		fights++;
		countedProjectiles.Clear();
		lastEnemyHit.Clear();
	}

	internal static BoardData TakeSnapshot(int round)
	{
		BoardData boardData = new BoardData
		{
			Round = round,
			Fights = Math.Max(1, fights),
			FromHost = false
		};
		try
		{
			foreach (Player player in PlayerManager.instance.players)
			{
				if (!((Object)(object)player == (Object)null))
				{
					boardData.Players.Add(Get(player.playerID).Clone());
				}
			}
			foreach (KeyValuePair<int, PlayerStats> kv in stats)
			{
				if (!boardData.Players.Exists((PlayerStats s) => s.PlayerId == kv.Key))
				{
					boardData.Players.Add(kv.Value.Clone());
				}
			}
		}
		catch (Exception arg)
		{
			Scoreboard.Log.LogError((object)$"Snapshot failed: {arg}");
		}
		Reset();
		return boardData;
	}

	private static PlayerStats Get(int playerId)
	{
		if (!stats.TryGetValue(playerId, out var value))
		{
			value = new PlayerStats
			{
				PlayerId = playerId
			};
			stats[playerId] = value;
		}
		return value;
	}

	private static bool IsOpponent(Player attacker, Player victim)
	{
		if ((Object)(object)attacker != (Object)null && (Object)(object)victim != (Object)null && (Object)(object)attacker != (Object)(object)victim)
		{
			return attacker.teamID != victim.teamID;
		}
		return false;
	}

	private static void CountKill(CharacterData data)
	{
		try
		{
			if (!Tracking || (Object)(object)data == (Object)null || data.dead || !data.isPlaying)
			{
				return;
			}
			Player player = data.player;
			if (!((Object)(object)player == (Object)null))
			{
				Player lastSourceOfDamage = data.lastSourceOfDamage;
				KeyValuePair<int, float> value;
				if (IsOpponent(lastSourceOfDamage, player))
				{
					Get(lastSourceOfDamage.playerID).Kills++;
				}
				else if (lastEnemyHit.TryGetValue(player.playerID, out value) && Time.time - value.Value <= 5f)
				{
					Get(value.Key).Kills++;
				}
				lastEnemyHit.Remove(player.playerID);
			}
		}
		catch
		{
		}
	}
}
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInPlugin("com.zen.rounds.scoreboard", "Scoreboard", "1.0.0")]
[BepInProcess("Rounds.exe")]
public class Scoreboard : BaseUnityPlugin
{
	[Serializable]
	[CompilerGenerated]
	private sealed class <>c
	{
		public static readonly <>c <>9 = new <>c();

		public static UnityAction <>9__18_0;

		public static UnityAction<bool> <>9__19_0;

		public static UnityAction<float> <>9__19_4;

		public static UnityAction<bool> <>9__19_1;

		public static UnityAction<float> <>9__19_5;

		public static UnityAction <>9__19_2;

		public static UnityAction <>9__19_3;

		internal void <Start>b__18_0()
		{
		}

		internal void <BuildMenu>b__19_0(bool v)
		{
			Enabled.Value = v;
		}

		internal void <BuildMenu>b__19_4(float v)
		{
			Duration.Value = Mathf.Round(v);
		}

		internal void <BuildMenu>b__19_1(bool v)
		{
			ShowFinal.Value = v;
		}

		internal void <BuildMenu>b__19_5(float v)
		{
			FinalDuration.Value = Mathf.Round(v);
		}

		internal void <BuildMenu>b__19_2()
		{
			ScoreboardUI.Preview(final: false);
		}

		internal void <BuildMenu>b__19_3()
		{
			ScoreboardUI.Preview(final: true);
		}
	}

	public const string ModId = "com.zen.rounds.scoreboard";

	public const string ModName = "Scoreboard";

	public const string Version = "1.0.0";

	public const string ModInitials = "Zen";

	internal static ConfigEntry<bool> Enabled;

	internal static ConfigEntry<float> Duration;

	internal static ConfigEntry<bool> ShowFinal;

	internal static ConfigEntry<float> FinalDuration;

	private Harmony harmony;

	internal static Scoreboard Instance { get; private set; }

	internal static ManualLogSource Log { get; private set; }

	private void Awake()
	{
		//IL_005f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0069: Expected O, but got Unknown
		//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c6: Expected O, but got Unknown
		//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00db: Expected O, but got Unknown
		Instance = this;
		Log = ((BaseUnityPlugin)this).Logger;
		Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Show the scoreboard before each card pick. When you host, your setting decides for the whole lobby.");
		Duration = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Duration", 5f, new ConfigDescription("Seconds the scoreboard stays up. When you host, your setting decides for the whole lobby.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(3f, 10f), Array.Empty<object>()));
		ShowFinal = ((BaseUnityPlugin)this).Config.Bind<bool>("Game end", "ShowTotals", true, "Show totals for the whole game before the victory / rematch screen. When you host, your setting decides for the whole lobby.");
		FinalDuration = ((BaseUnityPlugin)this).Config.Bind<float>("Game end", "Duration", 8f, new ConfigDescription("Seconds the game totals stay up. When you host, your setting decides for the whole lobby.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(3f, 15f), Array.Empty<object>()));
		try
		{
			harmony = new Harmony("com.zen.rounds.scoreboard");
			harmony.PatchAll(typeof(Scoreboard).Assembly);
		}
		catch (Exception arg)
		{
			Log.LogError((object)$"Couldn't patch stat tracking: {arg}");
		}
		((Component)this).gameObject.AddComponent<ScoreboardUI>();
	}

	private void Start()
	{
		//IL_0065: Unknown result type (might be due to invalid IL or missing references)
		//IL_006a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0070: Expected O, but got Unknown
		BoardSync.Register();
		if (harmony != null)
		{
			RwfEndScreen.TryPatch(harmony);
		}
		Unbound.RegisterCredits("Scoreboard", new string[1] { "Zen" }, new string[1] { "Thunderstore" }, new string[1] { "https://thunderstore.io/c/rounds/p/Zenith/" });
		object obj = <>c.<>9__18_0;
		if (obj == null)
		{
			UnityAction val = delegate
			{
			};
			<>c.<>9__18_0 = val;
			obj = (object)val;
		}
		Unbound.RegisterMenu("Scoreboard", (UnityAction)obj, (Action<GameObject>)BuildMenu, (GameObject)null, true);
	}

	private static void BuildMenu(GameObject menu)
	{
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0233: Unknown result type (might be due to invalid IL or missing references)
		//IL_0238: Unknown result type (might be due to invalid IL or missing references)
		//IL_023e: Expected O, but got Unknown
		//IL_02cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_0275: Unknown result type (might be due to invalid IL or missing references)
		//IL_027a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0280: Expected O, but got Unknown
		TextMeshProUGUI val = default(TextMeshProUGUI);
		MenuHandler.CreateText("Scoreboard", menu, ref val, 60, false, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null);
		MenuHandler.CreateText("Kills, damage, accuracy and MVP before every card pick", menu, ref val, 25, false, (Color?)Color.gray, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null);
		MenuHandler.CreateText(" ", menu, ref val, 15, true, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null);
		MenuHandler.CreateToggle(Enabled.Value, "Show scoreboard", menu, (UnityAction<bool>)delegate(bool v)
		{
			Enabled.Value = v;
		}, 40, false, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null);
		Slider val2 = default(Slider);
		MenuHandler.CreateSlider("Seconds on screen", menu, 30, 3f, 10f, Duration.Value, (UnityAction<float>)delegate(float v)
		{
			Duration.Value = Mathf.Round(v);
		}, ref val2, true, (Color?)null, (Direction)0, false, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null);
		MenuHandler.CreateToggle(ShowFinal.Value, "Show game totals at the end", menu, (UnityAction<bool>)delegate(bool v)
		{
			ShowFinal.Value = v;
		}, 40, false, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null);
		MenuHandler.CreateSlider("Game totals seconds", menu, 30, 3f, 15f, FinalDuration.Value, (UnityAction<float>)delegate(float v)
		{
			FinalDuration.Value = Mathf.Round(v);
		}, ref val2, true, (Color?)null, (Direction)0, false, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null);
		MenuHandler.CreateText("The host's settings are used for the whole lobby.", menu, ref val, 22, false, (Color?)Color.gray, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null);
		MenuHandler.CreateText(" ", menu, ref val, 15, true, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null);
		object obj = <>c.<>9__19_2;
		if (obj == null)
		{
			UnityAction val3 = delegate
			{
				ScoreboardUI.Preview(final: false);
			};
			<>c.<>9__19_2 = val3;
			obj = (object)val3;
		}
		MenuHandler.CreateButton("Preview", menu, (UnityAction)obj, 35, false, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null);
		object obj2 = <>c.<>9__19_3;
		if (obj2 == null)
		{
			UnityAction val4 = delegate
			{
				ScoreboardUI.Preview(final: true);
			};
			<>c.<>9__19_3 = val4;
			obj2 = (object)val4;
		}
		MenuHandler.CreateButton("Preview game totals", menu, (UnityAction)obj2, 35, false, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null);
		MenuHandler.CreateText(" ", menu, ref val, 15, true, (Color?)null, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null);
		MenuHandler.CreateText("Made by Zen", menu, ref val, 20, false, (Color?)Color.gray, (TMP_FontAsset)null, (Material)null, (TextAlignmentOptions?)null);
	}
}
public class ScoreboardUI : MonoBehaviour
{
	private struct PlayerView
	{
		public string Name;

		public string TeamName;

		public string Initial;

		public Color Color;

		public bool Local;

		internal static PlayerView Get(int playerId)
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			PlayerView result = new PlayerView
			{
				Name = "Player " + (playerId + 1),
				TeamName = "Left",
				Color = new Color(0.45f, 0.48f, 0.55f, 1f)
			};
			Player val = null;
			try
			{
				val = PlayerManager.instance?.players?.FirstOrDefault((Func<Player, bool>)((Player x) => (Object)(object)x != (Object)null && x.playerID == playerId));
			}
			catch
			{
			}
			if ((Object)(object)val != (Object)null)
			{
				bool flag = IsBot(val);
				try
				{
					result.Local = !flag && (Object)(object)val.data != (Object)null && (Object)(object)val.data.view != (Object)null && val.data.view.IsMine;
				}
				catch
				{
				}
				result.Name = (flag ? ("Bot " + (playerId + 1)) : (NetworkName(val) ?? result.Name));
				int num = val.teamID;
				try
				{
					num = PlayerExtensions.colorID(val);
				}
				catch
				{
				}
				try
				{
					PlayerSkin playerSkinColors = ExtraPlayerSkins.GetPlayerSkinColors(num);
					if ((Object)(object)playerSkinColors != (Object)null)
					{
						result.Color = playerSkinColors.winText;
						result.Color.a = 1f;
					}
				}
				catch
				{
				}
				try
				{
					result.TeamName = ExtraPlayerSkins.GetTeamColorName(num);
				}
				catch
				{
					result.TeamName = "Team " + (val.teamID + 1);
				}
				if (string.IsNullOrEmpty(result.TeamName))
				{
					result.TeamName = "Team " + (val.teamID + 1);
				}
			}
			result.Name = result.Name.Trim();
			if (result.Name.Length > 28)
			{
				result.Name = result.Name.Substring(0, 28);
			}
			result.Initial = InitialOf(result.Name);
			return result;
		}

		private static string NetworkName(Player p)
		{
			try
			{
				if (PhotonNetwork.OfflineMode)
				{
					return null;
				}
				CharacterData data = p.data;
				object obj;
				if (data == null)
				{
					obj = null;
				}
				else
				{
					PhotonView view = data.view;
					if (view == null)
					{
						obj = null;
					}
					else
					{
						Player owner = view.Owner;
						obj = ((owner != null) ? owner.NickName : null);
					}
				}
				string text = (string)obj;
				return string.IsNullOrWhiteSpace(text) ? null : text;
			}
			catch
			{
				return null;
			}
		}

		private static bool IsBot(Player p)
		{
			try
			{
				MonoBehaviour[] componentsInChildren = ((Component)p).GetComponentsInChildren<MonoBehaviour>(true);
				foreach (MonoBehaviour val in componentsInChildren)
				{
					if ((Object)(object)val != (Object)null && ((object)val).GetType().Name.StartsWith("PlayerAI", StringComparison.Ordinal))
					{
						return true;
					}
				}
			}
			catch
			{
			}
			return false;
		}

		private static string InitialOf(string name)
		{
			string text = name ?? "";
			foreach (char c in text)
			{
				if (!char.IsLetterOrDigit(c))
				{
					continue;
				}
				char c2 = char.ToUpperInvariant(c);
				try
				{
					if ((Object)(object)UIKit.Font != (Object)null && !UIKit.Font.HasCharacter(c2))
					{
						continue;
					}
				}
				catch
				{
				}
				return c2.ToString();
			}
			return "?";
		}
	}

	private static readonly Color Bg = Hex("#0F131B", 0.97f);

	private static readonly Color Surf = Hex("#171C26");

	private static readonly Color Surf2 = Hex("#202736");

	private static readonly Color Line = Hex("#2B3344");

	private static readonly Color TextCol = Hex("#E8ECF4");

	private static readonly Color Dim = Hex("#B9C1D0");

	private static readonly Color Muted = Hex("#8F99AB");

	private static readonly Color Accent = Hex("#7FA2FF");

	private static readonly Color AccText = Hex("#0F131B");

	private static readonly Color Gold = Hex("#F5C542");

	private static readonly Color GoldFill = Hex("#211E16");

	private static readonly Color AvatarText = new Color(0.07f, 0.07f, 0.07f, 1f);

	private const int ListPad = 20;

	private const int RowPadL = 14;

	private const int RowRightInset = 44;

	private const float ColKills = 96f;

	private const float ColDamage = 120f;

	private const float ColTaken = 120f;

	private const float ColStanding = 136f;

	private const float ColAcc = 150f;

	private GameObject canvasGO;

	private RectTransform root;

	private CanvasGroup rootGroup;

	private RectTransform panel;

	private RectTransform countdownFill;

	private TextMeshProUGUI countdownText;

	private readonly List<CanvasGroup> rowGroups = new List<CanvasGroup>();

	private Coroutine anim;

	private float shownAt;

	private float duration;

	private bool visible;

	internal static ScoreboardUI Instance { get; private set; }

	private void Awake()
	{
		Instance = this;
	}

	internal static void Show(BoardData board, float seconds)
	{
		try
		{
			Instance?.Build(board, seconds);
		}
		catch (Exception arg)
		{
			Scoreboard.Log.LogError((object)$"Scoreboard UI failed: {arg}");
			SafeHide();
		}
	}

	internal static void SafeHide()
	{
		try
		{
			Instance?.Hide();
		}
		catch
		{
		}
	}

	internal static void Preview(bool final)
	{
		try
		{
			BoardData boardData = new BoardData
			{
				Round = (final ? 4 : 2),
				Fights = (final ? 11 : 3),
				Duration = 5f,
				FromHost = true,
				IsFinal = final
			};
			float num = (final ? Scoreboard.FinalDuration.Value : 5f);
			List<int> list = (((Object)(object)PlayerManager.instance != (Object)null) ? (from p in PlayerManager.instance.players
				where (Object)(object)p != (Object)null
				select p.playerID).ToList() : new List<int>());
			if (list.Count == 0)
			{
				list = new List<int> { 0, 1, 2, 3 };
			}
			Random random = new Random(7);
			foreach (int item in list)
			{
				int num2 = random.Next(18, 60);
				int num3 = ((!final) ? 1 : 4);
				boardData.Players.Add(new PlayerStats
				{
					PlayerId = item,
					Kills = random.Next(0, 4) * num3,
					Damage = random.Next(40, 420) * num3,
					Shots = num2 * num3,
					Hits = random.Next(4, num2) * num3,
					DamageTaken = random.Next(60, 380) * num3,
					LastStanding = random.Next(0, 3) * num3
				});
			}
			Show(boardData, num);
			ScoreboardUI instance = Instance;
			if (instance != null)
			{
				((MonoBehaviour)instance).StartCoroutine(Instance.AutoHide(num));
			}
		}
		catch (Exception ex)
		{
			Scoreboard.Log.LogError((object)ex);
		}
	}

	private IEnumerator AutoHide(float t)
	{
		yield return (object)new WaitForSecondsRealtime(t);
		if (!BoardSync.Waiting)
		{
			SafeHide();
		}
	}

	private void Build(BoardData board, float seconds)
	{
		//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f4: 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)
		//IL_011a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0124: Expected O, but got Unknown
		//IL_0141: Unknown result type (might be due to invalid IL or missing references)
		//IL_0148: Unknown result type (might be due to invalid IL or missing references)
		//IL_015f: Unknown result type (might be due to invalid IL or missing references)
		//IL_018f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0232: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d3: Unknown result type (might be due to invalid IL or missing references)
		//IL_032d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0368: Unknown result type (might be due to invalid IL or missing references)
		//IL_03b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_03ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_0412: Unknown result type (might be due to invalid IL or missing references)
		//IL_0422: Unknown result type (might be due to invalid IL or missing references)
		//IL_0438: Unknown result type (might be due to invalid IL or missing references)
		//IL_043d: Unknown result type (might be due to invalid IL or missing references)
		//IL_043e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0445: Unknown result type (might be due to invalid IL or missing references)
		//IL_0b23: Unknown result type (might be due to invalid IL or missing references)
		//IL_0b70: Unknown result type (might be due to invalid IL or missing references)
		//IL_0662: Unknown result type (might be due to invalid IL or missing references)
		//IL_065b: Unknown result type (might be due to invalid IL or missing references)
		//IL_068c: Unknown result type (might be due to invalid IL or missing references)
		//IL_071b: Unknown result type (might be due to invalid IL or missing references)
		//IL_075b: Unknown result type (might be due to invalid IL or missing references)
		//IL_07a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_067b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0685: Unknown result type (might be due to invalid IL or missing references)
		//IL_0674: Unknown result type (might be due to invalid IL or missing references)
		//IL_086a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0912: Unknown result type (might be due to invalid IL or missing references)
		//IL_096d: Unknown result type (might be due to invalid IL or missing references)
		//IL_08d8: Unknown result type (might be due to invalid IL or missing references)
		EnsureCanvas();
		ClearPanel();
		duration = Mathf.Max(0.5f, seconds);
		shownAt = Time.realtimeSinceStartup;
		visible = true;
		List<PlayerStats> list = board.Sorted();
		int mvpId = board.MvpId;
		int count = list.Count;
		float num = ((count <= 6) ? 68f : ((count <= 10) ? 54f : 42f));
		float size = ((count <= 6) ? 21f : ((count <= 10) ? 18f : 16f));
		float size2 = ((count <= 6) ? 22f : ((count <= 10) ? 19f : 17f));
		float num2 = num - 22f;
		UIKit.Stretch(((Graphic)UIKit.Box((Transform)(object)root, new Color(0f, 0f, 0f, 0.5f), 0, "Dim")).rectTransform);
		Image val = UIKit.Bordered((Transform)(object)root, Bg, Line, 16, 1, "Panel");
		panel = (RectTransform)((Component)val).transform.parent;
		RectTransform obj = panel;
		RectTransform obj2 = panel;
		Vector2 val2 = default(Vector2);
		((Vector2)(ref val2))..ctor(0.5f, 0.5f);
		obj2.anchorMax = val2;
		obj.anchorMin = val2;
		panel.pivot = new Vector2(0.5f, 0.5f);
		((Component)panel).gameObject.AddComponent<ContentSizeFitter>().verticalFit = (FitMode)2;
		panel.sizeDelta = new Vector2(1060f, 0f);
		UIKit.VL((Component)(object)val, 0f, 0, 0, 0, 0, (TextAnchor)0);
		RectTransform obj3 = UIKit.Rect(((Component)val).transform, "Header");
		UIKit.HL((Component)(object)obj3, 16f, 28, 28, 22, 18, (TextAnchor)3);
		RectTransform obj4 = UIKit.Rect((Transform)(object)obj3, "Titles");
		UIKit.VL((Component)(object)obj4, 4f, 0, 0, 0, 0, (TextAnchor)3);
		UIKit.LE((Component)(object)obj4, -1f, -1f, 1f);
		((TMP_Text)UIKit.Text((Transform)(object)obj4, board.IsFinal ? "FINAL SCOREBOARD" : "SCOREBOARD", 28f, TextCol, (FontStyles)1, (TextAlignmentOptions)4097, "Title")).characterSpacing = 8f;
		string text = string.Format("{0} {1}", board.Fights, (board.Fights == 1) ? "FIGHT" : "FIGHTS");
		string text2 = (board.IsFinal ? string.Format("GAME OVER   ·   {0} {1}   ·   {2}", board.Round, (board.Round == 1) ? "ROUND" : "ROUNDS", text) : $"ROUND {board.Round}   ·   {text}");
		((TMP_Text)UIKit.Text((Transform)(object)obj4, text2, 13f, Muted, (FontStyles)1, (TextAlignmentOptions)4097, "Subtitle")).characterSpacing = 4f;
		RectTransform val3 = UIKit.Rect((Transform)(object)obj3, "Timer");
		UIKit.VL((Component)(object)val3, 2f, 0, 0, 0, 0, (TextAnchor)5, expandW: false);
		((TMP_Text)UIKit.Text((Transform)(object)val3, board.IsFinal ? "CONTINUE IN" : "CARD PICK IN", 11f, Muted, (FontStyles)1, (TextAlignmentOptions)4100, "Next")).characterSpacing = 4f;
		countdownText = UIKit.Text((Transform)(object)val3, Mathf.CeilToInt(duration).ToString(), 30f, Accent, (FontStyles)1, (TextAlignmentOptions)4100, "Count");
		UIKit.LE((Component)(object)countdownText, 120f, 120f, 0f);
		Image obj5 = UIKit.Box(((Component)val).transform, Line, 0, "Track");
		UIKit.LE((Component)(object)obj5, -1f, -1f, -1f, 3f, 3f);
		Image val4 = UIKit.Box(((Component)obj5).transform, Accent, 0, "Fill");
		countdownFill = ((Graphic)val4).rectTransform;
		countdownFill.anchorMin = Vector2.zero;
		countdownFill.anchorMax = Vector2.one;
		val2 = (countdownFill.offsetMin = (countdownFill.offsetMax = Vector2.zero));
		RectTransform val6 = UIKit.Rect(((Component)val).transform, "Columns");
		UIKit.HL((Component)(object)val6, 0f, 35, 44, 14, 6, (TextAnchor)3);
		ColumnLabel((Transform)(object)val6, "PLAYER", -1f, (TextAlignmentOptions)4097, flex: true);
		Transform parent = StatsGroup((Transform)(object)val6);
		ColumnLabel(parent, "KILLS", 96f, (TextAlignmentOptions)514);
		ColumnLabel(parent, "DMG DEALT", 120f, (TextAlignmentOptions)514);
		ColumnLabel(parent, "DMG TAKEN", 120f, (TextAlignmentOptions)514);
		ColumnLabel(parent, "LAST STANDING", 136f, (TextAlignmentOptions)514);
		ColumnLabel(parent, "ACCURACY", 150f, (TextAlignmentOptions)514);
		RectTransform val7 = UIKit.Rect(((Component)val).transform, "Rows");
		UIKit.VL((Component)(object)val7, (count <= 6) ? 8 : 5, 20, 20, 4, 8, (TextAnchor)0);
		int num3 = ((list.Count > 0) ? list.Max((PlayerStats r) => r.Kills) : 0);
		float num4 = ((list.Count > 0) ? list.Max((PlayerStats r) => r.Damage) : 0f);
		float num5 = ((list.Count > 0) ? list.Max((PlayerStats r) => r.Accuracy) : (-1f));
		int num6 = ((list.Count > 0) ? list.Max((PlayerStats r) => r.LastStanding) : 0);
		rowGroups.Clear();
		foreach (PlayerStats item in list)
		{
			PlayerView playerView = PlayerView.Get(item.PlayerId);
			bool flag = item.PlayerId == mvpId;
			int num7 = ((!flag) ? 1 : 2);
			Image obj6 = UIKit.Bordered((Transform)(object)val7, flag ? GoldFill : Surf, flag ? Gold : (playerView.Local ? (Accent * 0.75f) : Line), 12, num7, "Row");
			UIKit.LE((Component)(object)((Component)((Component)obj6).transform.parent).GetComponent<RectTransform>(), -1f, -1f, -1f, num, num);
			CanvasGroup val8 = ((Component)((Component)obj6).transform.parent).gameObject.AddComponent<CanvasGroup>();
			val8.alpha = 0f;
			rowGroups.Add(val8);
			UIKit.HL((Component)(object)obj6, 14f, 14, 24 - num7, 0, 0, (TextAnchor)3);
			UIKit.LE((Component)(object)UIKit.Box(((Component)obj6).transform, playerView.Color, 2, "Stripe"), 4f, 4f, 0f, num - 26f, num - 26f, 0f);
			Image obj7 = UIKit.Box(((Component)obj6).transform, playerView.Color, Mathf.RoundToInt(num2 * 0.22f), "Avatar");
			UIKit.LE((Component)(object)obj7, num2, num2, 0f, num2, num2, 0f);
			UIKit.Stretch(((TMP_Text)UIKit.Text(((Component)obj7).transform, playerView.Initial, num2 * 0.52f, AvatarText, (FontStyles)1, (TextAlignmentOptions)514, "Initial")).rectTransform);
			RectTransform obj8 = UIKit.Rect(((Component)obj6).transform, "NameCell");
			UIKit.VL((Component)(object)obj8, 1f, 0, 0, 0, 0, (TextAnchor)3);
			UIKit.LE((Component)(object)obj8, 80f, -1f, 1f);
			RectTransform val9 = UIKit.Rect((Transform)(object)obj8, "Top");
			UIKit.HL((Component)(object)val9, 6f, 0, 0, 0, 0, (TextAnchor)3);
			if (flag)
			{
				RectTransform obj9 = UIKit.Rect((Transform)(object)val9, "Crown");
				Image obj10 = ((Component)obj9).gameObject.AddComponent<Image>();
				obj10.sprite = UIKit.Crown();
				((Graphic)obj10).color = Gold;
				((Graphic)obj10).raycastTarget = false;
				obj10.preserveAspect = true;
				float num8 = ((count <= 6) ? 16f : 13f);
				UIKit.LE((Component)(object)obj9, num8 * 1.5f, num8 * 1.5f, 0f, num8, num8, 0f);
				((TMP_Text)UIKit.Text((Transform)(object)val9, board.IsFinal ? "GAME MVP" : "MVP", (count <= 6) ? 12 : 11, Gold, (FontStyles)1, (TextAlignmentOptions)4097, "Mvp")).characterSpacing = 4f;
			}
			else
			{
				((TMP_Text)UIKit.Text((Transform)(object)val9, playerView.TeamName.ToUpperInvariant(), (count <= 6) ? 11 : 10, Muted, (FontStyles)1, (TextAlignmentOptions)4097, "Team")).characterSpacing = 3f;
			}
			UIKit.Spacer((Transform)(object)val9);
			RectTransform val10 = UIKit.Rect((Transform)(object)obj8, "NameLine");
			UIKit.HL((Component)(object)val10, 8f, 0, 0, 0, 0, (TextAnchor)3);
			UIKit.LE((Component)(object)UIKit.Text((Transform)(object)val10, playerView.Name, size, TextCol, (FontStyles)1, (TextAlignmentOptions)4097, "Name"), 30f, -1f, 0f);
			if (playerView.Local)
			{
				Tag((Transform)(object)val10, "YOU");
			}
			UIKit.Spacer((Transform)(object)val10);
			Transform parent2 = StatsGroup(((Component)obj6).transform);
			Stat(parent2, item.Kills.ToString(), 96f, size2, item.Kills == num3 && num3 > 0);
			Stat(parent2, Mathf.RoundToInt(item.Damage).ToString(), 120f, size2, item.Damage >= num4 - 0.5f && num4 > 0f);
			Stat(parent2, Mathf.RoundToInt(item.DamageTaken).ToString(), 120f, size2, leader: false);
			Stat(parent2, item.LastStanding.ToString(), 136f, size2, item.LastStanding == num6 && num6 > 0);
			AccuracyCell(parent2, item.Accuracy, size2, item.Accuracy >= 0f && item.Accuracy >= num5 - 0.0001f);
		}
		RectTransform val11 = UIKit.Rect(((Component)val).transform, "Footer");
		UIKit.HL((Component)(object)val11, 12f, 28, 28, 4, 18, (TextAnchor)3);
		UIKit.LE((Component)(object)UIKit.Text((Transform)(object)val11, "MVP = 100 per kill + damage dealt", 12f, Muted, (FontStyles)0, (TextAlignmentOptions)4097, "How"), -1f, -1f, 1f);
		if (!board.FromHost)
		{
			((TMP_Text)UIKit.Text((Transform)(object)val11, "LOCAL STATS", 11f, Muted, (FontStyles)1, (TextAlignmentOptions)4100, "Source")).characterSpacing = 3f;
		}
		if (anim != null)
		{
			((MonoBehaviour)this).StopCoroutine(anim);
		}
		anim = ((MonoBehaviour)this).StartCoroutine(Animate());
	}

	private static Transform StatsGroup(Transform parent)
	{
		RectTransform obj = UIKit.Rect(parent, "Stats");
		UIKit.HL((Component)(object)obj, 0f, 0, 0, 0, 0, (TextAnchor)4);
		UIKit.LE((Component)(object)obj, 622f, 622f, 0f);
		return (Transform)(object)obj;
	}

	private void ColumnLabel(Transform parent, string text, float width, TextAlignmentOptions align, bool flex = false)
	{
		//IL_0007: 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)
		TextMeshProUGUI val = UIKit.Text(parent, text, 11f, Muted, (FontStyles)1, align, "Col");
		((TMP_Text)val).characterSpacing = 4f;
		if (flex)
		{
			UIKit.LE((Component)(object)val, 80f, -1f, 1f);
		}
		else
		{
			UIKit.LE((Component)(object)val, width, width, 0f);
		}
	}

	private void Stat(Transform parent, string value, float width, float size, bool leader)
	{
		//IL_000f: 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)
		UIKit.LE((Component)(object)UIKit.Text(parent, value, size, leader ? Color.white : Dim, (FontStyles)1, (TextAlignmentOptions)514, "Stat"), width, width, 0f);
	}

	private void AccuracyCell(Transform parent, float acc, float size, bool leader)
	{
		//IL_008e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_0087: 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_0116: 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_012c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0142: Unknown result type (might be due to invalid IL or missing references)
		//IL_014d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0152: Unknown result type (might be due to invalid IL or missing references)
		//IL_0153: Unknown result type (might be due to invalid IL or missing references)
		//IL_0159: Unknown result type (might be due to invalid IL or missing references)
		RectTransform obj = UIKit.Rect(parent, "Accuracy");
		UIKit.VL((Component)(object)obj, 5f, 0, 0, 0, 0, (TextAnchor)4, expandW: false);
		UIKit.LE((Component)(object)obj, 150f, 150f, 0f);
		string text = ((acc < 0f) ? "—" : (Mathf.RoundToInt(acc * 100f) + "%"));
		UIKit.LE((Component)(object)UIKit.Text((Transform)(object)obj, text, size, (acc < 0f) ? Muted : (leader ? Color.white : Dim), (FontStyles)1, (TextAlignmentOptions)514, "Value"), 110f, 110f, 0f);
		Image val = UIKit.Box((Transform)(object)obj, Line, 2, "Bar");
		UIKit.LE((Component)(object)val, 90f, 90f, 0f, 4f, 4f, 0f);
		if (acc > 0f)
		{
			RectTransform rectTransform = ((Graphic)UIKit.Box(((Component)val).transform, leader ? Accent : Muted, 2, "Fill")).rectTransform;
			rectTransform.anchorMin = Vector2.zero;
			rectTransform.anchorMax = new Vector2(Mathf.Clamp01(acc), 1f);
			Vector2 offsetMin = (rectTransform.offsetMax = Vector2.zero);
			rectTransform.offsetMin = offsetMin;
		}
	}

	private void Tag(Transform parent, string text)
	{
		//IL_0001: 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)
		Image obj = UIKit.Box(parent, Accent, 5, "Tag");
		UIKit.HL((Component)(object)obj, 0f, 7, 7, 2, 2, (TextAnchor)4);
		((TMP_Text)UIKit.Text(((Component)obj).transform, text, 11f, AccText, (FontStyles)1, (TextAlignmentOptions)514, "TagText")).characterSpacing = 3f;
	}

	private IEnumerator Animate()
	{
		rootGroup.alpha = 0f;
		float t = 0f;
		while (t < 1f)
		{
			t = Mathf.Clamp01((Time.realtimeSinceStartup - shownAt) / 0.22f);
			float num = 1f - (1f - t) * (1f - t);
			rootGroup.alpha = num;
			if ((Object)(object)panel != (Object)null)
			{
				((Transform)panel).localScale = Vector3.one * Mathf.Lerp(0.96f, 1f, num);
			}
			Tick();
			yield return null;
		}
		for (int i = 0; i < rowGroups.Count; i++)
		{
			((MonoBehaviour)this).StartCoroutine(FadeRow(rowGroups[i], (float)i * 0.05f));
		}
		while (visible)
		{
			Tick();
			yield return null;
		}
	}

	private IEnumerator FadeRow(CanvasGroup g, float delay)
	{
		float start = Time.realtimeSinceStartup + delay;
		while ((Object)(object)g != (Object)null)
		{
			float num = Mathf.Clamp01((Time.realtimeSinceStartup - start) / 0.2f);
			g.alpha = 1f - (1f - num) * (1f - num);
			if (num >= 1f)
			{
				break;
			}
			yield return null;
		}
	}

	private void Tick()
	{
		//IL_006b: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			float num = Mathf.Max(0f, duration - (Time.realtimeSinceStartup - shownAt));
			if ((Object)(object)countdownText != (Object)null)
			{
				((TMP_Text)countdownText).text = Mathf.CeilToInt(num).ToString();
			}
			if ((Object)(object)countdownFill != (Object)null)
			{
				countdownFill.anchorMax = new Vector2(Mathf.Clamp01(num / duration), 1f);
			}
		}
		catch
		{
		}
	}

	private void Hide()
	{
		if (visible && !((Object)(object)rootGroup == (Object)null))
		{
			visible = false;
			if (anim != null)
			{
				((MonoBehaviour)this).StopCoroutine(anim);
			}
			anim = ((MonoBehaviour)this).StartCoroutine(FadeOut());
		}
	}

	private IEnumerator FadeOut()
	{
		float start = Time.realtimeSinceStartup;
		float from = rootGroup.alpha;
		while (true)
		{
			float num = Mathf.Clamp01((Time.realtimeSinceStartup - start) / 0.18f);
			rootGroup.alpha = Mathf.Lerp(from, 0f, num);
			if (num >= 1f)
			{
				break;
			}
			yield return null;
		}
		ClearPanel();
	}

	private void EnsureCanvas()
	{
		//IL_0080: Unknown result type (might be due to invalid IL or missing references)
		//IL_008a: Expected O, but got Unknown
		//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)UIKit.Font == (Object)null)
		{
			UIKit.Font = FindFont(bold: false);
		}
		if ((Object)(object)UIKit.BoldFont == (Object)null)
		{
			UIKit.BoldFont = FindFont(bold: true);
		}
		if (!((Object)(object)canvasGO != (Object)null) || !((Object)(object)root != (Object)null))
		{
			canvasGO = new GameObject("Scoreboard Canvas", new Type[3]
			{
				typeof(RectTransform),
				typeof(Canvas),
				typeof(CanvasScaler)
			});
			Canvas component = canvasGO.GetComponent<Canvas>();
			component.renderMode = (RenderMode)0;
			component.sortingOrder = 29000;
			CanvasScaler component2 = canvasGO.GetComponent<CanvasScaler>();
			component2.uiScaleMode = (ScaleMode)1;
			component2.referenceResolution = new Vector2(1920f, 1080f);
			component2.matchWidthOrHeight = 0.5f;
			Object.DontDestroyOnLoad((Object)(object)canvasGO);
			root = UIKit.Rect(canvasGO.transform, "Root");
			UIKit.Stretch(root);
			rootGroup = ((Component)root).gameObject.AddComponent<CanvasGroup>();
			rootGroup.alpha = 0f;
			rootGroup.interactable = false;
			rootGroup.blocksRaycasts = false;
		}
	}

	private void ClearPanel()
	{
		rowGroups.Clear();
		panel = null;
		countdownFill = null;
		countdownText = null;
		if (!((Object)(object)root == (Object)null))
		{
			for (int num = ((Transform)root).childCount - 1; num >= 0; num--)
			{
				Object.Destroy((Object)(object)((Component)((Transform)root).GetChild(num)).gameObject);
			}
			if ((Object)(object)rootGroup != (Object)null)
			{
				rootGroup.alpha = 0f;
			}
		}
	}

	private static TMP_FontAsset FindFont(bool bold)
	{
		string[] array = ((!bold) ? new string[3] { "Gravity-Book SDF", "Gravity-Regular SDF", "Gravity-Bold SDF" } : new string[3] { "Gravity-Bold SDF", "Gravity-Regular SDF", "Gravity-Book SDF" });
		try
		{
			TMP_FontAsset[] source = Resources.FindObjectsOfTypeAll<TMP_FontAsset>();
			string[] array2 = array;
			foreach (string name in array2)
			{
				TMP_FontAsset val = ((IEnumerable<TMP_FontAsset>)source).FirstOrDefault((Func<TMP_FontAsset, bool>)((TMP_FontAsset a) => (Object)(object)a != (Object)null && ((Object)a).name == name));
				if ((Object)(object)val != (Object)null)
				{
					return val;
				}
			}
			TMP_FontAsset val2 = ((IEnumerable<TMP_FontAsset>)source).FirstOrDefault((Func<TMP_FontAsset, bool>)((TMP_FontAsset a) => (Object)(object)a != (Object)null && ((Object)a).name == "LiberationSans SDF"));
			if ((Object)(object)val2 != (Object)null)
			{
				return val2;
			}
		}
		catch
		{
		}
		try
		{
			return TMP_Settings.defaultFontAsset;
		}
		catch
		{
			return null;
		}
	}

	private static Color Hex(string hex, float alpha = 1f)
	{
		//IL_0018: 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_000f: Unknown result type (might be due to invalid IL or missing references)
		Color magenta = default(Color);
		if (!ColorUtility.TryParseHtmlString(hex, ref magenta))
		{
			magenta = Color.magenta;
		}
		magenta.a = alpha;
		return magenta;
	}
}
internal static class UIKit
{
	internal static TMP_FontAsset Font;

	internal static TMP_FontAsset BoldFont;

	private static readonly Dictionary<int, Sprite> roundedCache = new Dictionary<int, Sprite>();

	private static Sprite crown;

	internal static Sprite Rounded(int radius)
	{
		//IL_0144: Unknown result type (might be due to invalid IL or missing references)
		//IL_0153: Unknown result type (might be due to invalid IL or missing references)
		//IL_0167: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
		radius = Mathf.Clamp(radius, 1, 64);
		if (roundedCache.TryGetValue(radius, out var value) && (Object)(object)value != (Object)null)
		{
			return value;
		}
		int num = radius * 2 + 3;
		Texture2D val = NewTexture(num, num, "Scoreboard_Rounded" + radius);
		Color32[] array = (Color32[])(object)new Color32[num * num];
		for (int i = 0; i < num; i++)
		{
			for (int j = 0; j < num; j++)
			{
				float num2 = (float)j + 0.5f;
				float num3 = (float)i + 0.5f;
				float num4 = Mathf.Max(new float[3]
				{
					(float)radius - num2,
					0f,
					num2 - (float)(num - radius)
				});
				float num5 = Mathf.Max(new float[3]
				{
					(float)radius - num3,
					0f,
					num3 - (float)(num - radius)
				});
				float num6 = Mathf.Sqrt(num4 * num4 + num5 * num5);
				float num7 = Mathf.Clamp01((float)radius - num6 + 0.5f);
				array[i * num + j] = new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, (byte)Mathf.RoundToInt(num7 * 255f));
			}
		}
		val.SetPixels32(array);
		val.Apply(false, true);
		float num8 = radius + 1;
		Sprite val2 = Sprite.Create(val, new Rect(0f, 0f, (float)num, (float)num), new Vector2(0.5f, 0.5f), 100f, 0u, (SpriteMeshType)0, new Vector4(num8, num8, num8, num8));
		((Object)val2).hideFlags = (HideFlags)61;
		((Object)val2).name = ((Object)val).name;
		roundedCache[radius] = val2;
		return val2;
	}

	internal static Sprite Crown()
	{
		//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_003b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0040: Unknown result type (might be due to invalid IL or missing references)
		//IL_0051: 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_0067: 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_007d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0082: 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)
		//IL_0098: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ae: 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_00d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
		//IL_0101: Unknown result type (might be due to invalid IL or missing references)
		//IL_0106: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d2: Unknown result type (might be due to invalid IL or missing references)
		//IL_0182: Unknown result type (might be due to invalid IL or missing references)
		//IL_0277: Unknown result type (might be due to invalid IL or missing references)
		//IL_027c: Unknown result type (might be due to invalid IL or missing references)
		//IL_019c: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)crown != (Object)null)
		{
			return crown;
		}
		Vector2[] poly = (Vector2[])(object)new Vector2[7]
		{
			new Vector2(0.1f, 0.1f),
			new Vector2(0.9f, 0.1f),
			new Vector2(0.97f, 0.7f),
			new Vector2(0.72f, 0.42f),
			new Vector2(0.5f, 0.86f),
			new Vector2(0.28f, 0.42f),
			new Vector2(0.03f, 0.7f)
		};
		Vector3[] array = (Vector3[])(object)new Vector3[3]
		{
			new Vector3(0.03f, 0.74f, 0.075f),
			new Vector3(0.5f, 0.9f, 0.085f),
			new Vector3(0.97f, 0.74f, 0.075f)
		};
		Texture2D val = NewTexture(96, 64, "Scoreboard_Crown");
		Color32[] array2 = (Color32[])(object)new Color32[6144];
		Vector2 val2 = default(Vector2);
		for (int i = 0; i < 64; i++)
		{
			for (int j = 0; j < 96; j++)
			{
				int num = 0;
				for (int k = 0; k < 4; k++)
				{
					for (int l = 0; l < 4; l++)
					{
						((Vector2)(ref val2))..ctor(((float)j + ((float)l + 0.5f) / 4f) / 96f, ((float)i + ((float)k + 0.5f) / 4f) / 64f);
						bool flag = InPolygon(val2, poly);
						if (!flag)
						{
							Vector3[] array3 = array;
							foreach (Vector3 val3 in array3)
							{
								float num2 = (val2.x - val3.x) * 96f / 64f;
								float num3 = val2.y - val3.y;
								if (num2 * num2 + num3 * num3 <= val3.z * val3.z)
								{
									flag = true;
									break;
								}
							}
						}
						if (flag)
						{
							num++;
						}
					}
				}
				byte b = (byte)(num * 255 / 16);
				float num4 = ((float)i + 0.5f) / 64f;
				byte b2 = (byte)((num4 > 0.12f && num4 < 0.26f) ? 205u : 255u);
				array2[i * 96 + j] = new Color32(b2, b2, b2, b);
			}
		}
		val.SetPixels32(array2);
		val.Apply(false, true);
		crown = Sprite.Create(val, new Rect(0f, 0f, 96f, 64f), new Vector2(0.5f, 0.5f), 100f);
		((Object)crown).hideFlags = (HideFlags)61;
		((Object)crown).name = ((Object)val).name;
		return crown;
	}

	private static bool InPolygon(Vector2 p, Vector2[] poly)
	{
		//IL_001b: 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_0039: 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)
		bool flag = false;
		int num = 0;
		int num2 = poly.Length - 1;
		while (num < poly.Length)
		{
			if (poly[num].y > p.y != poly[num2].y > p.y && p.x < (poly[num2].x - poly[num].x) * (p.y - poly[num].y) / (poly[num2].y - poly[num].y) + poly[num].x)
			{
				flag = !flag;
			}
			num2 = num++;
		}
		return flag;
	}

	private static Texture2D NewTexture(int w, int h, string name)
	{
		//IL_0004: Unknown result type (might be due to invalid IL or missing references)
		//IL_0009: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: 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_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0027: Expected O, but got Unknown
		return new Texture2D(w, h, (TextureFormat)4, false)
		{
			filterMode = (FilterMode)1,
			wrapMode = (TextureWrapMode)1,
			hideFlags = (HideFlags)61,
			name = name
		};
	}

	internal static RectTransform Rect(Transform parent, string name)
	{
		//IL_0014: Unknown result type (might be due to invalid IL or missing references)
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_003b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0040: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: Expected O, but got Unknown
		RectTransform val = (RectTransform)new GameObject(name, new Type[1] { typeof(RectTransform) })
		{
			layer = (((Object)(object)parent != (Object)null) ? ((Component)parent).gameObject.layer : 5)
		}.transform;
		((Transform)val).SetParent(parent, false);
		return val;
	}

	internal static void Stretch(RectTransform rt, float left = 0f, float right = 0f, float top = 0f, float bottom = 0f)
	{
		//IL_0001: 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_0021: 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_003e: Unknown result type (might be due to invalid IL or missing references)
		rt.anchorMin = Vector2.zero;
		rt.anchorMax = Vector2.one;
		rt.pivot = new Vector2(0.5f, 0.5f);
		rt.offsetMin = new Vector2(left, bottom);
		rt.offsetMax = new Vector2(0f - right, 0f - top);
	}

	internal static Image Box(Transform parent, Color color, int radius = 0, string name = "Box")
	{
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		Image val = ((Component)Rect(parent, name)).gameObject.AddComponent<Image>();
		((Graphic)val).color = color;
		((Graphic)val).raycastTarget = false;
		if (radius > 0)
		{
			val.sprite = Rounded(radius);
			val.type = (Type)1;
			val.fillCenter = true;
		}
		return val;
	}

	internal static TextMeshProUGUI Text(Transform parent, string text, float size, Color color, FontStyles style = (FontStyles)0, TextAlignmentOptions align = (TextAlignmentOptions)4097, string name = "Text")
	{
		//IL_0013: 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_0018: Invalid comparison between Unknown and I4
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_0038: 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_0074: Unknown result type (might be due to invalid IL or missing references)
		//IL_007b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0083: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
		TextMeshProUGUI val = ((Component)Rect(parent, name)).gameObject.AddComponent<TextMeshProUGUI>();
		if ((style & 1) > 0 && (Object)(object)BoldFont != (Object)null)
		{
			((TMP_Text)val).font = BoldFont;
			style = (FontStyles)(style & -2);
		}
		else if ((Object)(object)Font != (Object)null)
		{
			((TMP_Text)val).font = Font;
		}
		((TMP_Text)val).richText = false;
		((TMP_Text)val).text = text ?? "";
		((TMP_Text)val).fontSize = size;
		((Graphic)val).color = color;
		((TMP_Text)val).fontStyle = style;
		((TMP_Text)val).alignment = align;
		((TMP_Text)val).enableWordWrapping = false;
		((TMP_Text)val).overflowMode = (TextOverflowModes)1;
		((Graphic)val).raycastTarget = false;
		((TMP_Text)val).margin = Vector4.zero;
		return val;
	}

	internal static LayoutElement LE(Component c, float minW = -1f, float prefW = -1f, float flexW = -1f, float minH = -1f, float prefH = -1f, float flexH = -1f)
	{
		LayoutElement obj = c.gameObject.GetComponent<LayoutElement>() ?? c.gameObject.AddComponent<LayoutElement>();
		obj.minWidth = minW;
		obj.preferredWidth = prefW;
		obj.flexibleWidth = flexW;
		obj.minHeight = minH;
		obj.preferredHeight = prefH;
		obj.flexibleHeight = flexH;
		return obj;
	}

	internal static HorizontalLayoutGroup HL(Component c, float spacing, int padL = 0, int padR = 0, int padT = 0, int padB = 0, TextAnchor align = (TextAnchor)3, bool expandW = false, bool expandH = false)
	{
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_0023: Expected O, but got Unknown
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		HorizontalLayoutGroup obj = c.gameObject.AddComponent<HorizontalLayoutGroup>();
		((HorizontalOrVerticalLayoutGroup)obj).spacing = spacing;
		((LayoutGroup)obj).padding = new RectOffset(padL, padR, padT, padB);
		((LayoutGroup)obj).childAlignment = align;
		((HorizontalOrVerticalLayoutGroup)obj).childControlWidth = true;
		((HorizontalOrVerticalLayoutGroup)obj).childControlHeight = true;
		((HorizontalOrVerticalLayoutGroup)obj).childForceExpandWidth = expandW;
		((HorizontalOrVerticalLayoutGroup)obj).childForceExpandHeight = expandH;
		return obj;
	}

	internal static VerticalLayoutGroup VL(Component c, float spacing, int padL = 0, int padR = 0, int padT = 0, int padB = 0, TextAnchor align = (TextAnchor)0, bool expandW = true, bool expandH = false)
	{
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_0023: Expected O, but got Unknown
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		VerticalLayoutGroup obj = c.gameObject.AddComponent<VerticalLayoutGroup>();
		((HorizontalOrVerticalLayoutGroup)obj).spacing = spacing;
		((LayoutGroup)obj).padding = new RectOffset(padL, padR, padT, padB);
		((LayoutGroup)obj).childAlignment = align;
		((HorizontalOrVerticalLayoutGroup)obj).childControlWidth = true;
		((HorizontalOrVerticalLayoutGroup)obj).childControlHeight = true;
		((HorizontalOrVerticalLayoutGroup)obj).childForceExpandWidth = expandW;
		((HorizontalOrVerticalLayoutGroup)obj).childForceExpandHeight = expandH;
		return obj;
	}

	internal static void Spacer(Transform parent, float flexW = 1f, float flexH = 0f)
	{
		LE((Component)(object)Rect(parent, "Spacer"), 0f, -1f, flexW, 0f, -1f, flexH);
	}

	internal static Image Bordered(Transform parent, Color fill, Color border, int radius, int thickness, string name = "Card")
	{
		//IL_0001: 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)
		Image obj = Box(parent, border, radius, name);
		HL((Component)(object)obj, 0f, thickness, thickness, thickness, thickness, (TextAnchor)0, expandW: true, expandH: true);
		return Box(((Component)obj).transform, fill, Mathf.Max(1, radius - thickness), "Inner");
	}
}