Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of CruiserScrapCounter v1.0.1
CruiserScrapCounter.dll
Decompiled a day agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using GameNetcodeStuff; using HarmonyLib; using TMPro; 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("CruiserScrapCounter")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.1.0")] [assembly: AssemblyInformationalVersion("1.0.1")] [assembly: AssemblyProduct("CruiserScrapCounter")] [assembly: AssemblyTitle("CruiserScrapCounter")] [assembly: AssemblyVersion("1.0.1.0")] namespace CruiserScrapCounter; [HarmonyPatch(typeof(HUDManager), "PingScan_performed")] internal static class CruiserScanPatch { private const string ValueCounterPath = "/Systems/UI/Canvas/IngamePlayerHUD/BottomMiddle/ValueCounter"; private static readonly float[] LineHeights = new float[2] { -70f, -90f }; private static readonly GameObject[] _counters = (GameObject[])(object)new GameObject[2]; private static readonly TMP_Text[] _texts = (TMP_Text[])(object)new TMP_Text[2]; private static float _displayTimeLeft; public static void Postfix() { try { GameNetworkManager instance = GameNetworkManager.Instance; if ((Object)(object)instance == (Object)null) { return; } PlayerControllerB localPlayerController = instance.localPlayerController; if ((Object)(object)localPlayerController == (Object)null || localPlayerController.isInsideFactory) { return; } StartOfRound instance2 = StartOfRound.Instance; if (!((Object)(object)instance2 == (Object)null) && !instance2.inShipPhase && LootTracker.ShipHasLanded() && !LootTracker.IsDisabledMoon()) { Component val = (Component)(object)Object.FindObjectOfType<VehicleController>(); if (!((Object)(object)val == (Object)null)) { LootTracker.Count(val, out var cruiserValue, out var cruiserCount, out var moonValue, out var moonCount); Show(FormatText(cruiserValue, moonValue, cruiserCount, moonCount), instance); } } } catch (Exception ex) { Plugin.Log.LogError((object)("Scan handler failed: " + ex)); } } private static string FormatText(int cruiserValue, int moonValue, int cruiserCount, int moonCount) { try { return string.Format(Plugin.Format.Value.Replace("\\n", "\n"), cruiserValue, moonValue, cruiserCount, moonCount); } catch (FormatException) { return "Cruiser: " + cruiserValue + "/" + moonValue + "\nCount: " + cruiserCount + "/" + moonCount; } } private static void Show(string message, GameNetworkManager gnm) { string[] array = message.Split(new char[1] { '\n' }, 2); for (int i = 0; i < 2; i++) { if ((Object)(object)_counters[i] == (Object)null && !CopyValueCounter(i)) { return; } _texts[i].text = ((i < array.Length) ? array[i] : ""); } bool activeSelf = _counters[0].activeSelf; _displayTimeLeft = ((Plugin.DisplayTime.Value > 0f) ? Plugin.DisplayTime.Value : 5f); if (!activeSelf) { ((MonoBehaviour)gnm).StartCoroutine(DisplayCoroutine(array.Length > 1)); } } private static IEnumerator DisplayCoroutine(bool twoLines) { _counters[0].SetActive(true); _counters[1].SetActive(twoLines); while (_displayTimeLeft > 0f) { float displayTimeLeft = _displayTimeLeft; _displayTimeLeft = 0f; yield return (object)new WaitForSeconds(displayTimeLeft); } for (int i = 0; i < 2; i++) { if ((Object)(object)_counters[i] != (Object)null) { _counters[i].SetActive(false); } } } private static bool CopyValueCounter(int index) { //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) GameObject val = GameObject.Find("/Systems/UI/Canvas/IngamePlayerHUD/BottomMiddle/ValueCounter"); if ((Object)(object)val == (Object)null) { Plugin.Log.LogError((object)"Failed to find ValueCounter object to copy!"); return false; } GameObject val2 = Object.Instantiate<GameObject>(val, val.transform.parent, false); val2.transform.Translate(0f, 1f, 0f); Vector3 localPosition = val2.transform.localPosition; val2.transform.localPosition = new Vector3(localPosition.x + 50f + Plugin.OffsetX.Value, LineHeights[index] + Plugin.OffsetY.Value, localPosition.z); TMP_Text componentInChildren = val2.GetComponentInChildren<TMP_Text>(); if ((Object)(object)componentInChildren == (Object)null) { Plugin.Log.LogError((object)"ValueCounter copy has no text component."); return false; } RectTransform rectTransform = componentInChildren.rectTransform; rectTransform.anchoredPosition += new Vector2(200f, 0f); rectTransform.sizeDelta = new Vector2(600f, rectTransform.sizeDelta.y); _counters[index] = val2; _texts[index] = componentInChildren; return true; } } [HarmonyPatch(typeof(StartOfRound), "openingDoorsSequence")] internal static class LandingPatch { private static void Postfix() { try { if (!LootTracker.IsDisabledMoon()) { LootTracker.RecordOldLoot(); } } catch (Exception ex) { Plugin.Log.LogError((object)("Recording old loot failed: " + ex)); } } } internal static class LootTracker { private static readonly HashSet<GrabbableObject> OldLoot = new HashSet<GrabbableObject>(); private static readonly FieldInfo DeactivatedField = AccessTools.Field(typeof(GrabbableObject), "deactivated"); private static int _seed; private static object GetField(object obj, string name) { if (obj == null) { return null; } FieldInfo fieldInfo = AccessTools.Field(obj.GetType(), name); if (!(fieldInfo != null)) { return null; } return fieldInfo.GetValue(obj); } internal static bool IsDisabledMoon() { StartOfRound instance = StartOfRound.Instance; if ((Object)(object)instance == (Object)null) { return false; } object field = GetField(instance, "currentLevel"); if (field == null) { return false; } object field2 = GetField(field, "levelID"); if (field2 is int && (int)field2 == 3) { return true; } string text = string.Concat(GetField(field, "PlanetName"), " ", GetField(field, "sceneName")); if (text.IndexOf("Gordion", StringComparison.OrdinalIgnoreCase) >= 0) { return true; } string[] array = Plugin.DisabledMoons.Value.Split(','); for (int i = 0; i < array.Length; i++) { string text2 = array[i].Trim(); if (text2.Length > 0 && text.IndexOf(text2, StringComparison.OrdinalIgnoreCase) >= 0) { return true; } } return false; } internal static bool ShipHasLanded() { object field = GetField(StartOfRound.Instance, "shipHasLanded"); if (field is bool) { return (bool)field; } return true; } private static bool IsActiveScrap(GrabbableObject g) { if ((Object)(object)g == (Object)null || (Object)(object)g.itemProperties == (Object)null || !g.itemProperties.isScrap) { return false; } if (g.itemUsedUp) { return false; } if (DeactivatedField != null) { object value = DeactivatedField.GetValue(g); if (value is bool && (bool)value) { return false; } } return true; } private static bool IsInCruiser(GrabbableObject g, Component cruiser) { if ((Object)(object)cruiser != (Object)null) { return ((Component)g).transform.IsChildOf(cruiser.transform); } return false; } private static bool IsAboardShip(GrabbableObject g, Component cruiser) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) if (g.isInShipRoom || IsInCruiser(g, cruiser)) { return true; } StartOfRound instance = StartOfRound.Instance; if ((Object)(object)instance != (Object)null && (Object)(object)instance.shipInnerRoomBounds != (Object)null) { Bounds bounds = instance.shipInnerRoomBounds.bounds; return ((Bounds)(ref bounds)).Contains(((Component)g).transform.position); } return false; } internal static void RecordOldLoot() { OldLoot.Clear(); _seed = StartOfRound.Instance.randomMapSeed; Component cruiser = (Component)(object)Object.FindObjectOfType<VehicleController>(); GrabbableObject[] array = Object.FindObjectsOfType<GrabbableObject>(); foreach (GrabbableObject val in array) { if (IsActiveScrap(val) && IsAboardShip(val, cruiser)) { OldLoot.Add(val); } } Plugin.Log.LogInfo((object)("Ignoring " + OldLoot.Count + " items that were already aboard when landing.")); } internal static void Count(Component cruiser, out int cruiserValue, out int cruiserCount, out int moonValue, out int moonCount) { cruiserValue = 0; cruiserCount = 0; moonValue = 0; moonCount = 0; int randomMapSeed = StartOfRound.Instance.randomMapSeed; if (randomMapSeed != _seed) { OldLoot.Clear(); _seed = randomMapSeed; } GrabbableObject[] array = Object.FindObjectsOfType<GrabbableObject>(); foreach (GrabbableObject val in array) { if (IsActiveScrap(val) && !val.scrapPersistedThroughRounds && !OldLoot.Contains(val)) { moonValue += val.scrapValue; moonCount++; if (IsInCruiser(val, cruiser)) { cruiserValue += val.scrapValue; cruiserCount++; } } } } } public static class MyPluginInfo { public const string PLUGIN_GUID = "CruiserScrapCounter"; public const string PLUGIN_NAME = "CruiserScrapCounter"; public const string PLUGIN_VERSION = "1.0.1"; } [BepInPlugin("CruiserScrapCounter", "CruiserScrapCounter", "1.0.1")] public class Plugin : BaseUnityPlugin { internal static ManualLogSource Log; internal static ConfigEntry<float> DisplayTime; internal static ConfigEntry<string> Format; internal static ConfigEntry<float> OffsetX; internal static ConfigEntry<float> OffsetY; internal static ConfigEntry<string> DisabledMoons; private const string DefaultFormat = "Cruiser: {0}/{1}\nCount: {2}/{3}"; private void Awake() { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Expected O, but got Unknown //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Expected O, but got Unknown //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Expected O, but got Unknown //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Expected O, but got Unknown //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Expected O, but got Unknown //IL_0173: Unknown result type (might be due to invalid IL or missing references) Log = ((BaseUnityPlugin)this).Logger; DisplayTime = ((BaseUnityPlugin)this).Config.Bind<float>("General", "DisplayTime", 5f, new ConfigDescription("How long the counter stays on screen after a scan, in seconds.", (AcceptableValueBase)null, Array.Empty<object>())); Format = ((BaseUnityPlugin)this).Config.Bind<string>("General", "Format", "Cruiser: {0}/{1}\nCount: {2}/{3}", new ConfigDescription("Counter text. {0} = Cruiser value, {1} = value of all of today's loot on the moon, {2} = Cruiser item count, {3} = item count of all of today's loot on the moon. Use \\n for a new line. One-line example: Cruiser: {0}/{1} {2}/{3}", (AcceptableValueBase)null, Array.Empty<object>())); OffsetX = ((BaseUnityPlugin)this).Config.Bind<float>("HUD", "OffsetX", 0f, new ConfigDescription("Moves the counter horizontally from its default spot (the QUOTA/OVERTIME rows). Negative = left, positive = right.", (AcceptableValueBase)null, Array.Empty<object>())); OffsetY = ((BaseUnityPlugin)this).Config.Bind<float>("HUD", "OffsetY", 0f, new ConfigDescription("Moves the counter vertically. Negative = down, positive = up.", (AcceptableValueBase)null, Array.Empty<object>())); DisabledMoons = ((BaseUnityPlugin)this).Config.Bind<string>("General", "DisabledMoons", "Galetry", new ConfigDescription("Comma-separated moon names where the counter stays hidden (matched anywhere in the moon name). The Company building is always disabled.", (AcceptableValueBase)null, Array.Empty<object>())); ConfigEntry<int> val = ((BaseUnityPlugin)this).Config.Bind<int>("Internal", "ConfigVersion", 0, new ConfigDescription("Used to apply new defaults once after an update. Don't change.", (AcceptableValueBase)null, Array.Empty<object>())); if (val.Value < 2) { Format.Value = "Cruiser: {0}/{1}\nCount: {2}/{3}"; } if (val.Value < 5) { OffsetX.Value = 0f; OffsetY.Value = 0f; val.Value = 5; ((BaseUnityPlugin)this).Config.Save(); } new Harmony("CruiserScrapCounter").PatchAll(); Log.LogInfo((object)"CruiserScrapCounter v1.0.1 has loaded!"); } }