Decompiled source of BombTimer v1.0.0

Antro.TimerBomb.dll

Decompiled a week ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.IL2CPP;
using BepInEx.Logging;
using CrabDevKit.Intermediary;
using CrabDevKit.Utilities;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using SteamworksNative;
using TMPro;
using UnhollowerBaseLib;
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(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("Antro.TimerBomb")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Antro.TimerBomb")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("Antro.TimerBomb")]
[assembly: AssemblyTitle("Antro.TimerBomb")]
[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.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Antro.TimerBomb
{
	[BepInPlugin("Antro.TimerBomb", "Antro.TimerBomb", "1.0.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public sealed class Plugin : BasePlugin
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static MessageHandler <0>__HandleTimerPacket;
		}

		public static Plugin Instance;

		internal static Harmony Harmony;

		internal static TextMeshProUGUI _myTimerText;

		internal static TextMeshProUGUI _gameOriginalTimer;

		internal static PropertyInfo _propTimerObject;

		internal static PropertyInfo _propTimerValue;

		internal static bool _fieldsCached = false;

		public const string CHANNEL_ID = "Antro:BombTimer";

		private static float _lastSentTime = 0f;

		private static int _lastChatInteger = -1;

		private static float _syncedTime = 0f;

		public override void Load()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Expected O, but got Unknown
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Expected O, but got Unknown
			Instance = this;
			Harmony = new Harmony("Antro.TimerBomb");
			((BasePlugin)this).Log.LogInfo((object)">>> [Antro.TimerBomb] Loading v1.0.0.0 (CrabNet Sync & Chat)...");
			object obj = <>O.<0>__HandleTimerPacket;
			if (obj == null)
			{
				MessageHandler val = HandleTimerPacket;
				<>O.<0>__HandleTimerPacket = val;
				obj = (object)val;
			}
			CrabNet.RegisterMessageHandler("Antro:BombTimer", (MessageHandler)obj);
			MethodInfo methodInfo = AccessTools.Method(typeof(MonoBehaviourPublicGaroloGaObInCacachGaUnique), "Update", (Type[])null, (Type[])null);
			if (methodInfo != null)
			{
				Harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(Plugin).GetMethod("GameUiPostfix", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
		}

		private static void HandleTimerPacket(ulong senderId, ObjectPublicIDisposableLi1ByInByBoUnique packet)
		{
			float syncedTime = PacketExtensions.ReadFloat(packet, true);
			_syncedTime = syncedTime;
		}

		public static void GameUiPostfix(MonoBehaviourPublicGaroloGaObInCacachGaUnique __instance)
		{
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			GameModePublicInSiLiSiIn1UIObBoUnique val = Object.FindObjectOfType<GameModePublicInSiLiSiIn1UIObBoUnique>();
			if ((Object)(object)val == (Object)null || !((Behaviour)val).enabled)
			{
				if ((Object)(object)_myTimerText != (Object)null && ((Component)_myTimerText).gameObject.activeSelf)
				{
					((Component)_myTimerText).gameObject.SetActive(false);
				}
				_lastChatInteger = -1;
				return;
			}
			if ((Object)(object)_gameOriginalTimer == (Object)null)
			{
				_gameOriginalTimer = FindOriginalTimer(((Component)__instance).gameObject);
			}
			if ((Object)(object)_myTimerText == (Object)null && (Object)(object)_gameOriginalTimer != (Object)null)
			{
				CreateCustomUi(_gameOriginalTimer);
			}
			if ((Object)(object)_myTimerText != (Object)null)
			{
				if (!((Component)_myTimerText).gameObject.activeSelf)
				{
					((Component)_myTimerText).gameObject.SetActive(true);
				}
				((TMP_Text)_myTimerText).transform.position = new Vector3(1872.4f, 947.3591f, 0f);
				ProcessGameMode(val);
			}
		}

		private static void ProcessGameMode(GameModePublicInSiLiSiIn1UIObBoUnique mode)
		{
			bool flag = MonoBehaviourPublicObInUIgaStCSBoStcuCSUnique.Instance.IsLobbyOwner();
			float num = 0f;
			if (flag)
			{
				float bombTimerFromHelperObject = GetBombTimerFromHelperObject(mode);
				num = bombTimerFromHelperObject;
				if (Time.time - _lastSentTime > 0.1f)
				{
					_lastSentTime = Time.time;
					SendTimeToClients(bombTimerFromHelperObject);
				}
				HandleHostChat(bombTimerFromHelperObject);
			}
			else
			{
				if (_syncedTime > 0f)
				{
					_syncedTime -= Time.deltaTime;
				}
				if (_syncedTime < 0f)
				{
					_syncedTime = 0f;
				}
				num = _syncedTime;
			}
			UpdateText(num);
		}

		private static void SendTimeToClients(float time)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//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_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			ObjectPublicIDisposableLi1ByInByBoUnique val = new ObjectPublicIDisposableLi1ByInByBoUnique();
			PacketExtensions.Write(val, time);
			CSteamID currentLobby = MonoBehaviourPublicObInUIgaStCSBoStcuCSUnique.Instance.currentLobby;
			int numLobbyMembers = SteamMatchmaking.GetNumLobbyMembers(currentLobby);
			List<ulong> list = new List<ulong>();
			for (int i = 0; i < numLobbyMembers; i++)
			{
				CSteamID lobbyMemberByIndex = SteamMatchmaking.GetLobbyMemberByIndex(currentLobby, i);
				if (lobbyMemberByIndex.m_SteamID != MonoBehaviourPublicObInUIgaStCSBoStcuCSUnique.Instance.field_Private_CSteamID_0.m_SteamID)
				{
					list.Add(lobbyMemberByIndex.m_SteamID);
				}
			}
			if (list.Count > 0)
			{
				CrabNet.SendMessage("Antro:BombTimer", val, (IEnumerable<ulong>)list);
			}
		}

		private static void HandleHostChat(float time)
		{
			if (time <= 0f)
			{
				return;
			}
			int num = Mathf.CeilToInt(time);
			if (num != _lastChatInteger)
			{
				bool flag = false;
				if (num == 20 || num == 10 || num == 5 || num == 3 || num == 2 || num == 1)
				{
					flag = true;
				}
				if (flag)
				{
					string msg = $"BOMB: {num}s";
					SendChatMessage(msg);
				}
				_lastChatInteger = num;
			}
		}

		private static void SendChatMessage(string msg)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			try
			{
				MonoBehaviourPublicInInUnique.SendChatMessage(1uL, msg);
			}
			catch (Exception ex)
			{
				ManualLogSource log = ((BasePlugin)Instance).Log;
				bool flag = default(bool);
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(21, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Failed to send chat: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
				}
				log.LogError(val);
			}
		}

		private static void UpdateText(float bombTime)
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			if (bombTime <= 0f)
			{
				((TMP_Text)_myTimerText).text = "";
				return;
			}
			((TMP_Text)_myTimerText).text = $"{bombTime:F2}";
			if (bombTime <= 5f)
			{
				((Graphic)_myTimerText).color = Color.red;
			}
			else if (bombTime <= 10f)
			{
				((Graphic)_myTimerText).color = new Color(1f, 0.5f, 0f);
			}
			else if (bombTime <= 20f)
			{
				((Graphic)_myTimerText).color = Color.yellow;
			}
			else
			{
				((Graphic)_myTimerText).color = Color.green;
			}
		}

		private static float GetBombTimerFromHelperObject(GameModePublicInSiLiSiIn1UIObBoUnique mode)
		{
			if (!_fieldsCached)
			{
				Type type = ((object)mode).GetType();
				_propTimerObject = type.GetProperty("field_Private_ObjectPublicSiBoSiSiSiUnique_0", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (_propTimerObject != null)
				{
					object value = _propTimerObject.GetValue(mode);
					if (value != null)
					{
						Type type2 = value.GetType();
						_propTimerValue = type2.GetProperty("field_Private_Single_0", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
						_fieldsCached = true;
					}
				}
			}
			if (!_fieldsCached || _propTimerObject == null || _propTimerValue == null)
			{
				return 0f;
			}
			try
			{
				object value2 = _propTimerObject.GetValue(mode);
				if (value2 == null)
				{
					return 0f;
				}
				return (float)_propTimerValue.GetValue(value2);
			}
			catch
			{
				return 0f;
			}
		}

		private static TextMeshProUGUI FindOriginalTimer(GameObject root)
		{
			Transform val = root.transform.Find("Status/TopRight/PlayersLeft/Timer/Text (TMP)");
			if ((Object)(object)val == (Object)null)
			{
				val = root.transform.Find("Status/TopRight/Timer/Text (TMP)");
			}
			if ((Object)(object)val == (Object)null)
			{
				Il2CppArrayBase<TextMeshProUGUI> componentsInChildren = root.GetComponentsInChildren<TextMeshProUGUI>(true);
				foreach (TextMeshProUGUI item in componentsInChildren)
				{
					if (((Object)item).name == "Text (TMP)" && ((Object)((TMP_Text)item).transform.parent).name == "Timer")
					{
						return item;
					}
				}
			}
			return ((Object)(object)val != (Object)null) ? ((Component)val).GetComponent<TextMeshProUGUI>() : null;
		}

		private static void CreateCustomUi(TextMeshProUGUI original)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			GameObject val = new GameObject("AntroBombTimer_V15");
			val.transform.SetParent(((TMP_Text)original).transform.parent.parent.parent, false);
			_myTimerText = val.AddComponent<TextMeshProUGUI>();
			((TMP_Text)_myTimerText).font = ((TMP_Text)original).font;
			((TMP_Text)_myTimerText).fontSize = ((TMP_Text)original).fontSize * 0.9f;
			((TMP_Text)_myTimerText).enableWordWrapping = false;
			((TMP_Text)_myTimerText).alignment = (TextAlignmentOptions)514;
			((TMP_Text)_myTimerText).text = "";
		}
	}
}