using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("ShipLoot")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.2.1.0")] [assembly: AssemblyInformationalVersion("1.2.1")] [assembly: AssemblyProduct("ShipLoot")] [assembly: AssemblyTitle("ShipLoot")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.2.1.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [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 ShipLoot { [BepInPlugin("com.github.tinyhoot.ShipLoot", "ShipLoot", "1.2.1")] [BepInDependency(/*Could not decode attribute arguments.*/)] internal class ShipLoot : BaseUnityPlugin { public const string GUID = "com.github.tinyhoot.ShipLoot"; public const string NAME = "ShipLoot"; public const string VERSION = "1.2.1"; internal static ShipLootConfig PluginConfig; internal static ManualLogSource Log; private void Awake() { //IL_002a: Unknown result type (might be due to invalid IL or missing references) Log = ((BaseUnityPlugin)this).Logger; PluginConfig = new ShipLootConfig(((BaseUnityPlugin)this).Config); PluginConfig.RegisterOptions(); new Harmony("com.github.tinyhoot.ShipLoot").PatchAll(Assembly.GetExecutingAssembly()); Log.LogInfo((object)"ShipLoot 1.2.1 loaded."); } private void Start() { SetLobbyCompatibility(); } private void SetLobbyCompatibility() { if (!Chainloader.PluginInfos.ContainsKey("BMX.LobbyCompatibility")) { return; } MethodInfo methodInfo = AccessTools.Method("LobbyCompatibility.Features.PluginHelper:RegisterPlugin", (Type[])null, (Type[])null); if (methodInfo == null) { Log.LogWarning((object)"Found LobbyCompatibility mod but failed to find plugin register API method!"); return; } Log.LogDebug((object)"Registering compatibility with LobbyCompatibility."); try { methodInfo.Invoke(null, new object[4] { "com.github.tinyhoot.ShipLoot", new Version("1.2.1"), 0, 0 }); } catch (Exception arg) { Log.LogError((object)$"Failed to register plugin compatibility with LobbyCompatibility.\n{arg}"); return; } Log.LogDebug((object)"Successfully registered with LobbyCompatibility."); } } internal class ShipLootConfig { private readonly ConfigFile _configFile; public ConfigEntry DisplayTime; public ConfigEntry VerticalOffset; public ShipLootConfig(ConfigFile configFile) { _configFile = configFile; } public void RegisterOptions() { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Expected O, but got Unknown DisplayTime = _configFile.Bind("General", "DisplayTime", 5f, new ConfigDescription("How long to display the total scrap value for, counted in seconds.", (AcceptableValueBase)(object)new AcceptableValueRange(1f, 30f), Array.Empty())); VerticalOffset = _configFile.Bind("General", "VerticalOffset", 50f, new ConfigDescription("How far below the game's own scan total to place the ship total, in UI units. Negative values move it above instead.", (AcceptableValueBase)(object)new AcceptableValueRange(-500f, 500f), Array.Empty())); } } } namespace ShipLoot.Patches { [HarmonyPatch] internal class HudManagerPatcher { private const float RefreshInterval = 0.2f; private static GameObject _totalCounter; private static TextMeshProUGUI _valueText; private static TextMeshProUGUI _labelText; private static float _displayTimeLeft; private static bool _diagnosticsLogged; private static float _lastLoggedTotal = float.NaN; [HarmonyPrefix] [HarmonyPatch(typeof(HUDManager), "PingScan_performed")] private static void OnScan(HUDManager __instance, CallbackContext context) { if ((Object)(object)GameNetworkManager.Instance == (Object)null || (Object)(object)GameNetworkManager.Instance.localPlayerController == (Object)null || !((CallbackContext)(ref context)).performed || !__instance.CanPlayerScan() || __instance.playerPingingScan > -1f || (Object)(object)StartOfRound.Instance == (Object)null || (!StartOfRound.Instance.inShipPhase && !GameNetworkManager.Instance.localPlayerController.isInHangarShipRoom)) { return; } if (!Object.op_Implicit((Object)(object)_totalCounter)) { BuildCounter(__instance); } if (Object.op_Implicit((Object)(object)_totalCounter) && Object.op_Implicit((Object)(object)_valueText)) { UpdateDisplayedTotal(); _displayTimeLeft = ShipLoot.PluginConfig.DisplayTime.Value; if (!_totalCounter.activeSelf) { ((MonoBehaviour)GameNetworkManager.Instance).StartCoroutine(ShipLootCoroutine()); } } } private static void ApplyShownState() { Transform[] componentsInChildren = _totalCounter.GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren.Length; i++) { ((Component)componentsInChildren[i]).gameObject.SetActive(true); } CanvasGroup[] componentsInChildren2 = _totalCounter.GetComponentsInChildren(true); foreach (CanvasGroup obj in componentsInChildren2) { obj.alpha = 1f; obj.interactable = false; obj.blocksRaycasts = false; } Graphic[] componentsInChildren3 = _totalCounter.GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren3.Length; i++) { ((Behaviour)componentsInChildren3[i]).enabled = true; } } private static IEnumerator ShipLootCoroutine() { _totalCounter.SetActive(true); ApplyShownState(); if (!_diagnosticsLogged) { _diagnosticsLogged = true; yield return (object)new WaitForEndOfFrame(); LogLayoutDiagnostics(); } float refreshTimer = 0.2f; while (_displayTimeLeft > 0f) { _displayTimeLeft -= Time.deltaTime; refreshTimer -= Time.deltaTime; if (refreshTimer <= 0f) { refreshTimer = 0.2f; UpdateDisplayedTotal(); } yield return null; } _totalCounter.SetActive(false); } private static void UpdateDisplayedTotal() { if (Object.op_Implicit((Object)(object)_valueText)) { ((TMP_Text)_valueText).text = $"${CalculateLootValue():F0}"; if (Object.op_Implicit((Object)(object)_labelText)) { ((TMP_Text)_labelText).text = "SHIP:"; } } } private static bool CountsAsScrap(GrabbableObject obj) { if ((Object)(object)obj.itemProperties != (Object)null && obj.itemProperties.isScrap && !obj.deactivated && !obj.itemUsedUp) { return !(obj is RagdollGrabbableObject); } return false; } private static float CalculateLootValue() { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) Collider val = (((Object)(object)StartOfRound.Instance != (Object)null) ? StartOfRound.Instance.shipInnerRoomBounds : null); List list; string arg; if ((Object)(object)val != (Object)null) { Bounds bounds = val.bounds; list = (from obj in Object.FindObjectsOfType() where ((Bounds)(ref bounds)).Contains(((Component)obj).transform.position) select obj).ToList(); arg = "ship bounds"; } else { GameObject val2 = FindShip(); if (!Object.op_Implicit((Object)(object)val2)) { ShipLoot.Log.LogError((object)"Failed to find the ship, cannot total up its scrap."); return 0f; } list = val2.GetComponentsInChildren().ToList(); arg = "ship hierarchy (fallback)"; } List list2 = list.Where(CountsAsScrap).ToList(); float num = list2.Sum((GrabbableObject scrap) => scrap.scrapValue); if (!num.Equals(_lastLoggedTotal)) { _lastLoggedTotal = num; ShipLoot.Log.LogDebug((object)($"Ship scrap total is now ${num:F0}, found via {arg}. " + $"{list.Count} grabbable object(s) in the ship, {list2.Count} counted.")); CollectionExtensions.Do((IEnumerable)list2, (Action)delegate(GrabbableObject scrap) { ShipLoot.Log.LogDebug((object)$" counted: {((Object)scrap).name} - ${scrap.scrapValue}"); }); foreach (GrabbableObject item in list.Except(list2)) { string arg2 = (((Object)(object)item.itemProperties == (Object)null) ? "no item properties" : ((item is RagdollGrabbableObject) ? "is a body" : (item.deactivated ? "deactivated" : (item.itemUsedUp ? "used up" : "not marked as scrap")))); ShipLoot.Log.LogDebug((object)$" skipped: {((Object)item).name} - ${item.scrapValue} ({arg2})"); } } return num; } private static GameObject FindShip() { Transform val = (((Object)(object)StartOfRound.Instance != (Object)null) ? StartOfRound.Instance.elevatorTransform : null); if ((Object)(object)val != (Object)null) { return ((Component)val).gameObject; } return GameObject.Find("/Environment/HangarShip"); } private static void BuildCounter(HUDManager hudManager) { //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) Transform val = FindScanContainer(hudManager); if ((Object)(object)val == (Object)null) { ShipLoot.Log.LogError((object)"Failed to find the scan info container to copy!"); return; } string text = (((Object)(object)hudManager.totalValueText != (Object)null) ? GetRelativePath(val, ((TMP_Text)hudManager.totalValueText).transform) : null); _totalCounter = Object.Instantiate(((Component)val).gameObject, val.parent, false); ((Object)_totalCounter).name = "ShipLootCounter"; Animator component = _totalCounter.GetComponent(); if ((Object)(object)component != (Object)null) { Object.Destroy((Object)(object)component); } ApplyShownState(); Transform transform = _totalCounter.transform; RectTransform val2 = (RectTransform)(object)((transform is RectTransform) ? transform : null); if (val2 != null) { RectTransform val3 = (RectTransform)(object)((val is RectTransform) ? val : null); if (val3 != null) { val2.anchoredPosition = val3.anchoredPosition + new Vector2(0f, 0f - ShipLoot.PluginConfig.VerticalOffset.Value); } } _valueText = null; if (!string.IsNullOrEmpty(text)) { Transform val4 = _totalCounter.transform.Find(text); if ((Object)(object)val4 != (Object)null) { _valueText = ((Component)val4).GetComponent(); } } TextMeshProUGUI[] componentsInChildren = _totalCounter.GetComponentsInChildren(true); if ((Object)(object)_valueText == (Object)null) { _valueText = componentsInChildren.FirstOrDefault(); } _labelText = ((IEnumerable)componentsInChildren).FirstOrDefault((Func)((TextMeshProUGUI val5) => (Object)(object)val5 != (Object)(object)_valueText)); if ((Object)(object)_valueText == (Object)null) { ShipLoot.Log.LogError((object)"Failed to find a text component on the copied scan info container!"); } _totalCounter.SetActive(false); } private static Transform FindScanContainer(HUDManager hudManager) { if ((Object)(object)hudManager == (Object)null) { return null; } if ((Object)(object)hudManager.scanInfoAnimator != (Object)null) { return ((Component)hudManager.scanInfoAnimator).transform; } if ((Object)(object)hudManager.totalValueText == (Object)null) { return null; } Transform val = ((TMP_Text)hudManager.totalValueText).transform; while ((Object)(object)val != (Object)null) { if ((Object)(object)((Component)val).GetComponent() != (Object)null) { return val; } val = val.parent; } return ((TMP_Text)hudManager.totalValueText).transform.parent; } private static string GetRelativePath(Transform root, Transform target) { if ((Object)(object)root == (Object)null || (Object)(object)target == (Object)null) { return null; } string text = null; Transform val = target; while ((Object)(object)val != (Object)null && (Object)(object)val != (Object)(object)root) { text = ((text == null) ? ((Object)val).name : (((Object)val).name + "/" + text)); val = val.parent; } return text; } private static string GetPath(Transform transform) { if ((Object)(object)transform == (Object)null) { return ""; } string text = ((Object)transform).name; Transform parent = transform.parent; while ((Object)(object)parent != (Object)null) { text = ((Object)parent).name + "/" + text; parent = parent.parent; } return "/" + text; } private static void LogLayoutDiagnostics() { //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: 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_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_026f: Unknown result type (might be due to invalid IL or missing references) ManualLogSource log = ShipLoot.Log; if (!Object.op_Implicit((Object)(object)_totalCounter)) { log.LogDebug((object)"ShipLoot counter is gone before it could be measured."); return; } log.LogDebug((object)"===== ShipLoot layout diagnostics ====="); log.LogDebug((object)$"screen : {Screen.width}x{Screen.height}"); log.LogDebug((object)("counter path : " + GetPath(_totalCounter.transform))); log.LogDebug((object)$"counter active: self={_totalCounter.activeSelf} inHierarchy={_totalCounter.activeInHierarchy}"); Transform transform = _totalCounter.transform; RectTransform val = (RectTransform)(object)((transform is RectTransform) ? transform : null); if (val != null) { log.LogDebug((object)$"counter rect : anchoredPos={val.anchoredPosition} sizeDelta={val.sizeDelta} lossyScale={((Transform)val).lossyScale}"); Vector3[] array = (Vector3[])(object)new Vector3[4]; val.GetWorldCorners(array); log.LogDebug((object)$"counter corner: bottomLeft={array[0]} topRight={array[2]}"); } Transform val2 = _totalCounter.transform; while ((Object)(object)val2 != (Object)null) { CanvasGroup component = ((Component)val2).GetComponent(); Canvas component2 = ((Component)val2).GetComponent(); if (!((Object)(object)component == (Object)null) || !((Object)(object)component2 == (Object)null) || !((Object)(object)val2 != (Object)(object)_totalCounter.transform)) { log.LogDebug((object)($" chain '{((Object)val2).name}': activeSelf={((Component)val2).gameObject.activeSelf}" + (((Object)(object)component != (Object)null) ? $" alpha={component.alpha}" : "") + (((Object)(object)component2 != (Object)null) ? $" canvasEnabled={((Behaviour)component2).enabled}" : ""))); } val2 = val2.parent; } if (Object.op_Implicit((Object)(object)_valueText)) { log.LogDebug((object)("value text : " + GetPath(((TMP_Text)_valueText).transform) + " '" + ((TMP_Text)_valueText).text + "' " + $"enabled={((Behaviour)_valueText).enabled} activeInHierarchy={((Component)_valueText).gameObject.activeInHierarchy} " + $"color={((Graphic)_valueText).color}")); } if (Object.op_Implicit((Object)(object)_labelText)) { log.LogDebug((object)("label text : " + GetPath(((TMP_Text)_labelText).transform) + " '" + ((TMP_Text)_labelText).text + "' " + $"enabled={((Behaviour)_labelText).enabled} activeInHierarchy={((Component)_labelText).gameObject.activeInHierarchy}")); } log.LogDebug((object)"===== end diagnostics ====="); } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }