Decompiled source of CustomStatTracking v1.7.0

HighQuotaStatTracking.dll

Decompiled a month 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.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using HighQuotaHelper;
using HighQuotaStatTracking;
using HighQuotaStatTracking.Patches;
using Microsoft.CodeAnalysis;
using StaticNetcodeLib;
using Unity.Netcode;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("HighQuotaStatTracking")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+508a25c1f42b3122ad2794362ffe9c6d73659da0")]
[assembly: AssemblyProduct("My first plugin")]
[assembly: AssemblyTitle("HighQuotaStatTracking")]
[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 HighQuotaHelper
{
	[StaticNetcode]
	public class NetworkRPC
	{
		public delegate void ReceivedStats(ClientPlayer player);

		public static event ReceivedStats OnReceivedStats;

		[ServerRpc(RequireOwnership = false)]
		public static void ReportStatsServerRpc(ClientPlayer playerStats)
		{
			if (NetworkRPC.OnReceivedStats != null)
			{
				NetworkRPC.OnReceivedStats(playerStats);
			}
		}
	}
}
namespace HighQuotaStatTracking
{
	public class ClientPlayer
	{
		public ulong SteamID { get; set; }

		public DateTime? DiedTime { get; set; }

		public ushort Jumps { get; set; }

		public short DoorsOpened { get; set; }

		public float DistanceTraveled { get; set; }

		public float DistanceJetpacked { get; set; }

		public float DistanceCrouched { get; set; }

		public float DistanceSprinted { get; set; }

		public float DistanceWalked { get; set; }

		public float DistanceLaddered { get; set; }

		public float DistanceCruisered { get; set; }

		public TimeSpan TotalWalkieTime { get; set; }

		public float TotalFlashlightTime { get; set; }

		public byte DamageTaken { get; set; }

		public float TotalStamina { get; set; }

		public int StaminaCounts { get; set; }

		public float TimeSpentAbove19PoundsInside { get; set; }

		public Dictionary<ulong, DateTime> ObtainedItems { get; set; } = new Dictionary<ulong, DateTime>();

	}
	[BepInPlugin("HighQuotaStatTracking", "High Quota Stat Tracking", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		internal static ManualLogSource LogSource;

		private readonly Harmony harmony = new Harmony("HighQuotaHelper");

		private void Awake()
		{
			LogSource = ((BaseUnityPlugin)this).Logger;
			LogSource.LogInfo((object)"Plugin HighQuotaStatTracking is loaded!");
			harmony.PatchAll(typeof(StartOfRoundPatch));
			harmony.PatchAll(typeof(PlayerControllerBPatch));
			harmony.PatchAll(typeof(WalkieTalkiePatch));
			harmony.PatchAll(typeof(DoorLockPatch));
			harmony.PatchAll(typeof(BeltBagItemPatch));
			LogSource.LogInfo((object)"Patched");
		}
	}
	public class StatManager
	{
		private static StatManager _instance;

		private Dictionary<ulong, DateTime> m_GrabbedObjects = new Dictionary<ulong, DateTime>();

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

		public bool IsOnMoon { get; private set; }

		public DateTime LandedTime { get; private set; }

		public ClientPlayer LocalPlayer { get; private set; }

		public void ResetLocalPlayer()
		{
			LocalPlayer = new ClientPlayer
			{
				SteamID = GameNetworkManager.Instance.localPlayerController.playerSteamId
			};
		}

		public void StartRound()
		{
			ResetLocalPlayer();
			IsOnMoon = true;
			LandedTime = DateTime.UtcNow;
			m_GrabbedObjects.Clear();
		}

		public void EndRound()
		{
			WalkieTalkiePatch.StartUseTime = null;
			IsOnMoon = false;
			NetworkRPC.ReportStatsServerRpc(LocalPlayer);
		}

		public void TrackObjectGrabbed(ulong networkID)
		{
			m_GrabbedObjects.Add(networkID, DateTime.UtcNow);
		}
	}
}
namespace HighQuotaStatTracking.Patches
{
	public static class BeltBagItemPatch
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(BeltBagItem), "PutObjectInBagLocalClient")]
		private static void PutObjectInBagLocalClient(GrabbableObject gObject, BeltBagItem __instance)
		{
			if (StatManager.Instance.IsOnMoon && !((Object)(object)((GrabbableObject)__instance).playerHeldBy == (Object)null) && ((NetworkBehaviour)((GrabbableObject)__instance).playerHeldBy).IsClient)
			{
				ClientPlayer localPlayer = StatManager.Instance.LocalPlayer;
				if (localPlayer != null && localPlayer.SteamID == ((GrabbableObject)__instance).playerHeldBy.playerSteamId)
				{
					Plugin.LogSource.LogInfo((object)$"Picked up {((NetworkBehaviour)gObject).NetworkObject.NetworkObjectId} in belt bag at {DateTime.UtcNow}");
					localPlayer.ObtainedItems.TryAdd(((NetworkBehaviour)gObject).NetworkObject.NetworkObjectId, DateTime.UtcNow);
				}
			}
		}
	}
	public class DoorLockPatch
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(DoorLock), "OpenOrCloseDoor")]
		private static void OpenOrCloseDoor(PlayerControllerB playerWhoTriggered, DoorLock __instance)
		{
			if (!((Object)(object)playerWhoTriggered != (Object)(object)GameNetworkManager.Instance.localPlayerController) && StatManager.Instance.IsOnMoon && (bool)typeof(DoorLock).GetField("isDoorOpened", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(__instance))
			{
				StatManager.Instance.LocalPlayer.DoorsOpened++;
			}
		}
	}
	public class PlayerControllerBPatch
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(PlayerControllerB), "LateUpdate")]
		public static void LateUpdate(PlayerControllerB __instance)
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//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_0063: Unknown result type (might be due to invalid IL or missing references)
			if (!StatManager.Instance.IsOnMoon || __instance.isInElevator)
			{
				return;
			}
			ClientPlayer localPlayer = StatManager.Instance.LocalPlayer;
			if (!__instance.isPlayerControlled || __instance.isPlayerDead || localPlayer == null || localPlayer.SteamID != __instance.playerSteamId)
			{
				return;
			}
			Vector3 val = __instance.oldPlayerPosition - ((Component)__instance).transform.localPosition;
			float magnitude = ((Vector3)(ref val)).magnitude;
			if (!__instance.teleportedLastFrame)
			{
				bool flag = false;
				VehicleController val2 = Object.FindObjectOfType<VehicleController>();
				if (__instance.jetpackControls && (Object)(object)__instance.ItemSlots[__instance.currentItemSlot] != (Object)null)
				{
					GrabbableObject obj = __instance.ItemSlots[__instance.currentItemSlot];
					JetpackItem val3 = (JetpackItem)(object)((obj is JetpackItem) ? obj : null);
					if (val3 != null)
					{
						if (typeof(JetpackItem).GetField("jetpackActivated", BindingFlags.Instance | BindingFlags.NonPublic) == null)
						{
							Plugin.LogSource.LogError((object)"Jetpack AHHHH");
						}
						flag = (bool)typeof(JetpackItem).GetField("jetpackActivated", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(val3);
					}
				}
				if (flag)
				{
					localPlayer.DistanceJetpacked += magnitude;
				}
				else if ((Object)(object)__instance.physicsParent != (Object)null && (Object)(object)val2 != (Object)null && (Object)(object)((Component)val2).transform != (Object)null && (Object)(object)__instance.physicsParent == (Object)(object)((Component)val2).transform)
				{
					localPlayer.DistanceCruisered += magnitude;
				}
				else if (__instance.isSprinting)
				{
					localPlayer.DistanceSprinted += magnitude;
				}
				else if (__instance.isCrouching)
				{
					localPlayer.DistanceCrouched += magnitude;
				}
				else
				{
					localPlayer.DistanceWalked += magnitude;
				}
				localPlayer.DistanceTraveled += magnitude;
			}
			else if (__instance.teleportedLastFrame && __instance.isClimbingLadder)
			{
				localPlayer.DistanceLaddered += magnitude;
				localPlayer.DistanceTraveled += magnitude;
			}
			localPlayer.TotalStamina += __instance.sprintMeter;
			localPlayer.StaminaCounts++;
			if (Mathf.RoundToInt(Mathf.Clamp(__instance.carryWeight - 1f, 0f, 100f) * 105f) > 19 && __instance.isInsideFactory)
			{
				localPlayer.TimeSpentAbove19PoundsInside += Time.deltaTime;
			}
			GrabbableObject[] itemSlots = __instance.ItemSlots;
			foreach (GrabbableObject val4 in itemSlots)
			{
				if ((Object)(object)val4 != (Object)null)
				{
					FlashlightItem val5 = (FlashlightItem)(object)((val4 is FlashlightItem) ? val4 : null);
					if (val5 != null && ((GrabbableObject)val5).isBeingUsed)
					{
						localPlayer.TotalFlashlightTime += Time.deltaTime;
						break;
					}
				}
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(PlayerControllerB), "PlayerJump")]
		public static void PlayerJump(PlayerControllerB __instance)
		{
			if (StatManager.Instance.IsOnMoon)
			{
				ClientPlayer localPlayer = StatManager.Instance.LocalPlayer;
				if (localPlayer != null && localPlayer.SteamID == __instance.playerSteamId)
				{
					localPlayer.Jumps++;
				}
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(PlayerControllerB), "DamagePlayerClientRpc")]
		public static void DamagePlayerClientRpc(int damageNumber, PlayerControllerB __instance)
		{
			if (StatManager.Instance.IsOnMoon)
			{
				ClientPlayer localPlayer = StatManager.Instance.LocalPlayer;
				if (localPlayer != null && localPlayer.SteamID == __instance.playerSteamId)
				{
					localPlayer.DamageTaken += (byte)damageNumber;
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(PlayerControllerB), "KillPlayer")]
		private static void KillPlayer(PlayerControllerB __instance)
		{
			if (StatManager.Instance.IsOnMoon && ((NetworkBehaviour)__instance).IsOwner && __instance.isPlayerDead)
			{
				StatManager.Instance.LocalPlayer.DiedTime = DateTime.UtcNow;
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(PlayerControllerB), "GrabObjectClientRpc")]
		private static void GrabObjectClientRpc(bool grabValidated, NetworkObjectReference grabbedObject, PlayerControllerB __instance)
		{
			if (StatManager.Instance.IsOnMoon || !((NetworkBehaviour)__instance).IsClient)
			{
				ClientPlayer localPlayer = StatManager.Instance.LocalPlayer;
				NetworkObject val = default(NetworkObject);
				if (localPlayer != null && localPlayer.SteamID == __instance.playerSteamId && grabValidated && ((NetworkObjectReference)(ref grabbedObject)).TryGet(ref val, (NetworkManager)null))
				{
					Plugin.LogSource.LogInfo((object)$"Picked up {val.NetworkObjectId} at {DateTime.UtcNow}");
					localPlayer.ObtainedItems.TryAdd(val.NetworkObjectId, DateTime.UtcNow);
				}
			}
		}
	}
	public class StartOfRoundPatch
	{
		[HarmonyPatch(typeof(StartOfRound), "openingDoorsSequence")]
		[HarmonyPrefix]
		public static void openingDoorsSequence(StartOfRound __instance)
		{
			StatManager.Instance.StartRound();
		}

		[HarmonyPatch(typeof(StartOfRound), "ShipHasLeft")]
		[HarmonyPrefix]
		public static void ShipHasLeft(StartOfRound __instance)
		{
			StatManager.Instance.EndRound();
		}
	}
	public class WalkieTalkiePatch
	{
		public static DateTime? StartUseTime;

		[HarmonyPrefix]
		[HarmonyPatch(typeof(WalkieTalkie), "SetLocalClientSpeaking")]
		private static void SetLocalClientSpeaking(bool speaking, WalkieTalkie __instance)
		{
			if ((Object)(object)((GrabbableObject)__instance).playerHeldBy != (Object)(object)GameNetworkManager.Instance.localPlayerController || !StatManager.Instance.IsOnMoon)
			{
				return;
			}
			if (speaking)
			{
				StartUseTime = DateTime.UtcNow;
				return;
			}
			if (!StartUseTime.HasValue)
			{
				StartUseTime = StatManager.Instance.LandedTime;
			}
			StatManager.Instance.LocalPlayer.TotalWalkieTime += DateTime.UtcNow - StartUseTime.Value;
		}
	}
}