Files
MiraExporter/Patches/GameStartTimePatch.cs
2025-10-10 23:00:21 +02:00

80 lines
2.8 KiB
C#

using HarmonyLib;
using UnityEngine;
namespace TownOfUsStatsExporter.Patches;
/// <summary>
/// Tracks when the game actually starts (after intro cutscene ends).
/// This allows calculating actual game duration instead of lobby time.
/// </summary>
[HarmonyPatch]
public static class GameStartTimePatch
{
/// <summary>
/// Time when the game started (after intro cutscene), in Unity Time.time format.
/// Null if game hasn't started yet.
/// </summary>
public static float? GameStartTime { get; private set; }
/// <summary>
/// Duration of the last completed game in seconds.
/// Set when the game ends, persists until next game starts.
/// </summary>
public static float LastGameDuration { get; private set; }
/// <summary>
/// Gets the duration of the last completed game in seconds.
/// This value is set when the game ends and remains available for async export.
/// </summary>
public static float GetGameDuration()
{
return LastGameDuration;
}
/// <summary>
/// Patch on ShipStatus.Begin - called when the game round starts.
/// This is more reliable than IntroCutscene.OnDestroy as it's always called when gameplay begins.
/// </summary>
[HarmonyPatch(typeof(ShipStatus), nameof(ShipStatus.Begin))]
[HarmonyPostfix]
public static void OnShipStatusBegin()
{
GameStartTime = Time.time;
LastGameDuration = 0f; // Reset duration for new game
TownOfUsStatsPlugin.Logger.LogInfo($"Game started at Time.time = {GameStartTime.Value:F2}");
}
/// <summary>
/// Calculate and store game duration when game ends.
/// This runs before the export, so duration is available for async export.
/// </summary>
[HarmonyPatch(typeof(AmongUsClient), nameof(AmongUsClient.OnGameEnd))]
[HarmonyPrefix]
public static void OnGameEndPrefix()
{
if (GameStartTime.HasValue)
{
LastGameDuration = Time.time - GameStartTime.Value;
TownOfUsStatsPlugin.Logger.LogInfo($"Game ended. Duration: {LastGameDuration:F2} seconds ({LastGameDuration / 60:F2} minutes)");
}
else
{
LastGameDuration = 0f;
TownOfUsStatsPlugin.Logger.LogWarning("Game ended but GameStartTime was not set! Duration will be 0.");
}
}
/// <summary>
/// Clear game start time after game ends to prepare for next game.
/// LastGameDuration is preserved for async export.
/// </summary>
[HarmonyPatch(typeof(AmongUsClient), nameof(AmongUsClient.OnGameEnd))]
[HarmonyPostfix]
[HarmonyPriority(Priority.Last)]
public static void OnGameEndPostfix()
{
GameStartTime = null;
TownOfUsStatsPlugin.Logger.LogInfo("Game start time cleared (duration preserved for export)");
}
}