Decompiled source of POG Timer v1.0.0

Mods\POGTimer.dll

Decompiled a day ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using Il2CppGame.Gameplay;
using Il2CppInterop.Runtime.Injection;
using MelonLoader;
using POGMods.Timer;
using Unity.Collections;
using Unity.Netcode;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(PogTimerMelon), "POG Timer", "1.0.0", "largo", "")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("POGTimer")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("POGTimer")]
[assembly: AssemblyTitle("POGTimer")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace POGMods.Timer;

public class PogTimerMelon : MelonMod
{
	public override void OnInitializeMelon()
	{
		//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)
		//IL_0015: Expected O, but got Unknown
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		ClassInjector.RegisterTypeInIl2Cpp<TimerBehaviour>();
		GameObject val = new GameObject("POGTimerRunner");
		Object.DontDestroyOnLoad((Object)val);
		((Object)val).hideFlags = (HideFlags)61;
		val.AddComponent<TimerBehaviour>();
		MelonLogger.Msg("POG Timer 1.0.0 (MelonLoader) loaded.");
	}
}
public class TimerBehaviour : MonoBehaviour
{
	private const float PollInterval = 0.25f;

	private const uint PayloadMagic = 1413959504u;

	private static bool s_unnamedHooked;

	private static UnnamedMessageDelegate s_unnamedDelegate;

	private static float s_netRemaining;

	private static bool s_netPlayedWarning;

	private static bool s_netRoundActive;

	private static bool s_hasNetworkSnapshot;

	private float _pollAccum;

	private GUIStyle _style;

	private GUIStyle _shadowStyle;

	private GUIStyle _smallStyle;

	private GUIStyle _smallShadowStyle;

	private string _timerText = "";

	private string _phaseText = "";

	private bool _loggedHostOnce;

	public TimerBehaviour(IntPtr ptr)
		: base(ptr)
	{
	}

	private void Update()
	{
		_pollAccum += Time.deltaTime;
		if (_pollAccum < 0.25f)
		{
			return;
		}
		_pollAccum = 0f;
		try
		{
			EnsureUnnamedHook();
			NetworkManager singleton = NetworkManager.Singleton;
			if ((Object)(object)singleton != (Object)null && singleton.IsServer)
			{
				TickAuthority(singleton);
			}
			else if ((Object)(object)singleton != (Object)null && singleton.IsClient && !singleton.IsServer)
			{
				TickRemoteClient();
			}
			else
			{
				TickOfflineOrNoNetwork();
			}
		}
		catch
		{
			ClearDisplay();
		}
	}

	private static void EnsureUnnamedHook()
	{
		if (!s_unnamedHooked)
		{
			NetworkManager singleton = NetworkManager.Singleton;
			if (!((Object)(object)singleton == (Object)null))
			{
				MethodInfo method = typeof(TimerBehaviour).GetMethod("OnUnnamedModMessage", BindingFlags.Static | BindingFlags.NonPublic);
				s_unnamedDelegate = UnnamedMessageDelegate.op_Implicit((Action<ulong, FastBufferReader>)Delegate.CreateDelegate(typeof(UnnamedMessageDelegate), method));
				CustomMessagingManager customMessagingManager = singleton.CustomMessagingManager;
				customMessagingManager.OnUnnamedMessage += s_unnamedDelegate;
				s_unnamedHooked = true;
				MelonLogger.Msg("[POGTimer] Subscribed to Netcode unnamed messages (sync for clients).");
			}
		}
	}

	private static void OnUnnamedModMessage(ulong senderClientId, FastBufferReader reader)
	{
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_0031: Unknown result type (might be due to invalid IL or missing references)
		if ((!((Object)(object)NetworkManager.Singleton != (Object)null) || !NetworkManager.Singleton.IsServer) && senderClientId == NetworkManager.ServerClientId && ReadUInt32LE(reader) == 1413959504)
		{
			float num = BitConverter.UInt32BitsToSingle(ReadUInt32LE(reader));
			byte b = default(byte);
			((FastBufferReader)(ref reader)).ReadByteSafe(ref b);
			s_netRoundActive = (b & 1) != 0;
			s_netPlayedWarning = (b & 2) != 0;
			s_netRemaining = num;
			s_hasNetworkSnapshot = true;
		}
	}

	private static uint ReadUInt32LE(FastBufferReader reader)
	{
		byte b = default(byte);
		((FastBufferReader)(ref reader)).ReadByteSafe(ref b);
		byte b2 = default(byte);
		((FastBufferReader)(ref reader)).ReadByteSafe(ref b2);
		byte b3 = default(byte);
		((FastBufferReader)(ref reader)).ReadByteSafe(ref b3);
		byte b4 = default(byte);
		((FastBufferReader)(ref reader)).ReadByteSafe(ref b4);
		return (uint)(b | (b2 << 8) | (b3 << 16) | (b4 << 24));
	}

	private static void WriteHeader(FastBufferWriter writer, uint value)
	{
		((FastBufferWriter)(ref writer)).WriteByteSafe((byte)(value & 0xFFu));
		((FastBufferWriter)(ref writer)).WriteByteSafe((byte)((value >> 8) & 0xFFu));
		((FastBufferWriter)(ref writer)).WriteByteSafe((byte)((value >> 16) & 0xFFu));
		((FastBufferWriter)(ref writer)).WriteByteSafe((byte)((value >> 24) & 0xFFu));
	}

	private static void WriteFloatBits(FastBufferWriter writer, float value)
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		uint value2 = BitConverter.SingleToUInt32Bits(value);
		WriteHeader(writer, value2);
	}

	private void TickAuthority(NetworkManager nm)
	{
		s_hasNetworkSnapshot = false;
		GameMode_Round instance = GameMode_Round.Instance;
		if ((Object)(object)instance == (Object)null || !instance.m_gameStarted)
		{
			ClearDisplay();
			BroadcastUnnamed(nm, active: false, 0f, playedWarning: false);
			return;
		}
		float elapsedGameTime = instance.ElapsedGameTime;
		float roundTime = instance.RoundTime;
		float num = roundTime - elapsedGameTime;
		if (!_loggedHostOnce)
		{
			MelonLogger.Msg($"[POGTimer] Host round sync: total={roundTime}s, elapsed={elapsedGameTime:F1}s");
			_loggedHostOnce = true;
		}
		ApplyDisplayFromRound(num, instance.m_playedWarning);
		BroadcastUnnamed(nm, active: true, Mathf.Max(0f, num), instance.m_playedWarning);
	}

	private static void BroadcastUnnamed(NetworkManager nm, bool active, float remaining, bool playedWarning)
	{
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		byte b = 0;
		if (active)
		{
			b = (byte)(b | 1u);
		}
		if (playedWarning)
		{
			b = (byte)(b | 2u);
		}
		FastBufferWriter val = default(FastBufferWriter);
		((FastBufferWriter)(ref val))..ctor(32, (Allocator)2, -1);
		try
		{
			WriteHeader(val, 1413959504u);
			WriteFloatBits(val, remaining);
			((FastBufferWriter)(ref val)).WriteByteSafe(b);
			nm.CustomMessagingManager.SendUnnamedMessageToAll(val, (NetworkDelivery)2);
		}
		finally
		{
			((FastBufferWriter)(ref val)).Dispose();
		}
	}

	private void TickRemoteClient()
	{
		if (!s_hasNetworkSnapshot || !s_netRoundActive)
		{
			ClearDisplay();
		}
		else
		{
			ApplyDisplayFromNetwork(s_netRemaining, s_netPlayedWarning);
		}
	}

	private void TickOfflineOrNoNetwork()
	{
		s_hasNetworkSnapshot = false;
		GameMode_Round instance = GameMode_Round.Instance;
		if ((Object)(object)instance == (Object)null || !instance.m_gameStarted)
		{
			ClearDisplay();
			return;
		}
		float elapsedGameTime = instance.ElapsedGameTime;
		float remaining = instance.RoundTime - elapsedGameTime;
		ApplyDisplayFromRound(remaining, instance.m_playedWarning);
	}

	private void ApplyDisplayFromRound(float remaining, bool playedWarning)
	{
		if (remaining <= 0f)
		{
			_timerText = "00:00";
			_phaseText = "TIME'S UP";
			return;
		}
		int value = (int)(remaining / 60f);
		int value2 = (int)(remaining % 60f);
		_timerText = $"{value:D2}:{value2:D2}";
		if (remaining < 60f)
		{
			_phaseText = "HURRY!";
		}
		else if (playedWarning)
		{
			_phaseText = "WARNING";
		}
		else
		{
			_phaseText = "";
		}
	}

	private void ApplyDisplayFromNetwork(float remaining, bool playedWarning)
	{
		if (remaining <= 0f)
		{
			_timerText = "00:00";
			_phaseText = "TIME'S UP";
			return;
		}
		int value = (int)(remaining / 60f);
		int value2 = (int)(remaining % 60f);
		_timerText = $"{value:D2}:{value2:D2}";
		if (remaining < 60f)
		{
			_phaseText = "HURRY!";
		}
		else if (playedWarning)
		{
			_phaseText = "WARNING";
		}
		else
		{
			_phaseText = "";
		}
	}

	private void ClearDisplay()
	{
		_timerText = "";
		_phaseText = "";
	}

	private void OnGUI()
	{
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Expected O, but got Unknown
		//IL_005e: 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_0079: Expected O, but got Unknown
		//IL_0098: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b7: Expected O, but got Unknown
		//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
		//IL_0107: Unknown result type (might be due to invalid IL or missing references)
		//IL_0111: Expected O, but got Unknown
		//IL_0130: Unknown result type (might be due to invalid IL or missing references)
		//IL_0175: Unknown result type (might be due to invalid IL or missing references)
		//IL_016e: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_0203: Unknown result type (might be due to invalid IL or missing references)
		//IL_0227: Unknown result type (might be due to invalid IL or missing references)
		if (!string.IsNullOrEmpty(_timerText))
		{
			if (_style == null)
			{
				_style = new GUIStyle(GUI.skin.label);
				_style.fontSize = 30;
				_style.fontStyle = (FontStyle)1;
				_style.alignment = (TextAnchor)2;
				_style.normal.textColor = Color.white;
				_shadowStyle = new GUIStyle(_style);
				_shadowStyle.normal.textColor = new Color(0f, 0f, 0f, 0.7f);
				_smallStyle = new GUIStyle(GUI.skin.label);
				_smallStyle.fontSize = 16;
				_smallStyle.fontStyle = (FontStyle)1;
				_smallStyle.alignment = (TextAnchor)2;
				_smallStyle.normal.textColor = new Color(1f, 0.8f, 0.3f);
				_smallShadowStyle = new GUIStyle(_smallStyle);
				_smallShadowStyle.normal.textColor = new Color(0f, 0f, 0f, 0.7f);
			}
			bool flag = _phaseText == "HURRY!" || _phaseText == "TIME'S UP";
			_style.normal.textColor = (flag ? Color.red : Color.white);
			float num = 200f;
			float num2 = (float)Screen.width - num - 20f;
			float num3 = 15f;
			GUI.Label(new Rect(num2 + 2f, num3 + 2f, num, 40f), _timerText, _shadowStyle);
			GUI.Label(new Rect(num2, num3, num, 40f), _timerText, _style);
			if (!string.IsNullOrEmpty(_phaseText))
			{
				GUI.Label(new Rect(num2 + 2f, num3 + 36f, num, 25f), _phaseText, _smallShadowStyle);
				GUI.Label(new Rect(num2, num3 + 34f, num, 25f), _phaseText, _smallStyle);
			}
		}
	}
}