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;
}
}
}