Decompiled source of UpgradeVote v0.2.0

LerrdyhoReposession-UpgradeVotes.dll

Decompiled 5 hours ago
using System;
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 System.Threading.Tasks;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using MenuLib;
using MenuLib.MonoBehaviors;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using Steamworks;
using Steamworks.Data;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("")]
[assembly: AssemblyCompany("Lerdi")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+175556a80540d5c304895b0f89ca9e4432ef33f0")]
[assembly: AssemblyProduct("LerrdyhoReposession-UpgradeVotes")]
[assembly: AssemblyTitle("LerrdyhoReposession-UpgradeVotes")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.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 UpgradeVote
{
	[BepInPlugin("com.lerrdy.repo.upgradevote", "Upgrade Vote", "0.4.0")]
	public class UpgradeVotePlugin : BaseUnityPlugin
	{
		public const string PluginGuid = "com.lerrdy.repo.upgradevote";

		public const string PluginName = "Upgrade Vote";

		public const string PluginVersion = "0.4.0";

		internal static ManualLogSource Log;

		private Harmony _harmony;

		internal static ConfigEntry<bool> EnablePlugin;

		internal static ConfigEntry<float> VoteDurationSeconds;

		internal static ConfigEntry<bool> VerboseLogging;

		internal static void LogDebug(string msg)
		{
			if (VerboseLogging != null && VerboseLogging.Value)
			{
				ManualLogSource log = Log;
				if (log != null)
				{
					log.LogInfo((object)msg);
				}
			}
		}

		private void Awake()
		{
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			EnablePlugin = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "EnablePlugin", true, "Enable / disable the Upgrade Vote plugin.");
			VoteDurationSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Voting", "VoteDurationSeconds", 15f, "Duration (seconds) of each upgrade vote.");
			VerboseLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "VerboseLogging", false, "If true, prints extra debug logs for troubleshooting.");
			if (!EnablePlugin.Value)
			{
				Log.LogInfo((object)"[UpgradeVote] Plugin disabled via config.");
				return;
			}
			try
			{
				_harmony = new Harmony("com.lerrdy.repo.upgradevote");
				_harmony.PatchAll();
				Log.LogInfo((object)"[UpgradeVote] Harmony patches applied.");
			}
			catch (Exception ex)
			{
				Log.LogError((object)"[UpgradeVote] Harmony.PatchAll() threw:");
				Log.LogError((object)ex.ToString());
			}
			Log.LogInfo((object)"[UpgradeVote] Loaded Upgrade Vote v0.4.0");
		}

		private void OnDestroy()
		{
			try
			{
				Harmony harmony = _harmony;
				if (harmony != null)
				{
					harmony.UnpatchSelf();
				}
			}
			catch
			{
			}
		}
	}
	public class UpgradeVoteNetwork : MonoBehaviourPun
	{
		public static UpgradeVoteNetwork Instance { get; private set; }

		private void Awake()
		{
			if ((Object)(object)Instance != (Object)null && (Object)(object)Instance != (Object)(object)this)
			{
				Object.Destroy((Object)(object)this);
			}
			else
			{
				Instance = this;
			}
		}

		private void OnDestroy()
		{
			if ((Object)(object)Instance == (Object)(object)this)
			{
				Instance = null;
			}
		}

		public void HostStartRound(int roundId, string upgradeKey, string[] playerNames, string[] playerSteamIds, float duration)
		{
			if ((Object)(object)((MonoBehaviourPun)this).photonView == (Object)null)
			{
				ManualLogSource log = UpgradeVotePlugin.Log;
				if (log != null)
				{
					log.LogWarning((object)"[UpgradeVote] HostStartRound: photonView null.");
				}
				return;
			}
			ManualLogSource log2 = UpgradeVotePlugin.Log;
			if (log2 != null)
			{
				log2.LogInfo((object)$"[UpgradeVote] RPC UpgradeVote_StartRound round={roundId} key={upgradeKey}");
			}
			((MonoBehaviourPun)this).photonView.RPC("UpgradeVote_StartRound", (RpcTarget)0, new object[5] { roundId, upgradeKey, playerNames, playerSteamIds, duration });
		}

		public void SendVote(int roundId, int voterActorNumber, int choiceIndex)
		{
			if (!PhotonNetwork.IsConnected || PhotonNetwork.CurrentRoom == null)
			{
				return;
			}
			PhotonView photonView = ((MonoBehaviourPun)this).photonView;
			if ((Object)(object)photonView == (Object)null)
			{
				ManualLogSource log = UpgradeVotePlugin.Log;
				if (log != null)
				{
					log.LogWarning((object)"[UpgradeVote] SendVote: photonView is null, aborting.");
				}
				return;
			}
			ManualLogSource log2 = UpgradeVotePlugin.Log;
			if (log2 != null)
			{
				log2.LogInfo((object)$"[UpgradeVote] RPC UpgradeVote_SubmitVote round={roundId} actor={voterActorNumber} choice={choiceIndex}");
			}
			photonView.RPC("UpgradeVote_SubmitVote", (RpcTarget)2, new object[3] { roundId, voterActorNumber, choiceIndex });
		}

		public void HostBroadcastVoteUpdate(int roundId, int[] voteCounts)
		{
			if (!((Object)(object)((MonoBehaviourPun)this).photonView == (Object)null))
			{
				((MonoBehaviourPun)this).photonView.RPC("UpgradeVote_VoteUpdate", (RpcTarget)0, new object[2] { roundId, voteCounts });
			}
		}

		public void HostEndRound(int roundId, int winnerIndex, string winnerName, string upgradeKey)
		{
			if (!((Object)(object)((MonoBehaviourPun)this).photonView == (Object)null))
			{
				ManualLogSource log = UpgradeVotePlugin.Log;
				if (log != null)
				{
					log.LogInfo((object)$"[UpgradeVote] RPC UpgradeVote_EndRound round={roundId} winnerIndex={winnerIndex} winner={winnerName}");
				}
				((MonoBehaviourPun)this).photonView.RPC("UpgradeVote_EndRound", (RpcTarget)0, new object[4] { roundId, winnerIndex, winnerName, upgradeKey });
			}
		}

		[PunRPC]
		private void UpgradeVote_StartRound(int roundId, string upgradeKey, string[] playerNames, string[] playerSteamIds, float duration)
		{
			UpgradeVoteManager.Instance.OnNetworkStartRound(roundId, upgradeKey, playerNames, playerSteamIds, duration);
		}

		[PunRPC]
		private void UpgradeVote_SubmitVote(int roundId, int voterActorNumber, int choiceIndex)
		{
			UpgradeVoteManager.Instance.OnNetworkVote(roundId, voterActorNumber, choiceIndex);
		}

		[PunRPC]
		private void UpgradeVote_VoteUpdate(int roundId, int[] voteCounts)
		{
			UpgradeVoteManager.Instance.OnNetworkVoteUpdate(roundId, voteCounts);
		}

		[PunRPC]
		private void UpgradeVote_EndRound(int roundId, int winnerIndex, string winnerName, string upgradeKey)
		{
			UpgradeVoteManager.Instance.OnNetworkEndRound(roundId, winnerIndex, winnerName, upgradeKey);
		}
	}
	public class UpgradeVoteManager : MonoBehaviour
	{
		private sealed class PlayerRow
		{
			public string Name;

			public REPOButton Button;

			public TextMeshProUGUI VotesLabel;
		}

		private static UpgradeVoteManager _instance;

		private string[] _localPlayerSteamIDs = Array.Empty<string>();

		private const string NameIndentTag = "<indent=32px>";

		private const bool DebugFillTestPlayers = true;

		private readonly Queue<string> _upgradeQueue = new Queue<string>();

		private bool _networkAttached = false;

		private int _currentRoundId = 0;

		private string _currentUpgradeKey = null;

		private List<PlayerAvatar> _currentPlayers = new List<PlayerAvatar>();

		private Dictionary<int, int> _votesByActor = new Dictionary<int, int>();

		private float _hostTimer = 0f;

		private bool _hostVoteActive = false;

		private bool _localVoteActive = false;

		private int _localRoundId = -1;

		private string[] _localPlayerNames = Array.Empty<string>();

		private int[] _localVoteCounts = Array.Empty<int>();

		private int? _localMyChoiceIndex = null;

		private float _localTimer = 0f;

		private REPOPopupPage _votePopup;

		private REPOLabel _timerLabel;

		private REPOPopupPage _popup;

		private readonly List<REPOButton> _playerButtons = new List<REPOButton>();

		private REPOLabel _questionLabel;

		private GameObject _toastCanvas;

		private float _toastTimer = 0f;

		private readonly List<Image> _playerAvatarImages = new List<Image>();

		private readonly List<PlayerRow> _playerRows = new List<PlayerRow>();

		private readonly HashSet<int> _avatarLoggedOnce = new HashSet<int>();

		public static UpgradeVoteManager Instance
		{
			get
			{
				//IL_0030: Unknown result type (might be due to invalid IL or missing references)
				//IL_0036: Expected O, but got Unknown
				if ((Object)(object)_instance == (Object)null)
				{
					_instance = Object.FindObjectOfType<UpgradeVoteManager>();
					if ((Object)(object)_instance == (Object)null)
					{
						GameObject val = new GameObject("UpgradeVoteManager");
						_instance = val.AddComponent<UpgradeVoteManager>();
						Object.DontDestroyOnLoad((Object)(object)val);
						ManualLogSource log = UpgradeVotePlugin.Log;
						if (log != null)
						{
							log.LogInfo((object)"[UpgradeVote] UpgradeVoteManager created lazily.");
						}
					}
				}
				return _instance;
			}
		}

		private bool _isHost => SemiFunc.IsMasterClientOrSingleplayer();

		private void Awake()
		{
			if ((Object)(object)_instance != (Object)null && (Object)(object)_instance != (Object)(object)this)
			{
				Object.Destroy((Object)(object)((Component)this).gameObject);
				return;
			}
			_instance = this;
			Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
			ManualLogSource log = UpgradeVotePlugin.Log;
			if (log != null)
			{
				log.LogInfo((object)"[UpgradeVote] UpgradeVoteManager Awake (singleton set).");
			}
		}

		public void HostRegisterLocalVote(int choiceIndex)
		{
			if (_isHost && _hostVoteActive && choiceIndex >= 0 && choiceIndex < _currentPlayers.Count)
			{
				_votesByActor[-1] = choiceIndex;
			}
		}

		private void RefreshPlayerAvatars()
		{
			int num = Mathf.Min(_playerAvatarImages.Count, _localPlayerSteamIDs.Length);
			for (int i = 0; i < num; i++)
			{
				Image val = _playerAvatarImages[i];
				if (!((Object)(object)val == (Object)null))
				{
					string text = _localPlayerSteamIDs[i];
					if (UpgradeVotePlugin.VerboseLogging.Value && !_avatarLoggedOnce.Contains(i))
					{
						_avatarLoggedOnce.Add(i);
						UpgradeVotePlugin.LogDebug(string.Format("[Avatar] Refresh index {0}, steamId={1}", i, text ?? "NULL"));
					}
					Sprite avatarSprite = SteamAvatarCache.GetAvatarSprite(text);
					bool enabled = (Object)(object)avatarSprite != (Object)null;
					val.sprite = avatarSprite;
					((Behaviour)val).enabled = enabled;
				}
			}
		}

		private void Update()
		{
			if (!UpgradeVotePlugin.EnablePlugin.Value)
			{
				return;
			}
			AttachNetworkIfPossible();
			if (_isHost && _hostVoteActive)
			{
				_hostTimer -= Time.deltaTime;
				if (_hostTimer < 0f)
				{
					_hostTimer = 0f;
				}
				int count = _currentPlayers.Count;
				if (count > 0 && _votesByActor.Count >= count)
				{
					HostResolveCurrentVote();
				}
				else if (_hostTimer <= 0f)
				{
					HostResolveCurrentVote();
				}
			}
			if (_localVoteActive)
			{
				if ((Object)(object)_timerLabel != (Object)null)
				{
					_localTimer -= Time.deltaTime;
					if (_localTimer < 0f)
					{
						_localTimer = 0f;
					}
					((TMP_Text)_timerLabel.labelTMP).text = $"Time left: {_localTimer:0.0}s";
				}
				RefreshPlayerAvatars();
			}
			if ((Object)(object)_toastCanvas != (Object)null)
			{
				_toastTimer -= Time.deltaTime;
				if (_toastTimer <= 0f)
				{
					Object.Destroy((Object)(object)_toastCanvas);
					_toastCanvas = null;
				}
			}
			UpgradeVoteNotification.Update();
		}

		private static string ColorString(string text, Color color)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			return "<color=#" + ColorUtility.ToHtmlStringRGB(color) + ">" + text + "</color>";
		}

		private static string GetPrettyUpgradeName(string fullKey)
		{
			if (string.IsNullOrEmpty(fullKey))
			{
				return "upgrade";
			}
			if (fullKey.StartsWith("playerUpgrade", StringComparison.OrdinalIgnoreCase))
			{
				fullKey = fullKey.Substring("playerUpgrade".Length).TrimStart('_', '.', '/');
			}
			int num = fullKey.LastIndexOf('/');
			if (num >= 0 && num < fullKey.Length - 1)
			{
				fullKey = fullKey.Substring(num + 1);
			}
			int num2 = fullKey.LastIndexOf('.');
			if (num2 > 0)
			{
				fullKey = fullKey.Substring(0, num2);
			}
			fullKey = fullKey.Replace('_', ' ');
			if (string.IsNullOrWhiteSpace(fullKey))
			{
				return "upgrade";
			}
			return char.ToUpper(fullKey[0]) + fullKey.Substring(1);
		}

		private string BuildPlayerRowLabel(string playerName, int votesForThisPlayer, int totalPlayers, bool isMyVote, bool highlightWinner)
		{
			//IL_0021: 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_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			int num = Mathf.Clamp(totalPlayers, 4, 12);
			Color color = (highlightWinner ? Color.green : (isMyVote ? Color.yellow : Color.white));
			StringBuilder stringBuilder = new StringBuilder();
			bool flag = isMyVote || highlightWinner;
			stringBuilder.Append("<mspace=0.25em>[");
			stringBuilder.Append(ColorString(flag ? "X" : " ", color));
			stringBuilder.Append("]</mspace>  ");
			stringBuilder.Append(ColorString(playerName, color));
			stringBuilder.Append($"  <size=18>({votesForThisPlayer}/{num} votes)</size>");
			return stringBuilder.ToString();
		}

		private void AttachNetworkIfPossible()
		{
			if (_networkAttached || (Object)(object)PunManager.instance == (Object)null)
			{
				return;
			}
			GameObject gameObject = ((Component)PunManager.instance).gameObject;
			if ((Object)(object)gameObject.GetComponent<UpgradeVoteNetwork>() == (Object)null)
			{
				gameObject.AddComponent<UpgradeVoteNetwork>();
			}
			_networkAttached = true;
			ManualLogSource log = UpgradeVotePlugin.Log;
			if (log != null)
			{
				log.LogInfo((object)"[UpgradeVote] Attached UpgradeVoteNetwork to PunManager.");
			}
			if (_isHost && !_hostVoteActive && _upgradeQueue.Count > 0)
			{
				ManualLogSource log2 = UpgradeVotePlugin.Log;
				if (log2 != null)
				{
					log2.LogInfo((object)"[UpgradeVote] Network attached with pending upgrades; starting first vote.");
				}
				HostStartNextVoteIfAny();
			}
		}

		public void EnqueueUpgrade(string fullKey, int count)
		{
			if (_isHost && !string.IsNullOrEmpty(fullKey) && count > 0)
			{
				for (int i = 0; i < count; i++)
				{
					_upgradeQueue.Enqueue(fullKey);
				}
				ManualLogSource log = UpgradeVotePlugin.Log;
				if (log != null)
				{
					log.LogInfo((object)$"[UpgradeVote] Enqueued {count}x {fullKey} (queue size now {_upgradeQueue.Count}).");
				}
				if (!_hostVoteActive)
				{
					HostStartNextVoteIfAny();
				}
			}
		}

		private void HostStartNextVoteIfAny()
		{
			if (!_isHost || _hostVoteActive || _upgradeQueue.Count == 0)
			{
				return;
			}
			_currentUpgradeKey = _upgradeQueue.Dequeue();
			_currentRoundId++;
			_currentPlayers = SemiFunc.PlayerGetAll() ?? new List<PlayerAvatar>();
			_currentPlayers = _currentPlayers.Where((PlayerAvatar p) => (Object)(object)p != (Object)null && (Object)(object)p.photonView != (Object)null).ToList();
			string[] array = _currentPlayers.Select(GetPlayerNameSafe).ToArray();
			string[] playerSteamIds = _currentPlayers.Select(GetPlayerSteamIDSafe).ToArray();
			_votesByActor.Clear();
			_hostTimer = Mathf.Max(1f, UpgradeVotePlugin.VoteDurationSeconds.Value);
			_hostVoteActive = true;
			if ((Object)(object)UpgradeVoteNetwork.Instance != (Object)null && PhotonNetwork.IsConnected && PhotonNetwork.CurrentRoom != null)
			{
				ManualLogSource log = UpgradeVotePlugin.Log;
				if (log != null)
				{
					log.LogInfo((object)$"[UpgradeVote] Starting vote round #{_currentRoundId} for {_currentUpgradeKey} (players={array.Length}) via NETWORK.");
				}
				UpgradeVoteNetwork.Instance.HostStartRound(_currentRoundId, _currentUpgradeKey, array, playerSteamIds, _hostTimer);
			}
			else
			{
				ManualLogSource log2 = UpgradeVotePlugin.Log;
				if (log2 != null)
				{
					log2.LogWarning((object)("[UpgradeVote] HostStartNextVoteIfAny: no UpgradeVoteNetwork/room; starting LOCAL-only vote for " + _currentUpgradeKey + "."));
				}
				OnNetworkStartRound(_currentRoundId, _currentUpgradeKey, array, playerSteamIds, _hostTimer);
			}
		}

		private void HostResolveCurrentVote()
		{
			if (!_isHost || !_hostVoteActive)
			{
				return;
			}
			_hostVoteActive = false;
			int count = _currentPlayers.Count;
			int[] array = new int[count];
			Array.Clear(array, 0, array.Length);
			foreach (KeyValuePair<int, int> item in _votesByActor)
			{
				int value = item.Value;
				if (value >= 0 && value < count)
				{
					array[value]++;
				}
			}
			int num = -1;
			string text = "(none)";
			if (count > 0)
			{
				if (array.All((int c) => c <= 0))
				{
					num = Random.Range(0, count);
				}
				else
				{
					int num2 = array.Max();
					List<int> list = new List<int>();
					for (int i = 0; i < array.Length; i++)
					{
						if (array[i] == num2)
						{
							list.Add(i);
						}
					}
					int index = Random.Range(0, list.Count);
					num = list[index];
				}
				if (num >= 0 && num < count)
				{
					PlayerAvatar avatar = _currentPlayers[num];
					text = GetPlayerNameSafe(avatar);
					try
					{
						ApplyUpgradeToPlayer(_currentUpgradeKey, avatar);
					}
					catch (Exception arg)
					{
						ManualLogSource log = UpgradeVotePlugin.Log;
						if (log != null)
						{
							log.LogWarning((object)$"[UpgradeVote] Failed to apply {_currentUpgradeKey} to {text}: {arg}");
						}
					}
				}
			}
			ManualLogSource log2 = UpgradeVotePlugin.Log;
			if (log2 != null)
			{
				log2.LogInfo((object)$"[UpgradeVote] Round #{_currentRoundId} result: {_currentUpgradeKey} -> {text}");
			}
			if ((Object)(object)UpgradeVoteNetwork.Instance != (Object)null && PhotonNetwork.IsConnected && PhotonNetwork.CurrentRoom != null)
			{
				UpgradeVoteNetwork.Instance.HostEndRound(_currentRoundId, num, text, _currentUpgradeKey);
			}
			else
			{
				OnNetworkEndRound(_currentRoundId, num, text, _currentUpgradeKey);
			}
			HostStartNextVoteIfAny();
		}

		private void ApplyUpgradeToPlayer(string fullKey, PlayerAvatar avatar)
		{
			if ((Object)(object)StatsManager.instance == (Object)null)
			{
				ManualLogSource log = UpgradeVotePlugin.Log;
				if (log != null)
				{
					log.LogWarning((object)"[UpgradeVote] StatsManager.instance null, cannot apply upgrade.");
				}
				return;
			}
			if ((Object)(object)PunManager.instance == (Object)null)
			{
				ManualLogSource log2 = UpgradeVotePlugin.Log;
				if (log2 != null)
				{
					log2.LogWarning((object)"[UpgradeVote] PunManager.instance null, cannot apply upgrade.");
				}
				return;
			}
			string text = SemiFunc.PlayerGetSteamID(avatar);
			if (string.IsNullOrEmpty(text))
			{
				ManualLogSource log3 = UpgradeVotePlugin.Log;
				if (log3 != null)
				{
					log3.LogWarning((object)"[UpgradeVote] steamID null/empty, cannot apply upgrade.");
				}
				return;
			}
			if (!StatsManager.instance.dictionaryOfDictionaries.TryGetValue(fullKey, out var value))
			{
				ManualLogSource log4 = UpgradeVotePlugin.Log;
				if (log4 != null)
				{
					log4.LogWarning((object)("[UpgradeVote] dictionaryOfDictionaries missing key '" + fullKey + "'."));
				}
				return;
			}
			int value2 = 0;
			value.TryGetValue(text, out value2);
			int num2 = (value[text] = value2 + 1);
			PhotonView component = ((Component)PunManager.instance).GetComponent<PhotonView>();
			if ((Object)(object)component == (Object)null)
			{
				ManualLogSource log5 = UpgradeVotePlugin.Log;
				if (log5 != null)
				{
					log5.LogWarning((object)"[UpgradeVote] PunManager PhotonView null, cannot send UpdateStatRPC.");
				}
				return;
			}
			ManualLogSource log6 = UpgradeVotePlugin.Log;
			if (log6 != null)
			{
				log6.LogInfo((object)$"[UpgradeVote] Applying {fullKey} to {text} (new value {num2}) via UpdateStatRPC.");
			}
			component.RPC("UpdateStatRPC", (RpcTarget)0, new object[3] { fullKey, text, num2 });
		}

		private string GetPlayerNameSafe(PlayerAvatar avatar)
		{
			if ((Object)(object)avatar == (Object)null)
			{
				return "Unknown";
			}
			try
			{
				FieldInfo fieldInfo = AccessTools.Field(typeof(PlayerAvatar), "playerName");
				if (fieldInfo != null)
				{
					string text = fieldInfo.GetValue(avatar) as string;
					if (!string.IsNullOrEmpty(text))
					{
						return text;
					}
				}
			}
			catch
			{
			}
			PhotonView photonView = avatar.photonView;
			return $"Player {((photonView != null) ? photonView.ViewID : (-1))}";
		}

		private string GetPlayerSteamIDSafe(PlayerAvatar avatar)
		{
			if ((Object)(object)avatar == (Object)null)
			{
				return null;
			}
			try
			{
				FieldInfo fieldInfo = AccessTools.Field(typeof(PlayerAvatar), "steamID");
				if (fieldInfo != null)
				{
					string text = fieldInfo.GetValue(avatar) as string;
					if (!string.IsNullOrEmpty(text))
					{
						return text;
					}
				}
			}
			catch
			{
			}
			return null;
		}

		public void OnNetworkStartRound(int roundId, string upgradeKey, string[] playerNames, string[] playerSteamIds, float duration)
		{
			UpgradeVotePlugin.LogDebug($"[UpgradeVote] OnNetworkStartRound round={roundId} key={upgradeKey}");
			_localRoundId = roundId;
			_currentUpgradeKey = upgradeKey;
			_localPlayerNames = playerNames ?? Array.Empty<string>();
			_localPlayerSteamIDs = playerSteamIds ?? new string[_localPlayerNames.Length];
			if (UpgradeVotePlugin.VerboseLogging.Value)
			{
				List<string> list = new List<string>(_localPlayerNames);
				List<string> list2 = new List<string>(_localPlayerSteamIDs);
				while (list.Count < 12)
				{
					int num = list.Count + 1;
					list.Add($"TestPlayer {num}");
					list2.Add(null);
				}
				_localPlayerNames = list.ToArray();
				_localPlayerSteamIDs = list2.ToArray();
			}
			_localVoteCounts = new int[_localPlayerNames.Length];
			_localMyChoiceIndex = null;
			_localTimer = duration;
			_localVoteActive = true;
			BuildVoteUI();
		}

		public void OnNetworkVote(int roundId, int voterActorNumber, int choiceIndex)
		{
			if (!_isHost || !_hostVoteActive || roundId != _currentRoundId)
			{
				return;
			}
			int count = _currentPlayers.Count;
			if (choiceIndex < 0 || choiceIndex >= count)
			{
				return;
			}
			_votesByActor[voterActorNumber] = choiceIndex;
			int[] array = new int[count];
			foreach (KeyValuePair<int, int> item in _votesByActor)
			{
				int value = item.Value;
				if (value >= 0 && value < count)
				{
					array[value]++;
				}
			}
			UpgradeVoteNetwork.Instance?.HostBroadcastVoteUpdate(roundId, array);
		}

		public void OnNetworkVoteUpdate(int roundId, int[] voteCounts)
		{
			if (_localVoteActive && roundId == _localRoundId)
			{
				_localVoteCounts = voteCounts ?? Array.Empty<int>();
				RefreshPlayerLines();
			}
		}

		public void OnNetworkEndRound(int roundId, int winnerIndex, string winnerName, string upgradeKey)
		{
			if (roundId == _localRoundId)
			{
				ManualLogSource log = UpgradeVotePlugin.Log;
				if (log != null)
				{
					log.LogInfo((object)$"[UpgradeVote] OnNetworkEndRound round={roundId} winner={winnerName}");
				}
				_localVoteActive = false;
				DestroyVoteUI();
				string prettyUpgradeName = GetPrettyUpgradeName(upgradeKey);
				UpgradeVoteNotification.ShowUpgradeAward(winnerName, prettyUpgradeName);
			}
		}

		private void BuildVoteUI()
		{
			//IL_0068: 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_00c2: Expected O, but got Unknown
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Expected O, but got Unknown
			UpgradeVotePlugin.LogDebug($"[Avatar] BuildVoteUI: names={_localPlayerNames.Length}, steamIds={_localPlayerSteamIDs.Length}");
			DestroyVoteUI();
			MenuAPI.CloseAllPagesAddedOnTop();
			string prettyUpgradeName = GetPrettyUpgradeName(_currentUpgradeKey);
			string text = "Kdo dostane\n\"" + prettyUpgradeName + "\"?\n";
			_popup = MenuAPI.CreateREPOPopupPage(text, true, true, 0f, (Vector2?)new Vector2(-100f, 0f));
			_playerButtons.Clear();
			for (int i = 0; i < _localPlayerNames.Length; i++)
			{
				int idx = i;
				_popup.AddElementToScrollView((ScrollViewBuilderDelegate)delegate(Transform parent)
				{
					//IL_0026: 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_003c: Unknown result type (might be due to invalid IL or missing references)
					//IL_0065: Unknown result type (might be due to invalid IL or missing references)
					//IL_006f: Unknown result type (might be due to invalid IL or missing references)
					//IL_0081: 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_009d: Unknown result type (might be due to invalid IL or missing references)
					//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
					//IL_00b9: 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)
					//IL_015b: Unknown result type (might be due to invalid IL or missing references)
					//IL_016c: Unknown result type (might be due to invalid IL or missing references)
					//IL_0173: Expected O, but got Unknown
					//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
					//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
					//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
					//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
					//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
					REPOButton val = MenuAPI.CreateREPOButton((string)null, (Action)delegate
					{
						OnLocalPlayerButtonClicked(idx);
					}, parent, default(Vector2));
					RectTransform rectTransform = ((REPOElement)val).rectTransform;
					float num = rectTransform.sizeDelta.y;
					if (num <= 0f)
					{
						num = 56f;
					}
					rectTransform.anchorMin = new Vector2(0f, rectTransform.anchorMin.y);
					rectTransform.anchorMax = new Vector2(0.3f, rectTransform.anchorMax.y);
					rectTransform.offsetMin = new Vector2(0f, rectTransform.offsetMin.y);
					rectTransform.offsetMax = new Vector2(-40f, rectTransform.offsetMax.y);
					LayoutElement val2 = ((Component)val).gameObject.GetComponent<LayoutElement>() ?? ((Component)val).gameObject.AddComponent<LayoutElement>();
					val2.minWidth = 0f;
					val2.preferredWidth = -1f;
					val2.flexibleWidth = 1f;
					val2.minHeight = num;
					val2.preferredHeight = num;
					val2.flexibleHeight = 0f;
					TextMeshProUGUI labelTMP = val.labelTMP;
					RectTransform rectTransform2 = ((TMP_Text)labelTMP).rectTransform;
					((TMP_Text)labelTMP).alignment = (TextAlignmentOptions)513;
					((TMP_Text)labelTMP).enableWordWrapping = false;
					((TMP_Text)labelTMP).overflowMode = (TextOverflowModes)0;
					float x = rectTransform2.offsetMin.x;
					GameObject val3 = new GameObject("Avatar");
					val3.transform.SetParent(((Component)val).transform, false);
					Image val4 = val3.AddComponent<Image>();
					RectTransform rectTransform3 = ((Graphic)val4).rectTransform;
					rectTransform3.anchorMin = new Vector2(0f, 0.5f);
					rectTransform3.anchorMax = new Vector2(0f, 0.5f);
					rectTransform3.pivot = new Vector2(0f, 0.5f);
					rectTransform3.sizeDelta = new Vector2(32f, 32f);
					rectTransform3.anchoredPosition = new Vector2(x, 0f);
					_playerAvatarImages.Add(val4);
					_playerButtons.Add(val);
					return ((REPOElement)val).rectTransform;
				}, 0f, 0f);
			}
			_popup.AddElement((BuilderDelegate)delegate(Transform parent)
			{
				//IL_000e: Unknown result type (might be due to invalid IL or missing references)
				_timerLabel = MenuAPI.CreateREPOLabel((string)null, parent, new Vector2(254f, 30f));
				((TMP_Text)_timerLabel.labelTMP).alignment = (TextAlignmentOptions)514;
				((TMP_Text)_timerLabel.labelTMP).text = $"Time left: {_localTimer:0.0}s";
			});
			_popup.OpenPage(true);
			((Component)_popup).GetComponent<MenuPage>().PageStateSet((PageState)1);
			RefreshPlayerLines();
			RefreshPlayerAvatars();
		}

		private void DestroyVoteUI()
		{
			if ((Object)(object)_popup != (Object)null)
			{
				_popup.ClosePage(true);
				_popup = null;
			}
			_playerAvatarImages.Clear();
			_timerLabel = null;
			_questionLabel = null;
			_playerButtons.Clear();
		}

		private TextMeshProUGUI CreateTMP(GameObject parent, string text, int size, TextAlignmentOptions alignment = 514)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("TMP");
			val.transform.SetParent(parent.transform, false);
			TextMeshProUGUI val2 = val.AddComponent<TextMeshProUGUI>();
			((TMP_Text)val2).text = text;
			((TMP_Text)val2).fontSize = size;
			((TMP_Text)val2).alignment = alignment;
			((Graphic)val2).color = Color.white;
			((TMP_Text)val2).enableWordWrapping = false;
			((TMP_Text)val2).overflowMode = (TextOverflowModes)0;
			RectTransform component = val.GetComponent<RectTransform>();
			component.sizeDelta = new Vector2(0f, 40f);
			return val2;
		}

		private void OnLocalPlayerButtonClicked(int index)
		{
			if (_localVoteActive && index >= 0 && index < _localPlayerNames.Length)
			{
				_localMyChoiceIndex = index;
				RefreshPlayerLines();
				if (PhotonNetwork.IsConnected && PhotonNetwork.CurrentRoom != null && (Object)(object)UpgradeVoteNetwork.Instance != (Object)null)
				{
					int voterActorNumber = ((PhotonNetwork.LocalPlayer != null) ? PhotonNetwork.LocalPlayer.ActorNumber : (-1));
					UpgradeVoteNetwork.Instance.SendVote(_localRoundId, voterActorNumber, index);
				}
				else
				{
					HostRegisterLocalVote(index);
				}
			}
		}

		private void RefreshPlayerLines()
		{
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: 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_00ed: Unknown result type (might be due to invalid IL or missing references)
			if (_playerButtons.Count == 0)
			{
				return;
			}
			int num = Mathf.Clamp(_localPlayerNames.Length, 1, 12);
			for (int i = 0; i < _playerButtons.Count; i++)
			{
				REPOButton val = _playerButtons[i];
				if (!((Object)(object)val == (Object)null))
				{
					string arg = ((i < _localPlayerNames.Length) ? _localPlayerNames[i] : $"Player {i + 1}");
					int num2 = ((i < _localVoteCounts.Length) ? _localVoteCounts[i] : 0);
					Color color = ((_localMyChoiceIndex.HasValue && _localMyChoiceIndex.Value == i) ? Color.yellow : Color.white);
					StringBuilder stringBuilder = new StringBuilder();
					stringBuilder.Append("<indent=32px>");
					stringBuilder.Append(ColorString($"{i + 1}. {arg}", color));
					if (num2 > 0)
					{
						string arg2 = ((num2 == 1) ? "" : "s");
						stringBuilder.Append($"  <size=18>({num2} vote{arg2})</size>");
					}
					((TMP_Text)val.labelTMP).enableWordWrapping = false;
					((TMP_Text)val.labelTMP).overflowMode = (TextOverflowModes)0;
					((TMP_Text)val.labelTMP).alignment = (TextAlignmentOptions)513;
					((TMP_Text)val.labelTMP).text = stringBuilder.ToString();
				}
			}
		}

		private void ShowResultToast(string upgradeKey, string winnerName)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Expected O, but got Unknown
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Expected O, but got Unknown
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: 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_0106: Unknown result type (might be due to invalid IL or missing references)
			if (string.IsNullOrEmpty(winnerName))
			{
				winnerName = "(no one)";
			}
			if ((Object)(object)_toastCanvas != (Object)null)
			{
				Object.Destroy((Object)(object)_toastCanvas);
			}
			_toastCanvas = new GameObject("UpgradeVoteToast");
			Canvas val = _toastCanvas.AddComponent<Canvas>();
			val.renderMode = (RenderMode)0;
			val.sortingOrder = 10000;
			_toastCanvas.AddComponent<CanvasScaler>();
			_toastCanvas.AddComponent<GraphicRaycaster>();
			GameObject val2 = new GameObject("Panel");
			val2.transform.SetParent(_toastCanvas.transform, false);
			Image val3 = val2.AddComponent<Image>();
			((Graphic)val3).color = new Color(0f, 0f, 0f, 0.8f);
			RectTransform component = val2.GetComponent<RectTransform>();
			component.anchorMin = new Vector2(0.3f, 0.8f);
			component.anchorMax = new Vector2(0.7f, 0.95f);
			component.offsetMin = Vector2.zero;
			component.offsetMax = Vector2.zero;
			TextMeshProUGUI val4 = CreateTMP(val2, "Upgrade '" + upgradeKey + "' awarded to " + winnerName + ".", 24, (TextAlignmentOptions)514);
			((TMP_Text)val4).alignment = (TextAlignmentOptions)514;
			_toastTimer = 3f;
		}

		private void TrySendChatMessage(string msg)
		{
			try
			{
				Type type = AccessTools.TypeByName("ChatManager");
				if (type == null)
				{
					ManualLogSource log = UpgradeVotePlugin.Log;
					if (log != null)
					{
						log.LogInfo((object)("[UpgradeVote] (Chat fallback) " + msg));
					}
					return;
				}
				object obj = AccessTools.Field(type, "instance")?.GetValue(null);
				if (obj == null)
				{
					ManualLogSource log2 = UpgradeVotePlugin.Log;
					if (log2 != null)
					{
						log2.LogInfo((object)("[UpgradeVote] (Chat fallback2) " + msg));
					}
					return;
				}
				MethodInfo methodInfo = AccessTools.Method(type, "AddMessage", new Type[1] { typeof(string) }, (Type[])null);
				if (methodInfo != null)
				{
					methodInfo.Invoke(obj, new object[1] { msg });
					return;
				}
				ManualLogSource log3 = UpgradeVotePlugin.Log;
				if (log3 != null)
				{
					log3.LogInfo((object)("[UpgradeVote] (Chat fallback3) " + msg));
				}
			}
			catch
			{
				ManualLogSource log4 = UpgradeVotePlugin.Log;
				if (log4 != null)
				{
					log4.LogInfo((object)("[UpgradeVote] (Chat failed) " + msg));
				}
			}
		}
	}
	[HarmonyPatch]
	public static class ItemUpgrade_PlayerUpgrade_Patch
	{
		private static readonly Dictionary<string, int> _preUpgradeStats = new Dictionary<string, int>();

		private static string _targetSteamID;

		private static PlayerAvatar _targetAvatar;

		private static MethodBase TargetMethod()
		{
			Type type = AccessTools.TypeByName("ItemUpgrade");
			if (type == null)
			{
				ManualLogSource log = UpgradeVotePlugin.Log;
				if (log != null)
				{
					log.LogError((object)"[UpgradeVote] ItemUpgrade type not found.");
				}
				return null;
			}
			MethodInfo methodInfo = AccessTools.Method(type, "PlayerUpgrade", (Type[])null, (Type[])null);
			if (methodInfo == null)
			{
				ManualLogSource log2 = UpgradeVotePlugin.Log;
				if (log2 != null)
				{
					log2.LogError((object)"[UpgradeVote] ItemUpgrade.PlayerUpgrade method not found.");
				}
			}
			else
			{
				ManualLogSource log3 = UpgradeVotePlugin.Log;
				if (log3 != null)
				{
					log3.LogInfo((object)("[UpgradeVote] Patching ItemUpgrade.PlayerUpgrade: " + methodInfo));
				}
			}
			return methodInfo;
		}

		[HarmonyPrefix]
		public static void Prefix(object __instance)
		{
			if (!UpgradeVotePlugin.EnablePlugin.Value || !SemiFunc.IsMasterClientOrSingleplayer())
			{
				return;
			}
			_targetSteamID = null;
			_targetAvatar = null;
			_preUpgradeStats.Clear();
			try
			{
				Type type = __instance.GetType();
				object? obj = AccessTools.Field(type, "itemToggle")?.GetValue(__instance);
				ItemToggle val = (ItemToggle)((obj is ItemToggle) ? obj : null);
				if ((Object)(object)val == (Object)null)
				{
					return;
				}
				FieldInfo fieldInfo = AccessTools.Field(typeof(ItemToggle), "playerTogglePhotonID");
				if (fieldInfo == null)
				{
					return;
				}
				int num = (int)fieldInfo.GetValue(val);
				PlayerAvatar val2 = SemiFunc.PlayerAvatarGetFromPhotonID(num);
				if ((Object)(object)val2 == (Object)null)
				{
					return;
				}
				_targetAvatar = val2;
				FieldInfo fieldInfo2 = AccessTools.Field(typeof(PlayerAvatar), "steamID");
				if (fieldInfo2 == null)
				{
					return;
				}
				string text = fieldInfo2.GetValue(val2) as string;
				if (string.IsNullOrEmpty(text))
				{
					return;
				}
				_targetSteamID = text;
				if ((Object)(object)StatsManager.instance == (Object)null)
				{
					return;
				}
				Dictionary<string, Dictionary<string, int>> dictionaryOfDictionaries = StatsManager.instance.dictionaryOfDictionaries;
				if (dictionaryOfDictionaries == null)
				{
					return;
				}
				foreach (KeyValuePair<string, Dictionary<string, int>> item in dictionaryOfDictionaries)
				{
					if (item.Key.StartsWith("playerUpgrade"))
					{
						if (item.Value.TryGetValue(_targetSteamID, out var value))
						{
							_preUpgradeStats[item.Key] = value;
						}
						else
						{
							_preUpgradeStats[item.Key] = 0;
						}
					}
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log = UpgradeVotePlugin.Log;
				if (log != null)
				{
					log.LogWarning((object)"[UpgradeVote] PREFIX exception:");
				}
				ManualLogSource log2 = UpgradeVotePlugin.Log;
				if (log2 != null)
				{
					log2.LogWarning((object)ex.ToString());
				}
			}
		}

		[HarmonyPostfix]
		public static void Postfix(object __instance)
		{
			if (!UpgradeVotePlugin.EnablePlugin.Value || !SemiFunc.IsMasterClientOrSingleplayer() || (Object)(object)StatsManager.instance == (Object)null)
			{
				return;
			}
			try
			{
				if (string.IsNullOrEmpty(_targetSteamID) || (Object)(object)_targetAvatar == (Object)null)
				{
					return;
				}
				Dictionary<string, Dictionary<string, int>> dictionaryOfDictionaries = StatsManager.instance.dictionaryOfDictionaries;
				if (dictionaryOfDictionaries == null)
				{
					return;
				}
				UpgradeVoteManager instance = UpgradeVoteManager.Instance;
				if ((Object)(object)instance == (Object)null)
				{
					return;
				}
				foreach (KeyValuePair<string, Dictionary<string, int>> item in dictionaryOfDictionaries)
				{
					string key = item.Key;
					if (key.StartsWith("playerUpgrade"))
					{
						Dictionary<string, int> value = item.Value;
						int num = (_preUpgradeStats.ContainsKey(key) ? _preUpgradeStats[key] : 0);
						int num2 = (value.ContainsKey(_targetSteamID) ? value[_targetSteamID] : 0);
						if (num2 > num)
						{
							int count = num2 - num;
							value[_targetSteamID] = num;
							instance.EnqueueUpgrade(key, count);
						}
					}
				}
				MonoBehaviour val = (MonoBehaviour)((__instance is MonoBehaviour) ? __instance : null);
				if ((Object)(object)val != (Object)null && (Object)(object)((Component)val).gameObject != (Object)null)
				{
					Object.Destroy((Object)(object)((Component)val).gameObject);
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log = UpgradeVotePlugin.Log;
				if (log != null)
				{
					log.LogWarning((object)"[UpgradeVote] POSTFIX exception:");
				}
				ManualLogSource log2 = UpgradeVotePlugin.Log;
				if (log2 != null)
				{
					log2.LogWarning((object)ex.ToString());
				}
			}
			finally
			{
				_targetSteamID = null;
				_targetAvatar = null;
				_preUpgradeStats.Clear();
			}
		}
	}
	public static class SteamAvatarCache
	{
		private static readonly Dictionary<ulong, Sprite> _cache = new Dictionary<ulong, Sprite>();

		private static readonly Dictionary<ulong, Task<Image?>> _pending = new Dictionary<ulong, Task<Image?>>();

		public static Sprite GetAvatarSprite(string steamIdString)
		{
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: 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_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: 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_0147: Expected O, but got Unknown
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			if (string.IsNullOrEmpty(steamIdString))
			{
				return null;
			}
			if (!ulong.TryParse(steamIdString, out var result))
			{
				return null;
			}
			if (_cache.TryGetValue(result, out Sprite value) && (Object)(object)value != (Object)null)
			{
				return value;
			}
			try
			{
				if (!_pending.TryGetValue(result, out Task<Image?> value2))
				{
					SteamId val = default(SteamId);
					val.Value = result;
					value2 = SteamFriends.GetLargeAvatarAsync(val);
					_pending[result] = value2;
					return null;
				}
				if (!value2.IsCompleted)
				{
					return null;
				}
				_pending.Remove(result);
				if (!value2.IsCompletedSuccessfully)
				{
					return null;
				}
				Image? result2 = value2.Result;
				if (!result2.HasValue)
				{
					return null;
				}
				Image value3 = result2.Value;
				if (value3.Width == 0 || value3.Height == 0 || value3.Data == null || value3.Data.Length == 0)
				{
					return null;
				}
				Texture2D val2 = new Texture2D((int)value3.Width, (int)value3.Height, (TextureFormat)4, false);
				((Texture)val2).filterMode = (FilterMode)1;
				val2.LoadRawTextureData(value3.Data);
				val2.Apply();
				FlipTextureVertically(val2);
				Sprite val3 = Sprite.Create(val2, new Rect(0f, 0f, (float)((Texture)val2).width, (float)((Texture)val2).height), new Vector2(0.5f, 0.5f));
				_cache[result] = val3;
				return val3;
			}
			catch (Exception arg)
			{
				ManualLogSource log = UpgradeVotePlugin.Log;
				if (log != null)
				{
					log.LogWarning((object)$"[Avatar] Exception while loading avatar for {steamIdString}: {arg}");
				}
				return null;
			}
		}

		private static void FlipTextureVertically(Texture2D tex)
		{
			int width = ((Texture)tex).width;
			int height = ((Texture)tex).height;
			Color[] pixels = tex.GetPixels();
			Color[] array = (Color[])(object)new Color[pixels.Length];
			for (int i = 0; i < height; i++)
			{
				int sourceIndex = i * width;
				int destinationIndex = (height - 1 - i) * width;
				Array.Copy(pixels, sourceIndex, array, destinationIndex, width);
			}
			tex.SetPixels(array);
			tex.Apply();
		}
	}
	internal static class UpgradeVoteNotification
	{
		private static float _timer = 0f;

		private static string _text = "";

		private const string EmojiMoney = "{$$}";

		private static readonly Color TextColor = new Color(0f, 1f, 0.2f);

		public static void ShowUpgradeAward(string winnerName, string prettyUpgradeName, float duration = 3f)
		{
			if (string.IsNullOrEmpty(winnerName))
			{
				winnerName = "(no one)";
			}
			if (string.IsNullOrEmpty(prettyUpgradeName))
			{
				prettyUpgradeName = "upgrade";
			}
			_timer = duration;
			_text = "<size=26>" + winnerName + "</size> <size=18>Dostal</size>\n<size=26>" + prettyUpgradeName + "</size>";
		}

		public static void Update()
		{
			//IL_003f: 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 (!(_timer <= 0f))
			{
				_timer = Mathf.Max(0f, _timer - Time.deltaTime);
				SemiFunc.UIBigMessage(_text, "{$$}", 28f, TextColor, Color.white);
			}
		}
	}
}