Decompiled source of MissedScrap v1.1.2

plugins/MissedScrap.dll

Decompiled a month ago
using System;
using System.Collections;
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 HarmonyLib;
using Microsoft.CodeAnalysis;
using MissedScrap.Patches;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
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(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("MissedScrap")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Shows missed scrap items at end of day")]
[assembly: AssemblyFileVersion("1.1.2.0")]
[assembly: AssemblyInformationalVersion("1.1.2")]
[assembly: AssemblyProduct("MissedScrap")]
[assembly: AssemblyTitle("MissedScrap")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.2.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 MissedScrap
{
	public class MissedScrapUI : MonoBehaviour
	{
		private GameObject uiPanel;

		private Text titleText;

		private Text itemsText;

		private Text totalText;

		private Image backgroundImage;

		private bool isShowing = false;

		private void Update()
		{
			if (isShowing && Keyboard.current != null && ((ButtonControl)Keyboard.current.escapeKey).wasPressedThisFrame)
			{
				HideUI();
			}
		}

		public void ShowMissedScrap(List<(string name, int value)> missedItems, int totalValue)
		{
			if (!isShowing)
			{
				CreateUI();
				PopulateUI(missedItems, totalValue);
				isShowing = true;
				((MonoBehaviour)this).Invoke("HideUI", 15f);
			}
		}

		private void CreateUI()
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Expected O, but got Unknown
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Expected O, but got Unknown
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_021b: Unknown result type (might be due to invalid IL or missing references)
			//IL_022b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0232: Expected O, but got Unknown
			//IL_025b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0272: Unknown result type (might be due to invalid IL or missing references)
			//IL_0289: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0313: Unknown result type (might be due to invalid IL or missing references)
			//IL_0323: Unknown result type (might be due to invalid IL or missing references)
			//IL_032a: Expected O, but got Unknown
			//IL_0353: Unknown result type (might be due to invalid IL or missing references)
			//IL_036a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0381: Unknown result type (might be due to invalid IL or missing references)
			//IL_0398: Unknown result type (might be due to invalid IL or missing references)
			//IL_03af: Unknown result type (might be due to invalid IL or missing references)
			//IL_040d: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)uiPanel != (Object)null)
			{
				Object.Destroy((Object)(object)uiPanel);
			}
			uiPanel = new GameObject("MissedScrapPanel");
			Canvas val = uiPanel.AddComponent<Canvas>();
			val.renderMode = (RenderMode)0;
			val.sortingOrder = 1000;
			CanvasScaler val2 = uiPanel.AddComponent<CanvasScaler>();
			val2.uiScaleMode = (ScaleMode)1;
			val2.referenceResolution = new Vector2(1920f, 1080f);
			GameObject val3 = new GameObject("Background");
			val3.transform.SetParent(uiPanel.transform, false);
			RectTransform val4 = val3.AddComponent<RectTransform>();
			val4.anchorMin = new Vector2(1f, 0f);
			val4.anchorMax = new Vector2(1f, 1f);
			val4.pivot = new Vector2(1f, 0.5f);
			val4.sizeDelta = new Vector2(384f, 0f);
			backgroundImage = val3.AddComponent<Image>();
			((Graphic)backgroundImage).color = new Color(0.1f, 0.1f, 0.1f, 0.92f);
			GameObject val5 = new GameObject("Title");
			val5.transform.SetParent(val3.transform, false);
			RectTransform val6 = val5.AddComponent<RectTransform>();
			val6.anchorMin = new Vector2(0f, 1f);
			val6.anchorMax = new Vector2(1f, 1f);
			val6.pivot = new Vector2(0.5f, 1f);
			val6.sizeDelta = new Vector2(-20f, 45f);
			val6.anchoredPosition = new Vector2(0f, -10f);
			titleText = val5.AddComponent<Text>();
			titleText.font = Resources.GetBuiltinResource<Font>("Arial.ttf");
			titleText.fontSize = 24;
			titleText.fontStyle = (FontStyle)1;
			titleText.alignment = (TextAnchor)4;
			((Graphic)titleText).color = Color.white;
			GameObject val7 = new GameObject("Total");
			val7.transform.SetParent(val3.transform, false);
			RectTransform val8 = val7.AddComponent<RectTransform>();
			val8.anchorMin = new Vector2(0f, 1f);
			val8.anchorMax = new Vector2(1f, 1f);
			val8.pivot = new Vector2(0.5f, 1f);
			val8.sizeDelta = new Vector2(-20f, 55f);
			val8.anchoredPosition = new Vector2(0f, -60f);
			totalText = val7.AddComponent<Text>();
			totalText.font = Resources.GetBuiltinResource<Font>("Arial.ttf");
			totalText.fontSize = 22;
			totalText.fontStyle = (FontStyle)1;
			totalText.alignment = (TextAnchor)4;
			((Graphic)totalText).color = Color.yellow;
			GameObject val9 = new GameObject("ItemsList");
			val9.transform.SetParent(val3.transform, false);
			RectTransform val10 = val9.AddComponent<RectTransform>();
			val10.anchorMin = new Vector2(0f, 0f);
			val10.anchorMax = new Vector2(1f, 1f);
			val10.pivot = new Vector2(0.5f, 0.5f);
			val10.offsetMin = new Vector2(20f, 20f);
			val10.offsetMax = new Vector2(-20f, -135f);
			itemsText = val9.AddComponent<Text>();
			itemsText.font = Resources.GetBuiltinResource<Font>("Arial.ttf");
			itemsText.fontSize = 18;
			itemsText.alignment = (TextAnchor)0;
			((Graphic)itemsText).color = new Color(1f, 0.9f, 0.7f);
			itemsText.horizontalOverflow = (HorizontalWrapMode)0;
			itemsText.verticalOverflow = (VerticalWrapMode)1;
			itemsText.supportRichText = true;
			Object.DontDestroyOnLoad((Object)(object)uiPanel);
		}

		private void PopulateUI(List<(string name, int value)> missedItems, int totalValue)
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			Color color = default(Color);
			string text;
			if (totalValue == 0)
			{
				((Color)(ref color))..ctor(0.1f, 0.4f, 0.1f, 0.92f);
				text = "PERFECT!";
				((Graphic)titleText).color = new Color(0.3f, 1f, 0.3f);
			}
			else if (totalValue < 50)
			{
				((Color)(ref color))..ctor(0.4f, 0.4f, 0.1f, 0.92f);
				text = "MINOR LOSS";
				((Graphic)titleText).color = new Color(1f, 1f, 0.3f);
			}
			else if (totalValue < 150)
			{
				((Color)(ref color))..ctor(0.5f, 0.3f, 0.1f, 0.92f);
				text = "SIGNIFICANT LOSS";
				((Graphic)titleText).color = new Color(1f, 0.6f, 0.2f);
			}
			else
			{
				((Color)(ref color))..ctor(0.4f, 0.1f, 0.1f, 0.92f);
				text = "MAJOR LOSS!";
				((Graphic)titleText).color = new Color(1f, 0.3f, 0.3f);
			}
			((Graphic)backgroundImage).color = color;
			if (missedItems.Count == 0)
			{
				titleText.text = "NO SCRAP MISSED!";
				totalText.text = "";
				itemsText.text = "\n\nPerfect collection!\n\nYou got everything!";
				return;
			}
			titleText.text = text;
			totalText.text = $"{missedItems.Count} items missed worth ${totalValue}";
			string text2 = "";
			foreach (var missedItem in missedItems)
			{
				text2 += $"• ${missedItem.value} - {missedItem.name}\n";
			}
			itemsText.text = text2;
			Plugin.Logger.LogInfo((object)$"Displayed {missedItems.Count} missed items worth ${totalValue}");
		}

		public void HideUI()
		{
			if ((Object)(object)uiPanel != (Object)null)
			{
				Object.Destroy((Object)(object)uiPanel);
				uiPanel = null;
			}
			isShowing = false;
		}

		private void OnDestroy()
		{
			HideUI();
		}
	}
	[BepInPlugin("com.psyko.missedscrap", "MissedScrap", "1.1.2")]
	public class Plugin : BaseUnityPlugin
	{
		internal static ManualLogSource Logger;

		private readonly Harmony harmony = new Harmony("com.psyko.missedscrap");

		private void Awake()
		{
			Logger = ((BaseUnityPlugin)this).Logger;
			harmony.PatchAll(typeof(Plugin));
			harmony.PatchAll(typeof(EndOfDayPatch));
			harmony.PatchAll(typeof(GameResetPatch));
			harmony.PatchAll(typeof(EnemyDropPatch));
			harmony.PatchAll(typeof(GiftBoxPatch));
			Logger.LogInfo((object)"Plugin com.psyko.missedscrap is loaded!");
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "com.psyko.missedscrap";

		public const string PLUGIN_NAME = "MissedScrap";

		public const string PLUGIN_VERSION = "1.1.2";
	}
}
namespace MissedScrap.Patches
{
	[HarmonyPatch(typeof(RoundManager))]
	internal class EndOfDayPatch
	{
		private static List<GrabbableObject> currentRoundScrap = new List<GrabbableObject>();

		private static HashSet<int> previousShipItemIDs = new HashSet<int>();

		private static HashSet<int> trackedItemIDs = new HashSet<int>();

		private static HashSet<int> removedItemIDs = new HashSet<int>();

		private static MissedScrapUI uiInstance;

		private static bool isTrackingActive = false;

		private static readonly List<VehicleController> vehicleCache = new List<VehicleController>();

		private static float lastVehicleCacheTime = 0f;

		private static Coroutine continuousTrackingCoroutine = null;

		[HarmonyPatch(typeof(StartOfRound), "openingDoorsSequence")]
		[HarmonyPostfix]
		private static void BeforeLanding()
		{
			RecordPreExistingItems();
		}

		[HarmonyPatch(typeof(StartOfRound), "StartGame")]
		[HarmonyPostfix]
		private static void OnGameStart()
		{
			RecordPreExistingItems();
		}

		private static void RecordPreExistingItems()
		{
			if (isTrackingActive || currentRoundScrap.Count != 0)
			{
				return;
			}
			StopTrackingCoroutine();
			currentRoundScrap.Clear();
			trackedItemIDs.Clear();
			removedItemIDs.Clear();
			isTrackingActive = false;
			previousShipItemIDs.Clear();
			GrabbableObject[] array = Object.FindObjectsOfType<GrabbableObject>();
			GrabbableObject[] array2 = array;
			foreach (GrabbableObject val in array2)
			{
				if ((Object)(object)val != (Object)null && (Object)(object)val.itemProperties != (Object)null && val.itemProperties.isScrap && (val.isInShipRoom || val.isInElevator))
				{
					previousShipItemIDs.Add(((Object)val).GetInstanceID());
				}
			}
			Plugin.Logger.LogInfo((object)$"Tracked {previousShipItemIDs.Count} items from previous quotas");
		}

		[HarmonyPatch("SpawnScrapInLevel")]
		[HarmonyPostfix]
		private static void OnScrapSpawned(RoundManager __instance)
		{
			((MonoBehaviour)__instance).StartCoroutine(CaptureScrapDelayed());
		}

		private static IEnumerator CaptureScrapDelayed()
		{
			yield return (object)new WaitForSeconds(2f);
			CaptureNewScrap();
			isTrackingActive = true;
			if ((Object)(object)RoundManager.Instance != (Object)null)
			{
				continuousTrackingCoroutine = ((MonoBehaviour)RoundManager.Instance).StartCoroutine(ContinuousScrapTracking());
			}
		}

		private static void StopTrackingCoroutine()
		{
			if (continuousTrackingCoroutine != null && (Object)(object)RoundManager.Instance != (Object)null)
			{
				try
				{
					((MonoBehaviour)RoundManager.Instance).StopCoroutine(continuousTrackingCoroutine);
				}
				catch
				{
				}
				continuousTrackingCoroutine = null;
			}
		}

		internal static void StopTracking()
		{
			StopTrackingCoroutine();
		}

		private static IEnumerator ContinuousScrapTracking()
		{
			float checkInterval = 5f;
			while (isTrackingActive)
			{
				yield return (object)new WaitForSeconds(checkInterval);
				CaptureNewScrap();
			}
		}

		internal static void CaptureNewScrap()
		{
			try
			{
				GrabbableObject[] array = Object.FindObjectsOfType<GrabbableObject>();
				GrabbableObject[] array2 = array;
				foreach (GrabbableObject val in array2)
				{
					if ((Object)(object)val == (Object)null || (Object)(object)val.itemProperties == (Object)null)
					{
						continue;
					}
					try
					{
						if (!((Component)val).gameObject.activeInHierarchy)
						{
							continue;
						}
					}
					catch
					{
						continue;
					}
					if (val.itemProperties.isScrap)
					{
						int instanceID = ((Object)val).GetInstanceID();
						if (!previousShipItemIDs.Contains(instanceID) && !trackedItemIDs.Contains(instanceID))
						{
							currentRoundScrap.Add(val);
							trackedItemIDs.Add(instanceID);
						}
					}
				}
			}
			catch (Exception ex)
			{
				Plugin.Logger.LogError((object)("Error capturing scrap: " + ex.Message));
			}
		}

		internal static void RemoveTrackedItem(int itemID)
		{
			try
			{
				removedItemIDs.Add(itemID);
				trackedItemIDs.Remove(itemID);
				for (int num = currentRoundScrap.Count - 1; num >= 0; num--)
				{
					if ((Object)(object)currentRoundScrap[num] != (Object)null && ((Object)currentRoundScrap[num]).GetInstanceID() == itemID)
					{
						currentRoundScrap.RemoveAt(num);
						break;
					}
				}
			}
			catch (Exception ex)
			{
				Plugin.Logger.LogError((object)("Error removing tracked item: " + ex.Message));
			}
		}

		[HarmonyPatch(typeof(StartOfRound), "ShipLeave")]
		[HarmonyPostfix]
		private static void OnShipLeave()
		{
			((MonoBehaviour)StartOfRound.Instance).StartCoroutine(CheckMissedScrapDelayed());
		}

		private static IEnumerator CheckMissedScrapDelayed()
		{
			isTrackingActive = false;
			StopTrackingCoroutine();
			yield return (object)new WaitForSeconds(3f);
			try
			{
				if ((Object)(object)StartOfRound.Instance == (Object)null)
				{
					Plugin.Logger.LogWarning((object)"StartOfRound instance is null - aborting check");
					yield break;
				}
				if (((Object)StartOfRound.Instance.currentLevel).name.Contains("CompanyBuilding"))
				{
					Plugin.Logger.LogInfo((object)"Selling at company - skipping missed scrap check");
					yield break;
				}
				Plugin.Logger.LogInfo((object)$"Analyzing {currentRoundScrap.Count} items from this round...");
				HashSet<int> collectedItems = new HashSet<int>(currentRoundScrap.Count);
				foreach (GrabbableObject trackedItem in currentRoundScrap)
				{
					if ((Object)(object)trackedItem == (Object)null)
					{
						continue;
					}
					try
					{
						if (trackedItem.isInShipRoom || trackedItem.isInElevator)
						{
							collectedItems.Add(((Object)trackedItem).GetInstanceID());
						}
					}
					catch
					{
					}
				}
				float currentTime = Time.time;
				if (vehicleCache.Count == 0 || currentTime - lastVehicleCacheTime > 10f)
				{
					vehicleCache.Clear();
					VehicleController[] vehicles = Object.FindObjectsOfType<VehicleController>();
					VehicleController[] array = vehicles;
					foreach (VehicleController v in array)
					{
						vehicleCache.Add(v);
					}
					lastVehicleCacheTime = currentTime;
				}
				if (vehicleCache.Count > 0)
				{
					foreach (GrabbableObject trackedItem2 in currentRoundScrap)
					{
						if ((Object)(object)trackedItem2 == (Object)null)
						{
							continue;
						}
						int itemID2 = ((Object)trackedItem2).GetInstanceID();
						if (collectedItems.Contains(itemID2))
						{
							continue;
						}
						try
						{
							if (IsInVehicle(trackedItem2))
							{
								collectedItems.Add(itemID2);
							}
						}
						catch
						{
						}
					}
				}
				Plugin.Logger.LogInfo((object)$"Collected: {collectedItems.Count} items (ship + vehicles)");
				List<(string name, int value)> missedScrap = new List<(string, int)>();
				int totalMissedValue = 0;
				if (currentRoundScrap.Count > 0)
				{
					missedScrap.Capacity = currentRoundScrap.Count;
				}
				for (int i = 0; i < currentRoundScrap.Count; i++)
				{
					GrabbableObject spawnedItem = currentRoundScrap[i];
					if ((Object)(object)spawnedItem == (Object)null)
					{
						continue;
					}
					int itemID = ((Object)spawnedItem).GetInstanceID();
					if (removedItemIDs.Contains(itemID) || collectedItems.Contains(itemID))
					{
						continue;
					}
					try
					{
						if ((Object)(object)spawnedItem.itemProperties != (Object)null)
						{
							string itemName = spawnedItem.itemProperties.itemName;
							int value = spawnedItem.scrapValue;
							missedScrap.Add((itemName, value));
							totalMissedValue += value;
						}
					}
					catch
					{
					}
				}
				missedScrap.Sort(((string name, int value) a, (string name, int value) b) => b.value.CompareTo(a.value));
				if (missedScrap.Count > 0)
				{
					Plugin.Logger.LogWarning((object)"╔════ MISSED SCRAP ════╗");
					foreach (var item in missedScrap)
					{
						Plugin.Logger.LogWarning((object)$"  {item.name}: ${item.value}");
					}
					Plugin.Logger.LogWarning((object)$"  Total: ${totalMissedValue} ({missedScrap.Count} items)");
					Plugin.Logger.LogWarning((object)"╚══════════════════════╝");
				}
				else
				{
					Plugin.Logger.LogInfo((object)"✓ Perfect run - no scrap missed!");
				}
				ShowMissedScrapUI(missedScrap, totalMissedValue);
			}
			catch (Exception ex)
			{
				Plugin.Logger.LogError((object)("Error in MissedScrap: " + ex.Message));
				Plugin.Logger.LogError((object)("Stack trace: " + ex.StackTrace));
			}
			yield return (object)new WaitForSeconds(1f);
			CleanupOldData();
		}

		private static bool IsInVehicle(GrabbableObject item)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: 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)
			if (vehicleCache.Count == 0)
			{
				return false;
			}
			try
			{
				Vector3 position = ((Component)item).transform.position;
				bool flag = false;
				for (int i = 0; i < vehicleCache.Count; i++)
				{
					VehicleController val = vehicleCache[i];
					if ((Object)(object)val != (Object)null)
					{
						Vector3 val2 = position - ((Component)val).transform.position;
						float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude;
						if (sqrMagnitude < 100f)
						{
							flag = true;
							break;
						}
					}
				}
				if (!flag)
				{
					return false;
				}
				Transform parent = ((Component)item).transform.parent;
				int num = 5;
				int num2 = 0;
				while ((Object)(object)parent != (Object)null && num2 < num)
				{
					string name = ((Object)parent).name;
					if (name.Contains("Cruiser") || name.Contains("Vehicle"))
					{
						return true;
					}
					parent = parent.parent;
					num2++;
				}
				return flag;
			}
			catch
			{
			}
			return false;
		}

		private static void ShowMissedScrapUI(List<(string name, int value)> missedScrap, int totalValue)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			try
			{
				if ((Object)(object)uiInstance == (Object)null)
				{
					GameObject val = new GameObject("MissedScrapUIManager");
					uiInstance = val.AddComponent<MissedScrapUI>();
					Object.DontDestroyOnLoad((Object)(object)val);
				}
				uiInstance.ShowMissedScrap(missedScrap, totalValue);
			}
			catch (Exception ex)
			{
				Plugin.Logger.LogError((object)("Failed to display UI: " + ex.Message));
			}
		}

		private static void CleanupOldData()
		{
			try
			{
				currentRoundScrap.Clear();
				trackedItemIDs.Clear();
				removedItemIDs.Clear();
				if (currentRoundScrap.Capacity > 100)
				{
					currentRoundScrap.Capacity = 100;
				}
				vehicleCache.Clear();
				lastVehicleCacheTime = 0f;
				if (previousShipItemIDs.Count > 500)
				{
					Plugin.Logger.LogWarning((object)"Large number of ship items detected (500+). Performance may be impacted.");
				}
			}
			catch (Exception ex)
			{
				Plugin.Logger.LogError((object)("Error during cleanup: " + ex.Message));
			}
		}

		internal static void EmergencyReset()
		{
			try
			{
				Plugin.Logger.LogInfo((object)"Emergency reset triggered");
				isTrackingActive = false;
				StopTrackingCoroutine();
				currentRoundScrap.Clear();
				previousShipItemIDs.Clear();
				trackedItemIDs.Clear();
				removedItemIDs.Clear();
				vehicleCache.Clear();
			}
			catch
			{
			}
		}
	}
	[HarmonyPatch(typeof(StartOfRound))]
	internal class GameResetPatch
	{
		[HarmonyPatch("ReviveDeadPlayers")]
		[HarmonyPostfix]
		private static void OnPlayersRevived()
		{
			EndOfDayPatch.EmergencyReset();
		}

		[HarmonyPatch("EndOfGame")]
		[HarmonyPrefix]
		private static void BeforeEndOfGame()
		{
			EndOfDayPatch.StopTracking();
		}
	}
	[HarmonyPatch(typeof(EnemyAI))]
	internal class EnemyDropPatch
	{
		[HarmonyPatch("KillEnemy")]
		[HarmonyPostfix]
		private static void OnEnemyKilled(EnemyAI __instance)
		{
			((MonoBehaviour)__instance).StartCoroutine(CheckForDroppedLoot());
		}

		private static IEnumerator CheckForDroppedLoot()
		{
			yield return (object)new WaitForSeconds(0.5f);
			EndOfDayPatch.CaptureNewScrap();
		}
	}
	[HarmonyPatch(typeof(GiftBoxItem))]
	internal class GiftBoxPatch
	{
		[HarmonyPatch("OpenGiftBoxServerRpc")]
		[HarmonyPrefix]
		private static void BeforeOpenGiftBoxServer(GiftBoxItem __instance)
		{
			if ((Object)(object)__instance != (Object)null)
			{
				EndOfDayPatch.RemoveTrackedItem(((Object)__instance).GetInstanceID());
			}
		}

		[HarmonyPatch("OpenGiftBoxClientRpc")]
		[HarmonyPrefix]
		private static void BeforeOpenGiftBoxClient(GiftBoxItem __instance)
		{
			if ((Object)(object)__instance != (Object)null)
			{
				EndOfDayPatch.RemoveTrackedItem(((Object)__instance).GetInstanceID());
			}
		}

		[HarmonyPatch("OpenGiftBoxServerRpc")]
		[HarmonyPostfix]
		private static void AfterOpenGiftBox(GiftBoxItem __instance)
		{
			if ((Object)(object)__instance != (Object)null)
			{
				((MonoBehaviour)__instance).StartCoroutine(CaptureGiftItem());
			}
		}

		private static IEnumerator CaptureGiftItem()
		{
			yield return (object)new WaitForSeconds(1f);
			EndOfDayPatch.CaptureNewScrap();
		}
	}
}