using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using TMPro;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.SceneManagement;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("ShipLootTotal")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ShipLootTotal")]
[assembly: AssemblyCopyright("Copyright © 2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("03969134-fca5-435b-9dc6-2366b8fb8b9b")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace ShipLootTotal;
[BepInPlugin("DaanSmoki.LethalCompany.ShipLootTotal", "Ship Loot Total", "1.1.2")]
public class Plugin : BaseUnityPlugin
{
public const string PluginGuid = "DaanSmoki.LethalCompany.ShipLootTotal";
public const string PluginName = "Ship Loot Total";
public const string PluginVersion = "1.1.2";
internal static ManualLogSource Log;
internal static Harmony Harmony;
internal static float _lastScanPostfixAt = -999f;
internal static bool SuppressNextHudSfx = false;
internal static bool SuppressHudSfxActive = false;
internal static ConfigEntry<float> PopupDuration;
private void Awake()
{
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_001a: Expected O, but got Unknown
Log = ((BaseUnityPlugin)this).Logger;
Harmony = new Harmony("DaanSmoki.LethalCompany.ShipLootTotal");
PopupDuration = ((BaseUnityPlugin)this).Config.Bind<float>("General", "PopupDuration", 3f, "How long (in seconds) the popup stays visible after scanning.");
Harmony.PatchAll();
ScrapValueSyncPatcher.Apply(Harmony);
Log.LogInfo((object)"Ship Loot Total 1.1.2 loaded.");
}
}
[HarmonyPatch(typeof(HUDManager))]
public static class Patch_HUD_PingScan
{
[HarmonyPostfix]
[HarmonyPatch("PingScan_performed")]
public static void Postfix(CallbackContext context)
{
try
{
if (!((CallbackContext)(ref context)).performed || Time.time - Plugin._lastScanPostfixAt < 0.25f)
{
return;
}
Plugin._lastScanPostfixAt = Time.time;
object localPlayerController = Utils.GetLocalPlayerController();
if (localPlayerController != null && Utils.IsPlayerInShip(localPlayerController))
{
Utils.InvalidateGrabbablesCache();
int num = Utils.SumShipScrapValues();
HUDHelper.ShowStable("Total in Ship: " + num);
if (Plugin.Log != null)
{
Plugin.Log.LogInfo((object)("ShipLootTotal: PingScan -> total=" + num));
}
}
}
catch (Exception ex)
{
if (Plugin.Log != null)
{
Plugin.Log.LogError((object)ex);
}
}
}
}
[HarmonyPatch]
public static class Patch_HUD_Display_SilentGate
{
[CompilerGenerated]
private sealed class <TargetMethods>d__0 : IEnumerable<MethodBase>, IEnumerable, IEnumerator<MethodBase>, IDisposable, IEnumerator
{
private int <>1__state;
private MethodBase <>2__current;
private int <>l__initialThreadId;
MethodBase IEnumerator<MethodBase>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <TargetMethods>d__0(int <>1__state)
{
this.<>1__state = <>1__state;
<>l__initialThreadId = Environment.CurrentManagedThreadId;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<>1__state = -2;
}
private bool MoveNext()
{
switch (<>1__state)
{
default:
return false;
case 0:
{
<>1__state = -1;
Type type = AccessTools.TypeByName("HUDManager");
if (type == null)
{
return false;
}
MethodInfo methodInfo = AccessTools.Method(type, "DisplayGlobalNotification", new Type[1] { typeof(string) }, (Type[])null);
if (methodInfo != null)
{
<>2__current = methodInfo;
<>1__state = 1;
return true;
}
break;
}
case 1:
<>1__state = -1;
break;
}
return false;
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
[DebuggerHidden]
IEnumerator<MethodBase> IEnumerable<MethodBase>.GetEnumerator()
{
if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
{
<>1__state = 0;
return this;
}
return new <TargetMethods>d__0(0);
}
[DebuggerHidden]
IEnumerator IEnumerable.GetEnumerator()
{
return ((IEnumerable<MethodBase>)this).GetEnumerator();
}
}
[IteratorStateMachine(typeof(<TargetMethods>d__0))]
private static IEnumerable<MethodBase> TargetMethods()
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <TargetMethods>d__0(-2);
}
private static void Prefix()
{
Plugin.SuppressHudSfxActive = Plugin.SuppressNextHudSfx;
Plugin.SuppressNextHudSfx = false;
}
private static void Postfix()
{
Plugin.SuppressHudSfxActive = false;
}
}
internal static class HUDHelper
{
private static Type _hudType;
private static object _hudInstance;
private static MethodInfo _miDisplayGlobal;
public static void ShowStable(string bodyText)
{
try
{
object hUDManager = GetHUDManager();
if (hUDManager == null)
{
if (Plugin.Log != null)
{
Plugin.Log.LogWarning((object)"HUDHelper: HUDManager.Instance not found.");
}
return;
}
Plugin.SuppressNextHudSfx = true;
HudHideHelper.PrepareForShow(hUDManager);
if (_miDisplayGlobal == null || _miDisplayGlobal.DeclaringType == null)
{
_miDisplayGlobal = hUDManager.GetType().GetMethod("DisplayGlobalNotification", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[1] { typeof(string) }, null);
}
if (_miDisplayGlobal != null)
{
_miDisplayGlobal.Invoke(hUDManager, new object[1] { bodyText });
HudHideHelper.HideAfterSeconds((Plugin.PopupDuration != null) ? Plugin.PopupDuration.Value : 3f);
if (Plugin.Log != null)
{
Plugin.Log.LogInfo((object)"HUDHelper: Used DisplayGlobalNotification(string) [silent].");
}
}
else if (Plugin.Log != null)
{
Plugin.Log.LogWarning((object)"HUDHelper: DisplayGlobalNotification(string) not found.");
}
}
catch (Exception ex)
{
if (Plugin.Log != null)
{
Plugin.Log.LogWarning((object)("HUDHelper.ShowStable failed: " + ex.GetType().Name + ": " + ex.Message));
}
}
}
internal static object GetHUDManager()
{
//IL_0077: Unknown result type (might be due to invalid IL or missing references)
//IL_0082: Expected O, but got Unknown
//IL_008f: Unknown result type (might be due to invalid IL or missing references)
//IL_009a: Expected O, but got Unknown
if (_hudType == null)
{
_hudType = AccessTools.TypeByName("HUDManager");
if (_hudType == null)
{
return null;
}
}
PropertyInfo propertyInfo = _hudType.GetProperty("Instance", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) ?? _hudType.GetProperty("instance", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
object obj = ((propertyInfo != null) ? propertyInfo.GetValue(null) : null);
bool flag = _hudInstance is Object && (Object)_hudInstance == (Object)null;
bool flag2 = obj is Object && (Object)obj == (Object)null;
if (_hudInstance == null || flag || (!flag2 && _hudInstance != obj))
{
_hudInstance = obj;
HudAudioLocator.Reset();
}
return _hudInstance;
}
}
internal static class HudHideHelper
{
[CompilerGenerated]
private sealed class <HideCoroutine>d__5 : IEnumerator<object>, IDisposable, IEnumerator
{
private int <>1__state;
private object <>2__current;
public float seconds;
public object hud;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <HideCoroutine>d__5(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<>1__state = -2;
}
private bool MoveNext()
{
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: Expected O, but got Unknown
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
<>2__current = (object)new WaitForSeconds(seconds);
<>1__state = 1;
return true;
case 1:
<>1__state = -1;
try
{
FieldInfo field = hud.GetType().GetField("globalNotificationCoroutine", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (field != null)
{
object? value = field.GetValue(hud);
Coroutine val = (Coroutine)((value is Coroutine) ? value : null);
object obj = hud;
MonoBehaviour val2 = (MonoBehaviour)((obj is MonoBehaviour) ? obj : null);
if (val != null && (Object)(object)val2 != (Object)null)
{
val2.StopCoroutine(val);
field.SetValue(hud, null);
}
}
EnsureCachedParts(hud);
if ((Object)(object)_tmp != (Object)null)
{
((TMP_Text)_tmp).text = string.Empty;
}
if ((Object)(object)_panelGO != (Object)null)
{
CanvasGroup obj2 = _panelGO.GetComponent<CanvasGroup>() ?? _panelGO.AddComponent<CanvasGroup>();
obj2.alpha = 0f;
obj2.interactable = false;
obj2.blocksRaycasts = false;
}
}
catch (Exception ex)
{
if (Plugin.Log != null)
{
Plugin.Log.LogWarning((object)("HudHideHelper: hide failed: " + ex.Message));
}
}
return false;
}
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
private static Coroutine _hideRoutine;
private static GameObject _panelGO;
private static TextMeshProUGUI _tmp;
public static void PrepareForShow(object hud)
{
try
{
EnsureCachedParts(hud);
if ((Object)(object)_panelGO != (Object)null)
{
if (!_panelGO.activeSelf)
{
_panelGO.SetActive(true);
}
CanvasGroup obj = _panelGO.GetComponent<CanvasGroup>() ?? _panelGO.AddComponent<CanvasGroup>();
obj.alpha = 1f;
obj.interactable = false;
obj.blocksRaycasts = false;
}
if ((Object)(object)_tmp != (Object)null)
{
PropertyInfo property = ((object)_tmp).GetType().GetProperty("alpha");
if (property != null)
{
property.SetValue(_tmp, 1f);
}
}
}
catch
{
}
}
public static void HideAfterSeconds(float seconds)
{
object hUDManager = HUDHelper.GetHUDManager();
if (hUDManager == null)
{
return;
}
MonoBehaviour val = (MonoBehaviour)((hUDManager is MonoBehaviour) ? hUDManager : null);
if (!((Object)(object)val == (Object)null))
{
if (_hideRoutine != null)
{
val.StopCoroutine(_hideRoutine);
}
_hideRoutine = val.StartCoroutine(HideCoroutine(hUDManager, seconds));
}
}
[IteratorStateMachine(typeof(<HideCoroutine>d__5))]
private static IEnumerator HideCoroutine(object hud, float seconds)
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <HideCoroutine>d__5(0)
{
hud = hud,
seconds = seconds
};
}
private static void EnsureCachedParts(object hud)
{
if ((Object)(object)_panelGO != (Object)null && (Object)(object)_tmp != (Object)null)
{
return;
}
if (_panelGO != null && (Object)(object)_panelGO == (Object)null)
{
_panelGO = null;
}
if (_tmp != null && (Object)(object)_tmp == (Object)null)
{
_tmp = null;
}
if ((Object)(object)_panelGO != (Object)null && (Object)(object)_tmp != (Object)null)
{
return;
}
Type type = hud.GetType();
if ((Object)(object)_tmp == (Object)null)
{
FieldInfo field = type.GetField("globalNotificationText", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
_tmp = (TextMeshProUGUI)((field != null) ? /*isinst with value type is only supported in some contexts*/: null);
}
if (!((Object)(object)_panelGO == (Object)null))
{
return;
}
FieldInfo field2 = type.GetField("globalNotificationBackground", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
object obj = ((field2 != null) ? field2.GetValue(hud) : null);
GameObject val = (GameObject)((obj is GameObject) ? obj : null);
if ((Object)(object)val != (Object)null)
{
_panelGO = val;
}
else
{
Component val2 = (Component)((obj is Component) ? obj : null);
if ((Object)(object)val2 != (Object)null)
{
_panelGO = val2.gameObject;
}
}
if ((Object)(object)_panelGO == (Object)null && (Object)(object)_tmp != (Object)null && (Object)(object)((TMP_Text)_tmp).transform != (Object)null)
{
Transform parent = ((TMP_Text)_tmp).transform.parent;
if ((Object)(object)parent != (Object)null)
{
_panelGO = ((Component)parent).gameObject;
}
}
}
}
internal static class HudAudioLocator
{
private static AudioSource _cached;
private static Type _hudType;
private static object _hudInstance;
public static void Reset()
{
_cached = null;
_hudType = null;
_hudInstance = null;
}
public static AudioSource GetHudAudio()
{
//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
//IL_00af: Expected O, but got Unknown
//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
//IL_00c7: Expected O, but got Unknown
if (_cached != null && (Object)(object)_cached == (Object)null)
{
_cached = null;
}
if ((Object)(object)_cached != (Object)null)
{
return _cached;
}
if (_hudType == null)
{
_hudType = AccessTools.TypeByName("HUDManager");
}
if (_hudType == null)
{
return null;
}
PropertyInfo propertyInfo = _hudType.GetProperty("Instance", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) ?? _hudType.GetProperty("instance", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
object obj = ((propertyInfo != null) ? propertyInfo.GetValue(null) : null);
bool flag = _hudInstance is Object && (Object)_hudInstance == (Object)null;
bool flag2 = obj is Object && (Object)obj == (Object)null;
if (_hudInstance == null || flag || (!flag2 && _hudInstance != obj))
{
_hudInstance = obj;
_cached = null;
}
if (_hudInstance == null)
{
return null;
}
FieldInfo fieldInfo = _hudType.GetField("UIAudio", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) ?? _hudType.GetField("uiAudio", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (fieldInfo != null)
{
object? value = fieldInfo.GetValue(_hudInstance);
_cached = (AudioSource)((value is AudioSource) ? value : null);
}
if ((Object)(object)_cached == (Object)null)
{
PropertyInfo propertyInfo2 = _hudType.GetProperty("UIAudio", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) ?? _hudType.GetProperty("uiAudio", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (propertyInfo2 != null)
{
object? value2 = propertyInfo2.GetValue(_hudInstance);
_cached = (AudioSource)((value2 is AudioSource) ? value2 : null);
}
}
if ((Object)(object)_cached == (Object)null)
{
object hudInstance = _hudInstance;
Component val = (Component)((hudInstance is Component) ? hudInstance : null);
if ((Object)(object)val != (Object)null)
{
_cached = val.GetComponentInChildren<AudioSource>(true);
}
}
return _cached;
}
}
[HarmonyPatch(typeof(AudioSource), "PlayOneShot", new Type[] { typeof(AudioClip) })]
public static class Patch_AudioSource_PlayOneShot_1
{
private static bool Prefix(AudioSource __instance)
{
if (!Plugin.SuppressHudSfxActive)
{
return true;
}
AudioSource hudAudio = HudAudioLocator.GetHudAudio();
if ((Object)(object)hudAudio != (Object)null && (Object)(object)__instance == (Object)(object)hudAudio)
{
return false;
}
return true;
}
}
[HarmonyPatch(typeof(AudioSource), "PlayOneShot", new Type[]
{
typeof(AudioClip),
typeof(float)
})]
public static class Patch_AudioSource_PlayOneShot_2
{
private static bool Prefix(AudioSource __instance)
{
if (!Plugin.SuppressHudSfxActive)
{
return true;
}
AudioSource hudAudio = HudAudioLocator.GetHudAudio();
if ((Object)(object)hudAudio != (Object)null && (Object)(object)__instance == (Object)(object)hudAudio)
{
return false;
}
return true;
}
}
[HarmonyPatch(typeof(HUDManager), "Awake")]
public static class Patch_HUD_Awake_ResetAudioLocator
{
private static void Postfix()
{
HudAudioLocator.Reset();
}
}
internal static class Utils
{
private static Type _grabType;
private static FieldInfo _fi_itemProps;
private static FieldInfo _fi_scrapValue;
private static FieldInfo _fi_isInShipRoom;
private static FieldInfo _fi_isInElevator;
private static FieldInfo _fi_ip_isScrap;
private static FieldInfo _fi_ip_scrapValue;
private static FieldInfo _fi_isHeld;
private static FieldInfo _fi_isPocketed;
private static FieldInfo _fi_playerHeldBy;
private static Type _sorType;
private static Type _gnmType;
private static Type _pcbType;
private static PropertyInfo _pi_SOR_Instance;
private static FieldInfo _fi_SOR_localPlayerController;
private static PropertyInfo _pi_SOR_localPlayerController;
private static PropertyInfo _pi_GNM_Instance;
private static FieldInfo _fi_GNM_localPlayerController;
private static PropertyInfo _pi_GNM_localPlayerController;
private static FieldInfo _fi_PCB_isInHangar;
private static FieldInfo _fi_PCB_isInShip;
private static FieldInfo _fi_PCB_isLocal;
private static FieldInfo _fi_PCB_isOwner;
private static Object[] _grabbablesCache = (Object[])(object)new Object[0];
private static float _lastCacheAt = -999f;
private const float CacheWindowSeconds = 2f;
private static Bounds _shipBounds;
private static float _shipBoundsLastBuild = -999f;
private const float ShipBoundsRebuildSeconds = 3f;
private const float ShipBoundsPadding = 8f;
private static readonly string[] _shipNameNeedles = new string[2] { "ship", "hangar" };
private const int ParentHeuristicMaxDepth = 24;
public static object GetLocalPlayerController()
{
if (_sorType == null)
{
_sorType = AccessTools.TypeByName("StartOfRound");
if (_sorType != null)
{
_pi_SOR_Instance = _sorType.GetProperty("Instance", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
_fi_SOR_localPlayerController = _sorType.GetField("localPlayerController", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
_pi_SOR_localPlayerController = _sorType.GetProperty("localPlayerController", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
}
}
if (_sorType != null && _pi_SOR_Instance != null)
{
object value = _pi_SOR_Instance.GetValue(null);
if (value != null)
{
object obj = ((_fi_SOR_localPlayerController != null) ? _fi_SOR_localPlayerController.GetValue(value) : null);
if (obj == null && _pi_SOR_localPlayerController != null)
{
obj = _pi_SOR_localPlayerController.GetValue(value);
}
if (obj != null)
{
return obj;
}
}
}
if (_gnmType == null)
{
_gnmType = AccessTools.TypeByName("GameNetworkManager");
if (_gnmType != null)
{
_pi_GNM_Instance = _gnmType.GetProperty("Instance", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
_fi_GNM_localPlayerController = _gnmType.GetField("localPlayerController", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
_pi_GNM_localPlayerController = _gnmType.GetProperty("localPlayerController", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
}
}
if (_gnmType != null && _pi_GNM_Instance != null)
{
object value2 = _pi_GNM_Instance.GetValue(null);
if (value2 != null)
{
object obj2 = ((_fi_GNM_localPlayerController != null) ? _fi_GNM_localPlayerController.GetValue(value2) : null);
if (obj2 == null && _pi_GNM_localPlayerController != null)
{
obj2 = _pi_GNM_localPlayerController.GetValue(value2);
}
if (obj2 != null)
{
return obj2;
}
}
}
return null;
}
public static bool IsPlayerInShip(object playerControllerB)
{
//IL_016a: Unknown result type (might be due to invalid IL or missing references)
//IL_016f: Unknown result type (might be due to invalid IL or missing references)
//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
if (playerControllerB == null)
{
return false;
}
if (_pcbType == null)
{
_pcbType = playerControllerB.GetType();
_fi_PCB_isInHangar = _pcbType.GetField("isInHangarShipRoom", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
_fi_PCB_isInShip = _pcbType.GetField("isInShipRoom", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
_fi_PCB_isLocal = _pcbType.GetField("isLocalPlayer", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
_fi_PCB_isOwner = _pcbType.GetField("IsOwner", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
}
bool? flag = ((_fi_PCB_isLocal != null) ? ((bool?)_fi_PCB_isLocal.GetValue(playerControllerB)) : null);
if (flag.HasValue && !flag.Value)
{
return false;
}
bool? flag2 = ((_fi_PCB_isOwner != null) ? ((bool?)_fi_PCB_isOwner.GetValue(playerControllerB)) : null);
if (flag2.HasValue && !flag2.Value)
{
return false;
}
bool? flag3 = ((_fi_PCB_isInHangar != null) ? ((bool?)_fi_PCB_isInHangar.GetValue(playerControllerB)) : null);
if (flag3.HasValue && flag3.Value)
{
return true;
}
bool? flag4 = ((_fi_PCB_isInShip != null) ? ((bool?)_fi_PCB_isInShip.GetValue(playerControllerB)) : null);
if (flag4.HasValue)
{
return flag4.Value;
}
Bounds shipBounds = GetShipBounds();
Transform val = null;
Component val2 = (Component)((playerControllerB is Component) ? playerControllerB : null);
if ((Object)(object)val2 != (Object)null)
{
val = val2.transform;
}
else
{
PropertyInfo property = _pcbType.GetProperty("transform");
if (property != null)
{
object? value = property.GetValue(playerControllerB, null);
val = (Transform)((value is Transform) ? value : null);
}
}
if ((Object)(object)val != (Object)null && ((Bounds)(ref shipBounds)).size != Vector3.zero)
{
return ((Bounds)(ref shipBounds)).Contains(val.position);
}
return false;
}
private static Transform GetShipRootTransform()
{
if (_sorType == null)
{
return null;
}
object obj = ((_pi_SOR_Instance != null) ? _pi_SOR_Instance.GetValue(null) : null);
if (obj == null)
{
return null;
}
FieldInfo field = _sorType.GetField("shipRoom", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (field != null)
{
object? value = field.GetValue(obj);
GameObject val = (GameObject)((value is GameObject) ? value : null);
if ((Object)(object)val != (Object)null)
{
return val.transform;
}
}
FieldInfo field2 = _sorType.GetField("hangarShip", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (field2 != null)
{
object? value2 = field2.GetValue(obj);
GameObject val2 = (GameObject)((value2 is GameObject) ? value2 : null);
if ((Object)(object)val2 != (Object)null)
{
return val2.transform;
}
}
FieldInfo field3 = _sorType.GetField("shipFloor", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (field3 != null)
{
object? value3 = field3.GetValue(obj);
GameObject val3 = (GameObject)((value3 is GameObject) ? value3 : null);
if ((Object)(object)val3 != (Object)null)
{
return val3.transform;
}
}
return null;
}
private static Bounds GetShipBounds()
{
//IL_003d: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
//IL_0052: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
//IL_00df: Unknown result type (might be due to invalid IL or missing references)
//IL_006a: Unknown result type (might be due to invalid IL or missing references)
//IL_006f: Unknown result type (might be due to invalid IL or missing references)
//IL_00d4: 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)
if (Time.time - _shipBoundsLastBuild <= 3f && ((Bounds)(ref _shipBounds)).size != Vector3.zero)
{
return _shipBounds;
}
_shipBoundsLastBuild = Time.time;
_shipBounds = default(Bounds);
Transform shipRootTransform = GetShipRootTransform();
if ((Object)(object)shipRootTransform == (Object)null)
{
return _shipBounds;
}
Collider[] componentsInChildren = ((Component)shipRootTransform).GetComponentsInChildren<Collider>(true);
if (componentsInChildren != null && componentsInChildren.Length != 0)
{
_shipBounds = componentsInChildren[0].bounds;
for (int i = 1; i < componentsInChildren.Length; i++)
{
((Bounds)(ref _shipBounds)).Encapsulate(componentsInChildren[i].bounds);
}
((Bounds)(ref _shipBounds)).Expand(8f);
}
if (((Bounds)(ref _shipBounds)).size == Vector3.zero)
{
if (Plugin.Log != null)
{
Plugin.Log.LogInfo((object)"[ShipLootTotal] Ship bounds empty, scheduling delayed rebuild.");
}
new GameObject("ShipBoundsRebuilder").AddComponent<ShipBoundsRebuilder>();
}
return _shipBounds;
}
private static Object[] GetGrabbables()
{
//IL_014f: Unknown result type (might be due to invalid IL or missing references)
//IL_0154: Unknown result type (might be due to invalid IL or missing references)
if (_grabType == null)
{
_grabType = AccessTools.TypeByName("GrabbableObject");
if (_grabType != null)
{
_fi_itemProps = _grabType.GetField("itemProperties", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
_fi_scrapValue = _grabType.GetField("scrapValue", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
_fi_isInShipRoom = _grabType.GetField("isInShipRoom", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
_fi_isInElevator = _grabType.GetField("isInElevator", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
_fi_isHeld = _grabType.GetField("isHeld", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
_fi_isPocketed = _grabType.GetField("isPocketed", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
_fi_playerHeldBy = _grabType.GetField("playerHeldBy", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
}
}
if (_grabType == null)
{
return (Object[])(object)new Object[0];
}
if (Time.time - _lastCacheAt > 2f || _grabbablesCache == null)
{
_lastCacheAt = Time.time;
Object[] array = Object.FindObjectsOfType(_grabType);
if (array == null || array.Length == 0)
{
Object[] array2 = Resources.FindObjectsOfTypeAll(_grabType);
if (array2 != null && array2.Length != 0)
{
List<Object> list = new List<Object>(array2.Length);
for (int i = 0; i < array2.Length; i++)
{
Object obj = array2[i];
Component val = (Component)(object)((obj is Component) ? obj : null);
if (!((Object)(object)val == (Object)null))
{
Scene scene = val.gameObject.scene;
if (((Scene)(ref scene)).IsValid())
{
list.Add(array2[i]);
}
}
}
array = list.ToArray();
}
}
_grabbablesCache = (Object[])((array != null) ? ((Array)array) : ((Array)new Object[0]));
}
return _grabbablesCache;
}
public static int SumShipScrapValues()
{
//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
//IL_0404: Unknown result type (might be due to invalid IL or missing references)
//IL_0409: 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)
//IL_0412: Unknown result type (might be due to invalid IL or missing references)
//IL_0104: Unknown result type (might be due to invalid IL or missing references)
//IL_0339: Unknown result type (might be due to invalid IL or missing references)
//IL_033e: Unknown result type (might be due to invalid IL or missing references)
//IL_034e: Unknown result type (might be due to invalid IL or missing references)
//IL_0376: Unknown result type (might be due to invalid IL or missing references)
//IL_037b: Unknown result type (might be due to invalid IL or missing references)
//IL_037e: Unknown result type (might be due to invalid IL or missing references)
//IL_0383: Unknown result type (might be due to invalid IL or missing references)
//IL_0387: Unknown result type (might be due to invalid IL or missing references)
//IL_0393: Unknown result type (might be due to invalid IL or missing references)
//IL_0395: Unknown result type (might be due to invalid IL or missing references)
Object[] grabbables = GetGrabbables();
if (grabbables == null || grabbables.Length == 0)
{
return 0;
}
if (_fi_ip_isScrap == null || _fi_ip_scrapValue == null)
{
Object val = null;
for (int i = 0; i < grabbables.Length; i++)
{
if (grabbables[i] != (Object)null)
{
val = grabbables[i];
break;
}
}
if (val != (Object)null && _fi_itemProps != null)
{
object value = _fi_itemProps.GetValue(val);
if (value != null)
{
Type type = value.GetType();
if (_fi_ip_isScrap == null)
{
_fi_ip_isScrap = type.GetField("isScrap", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
}
if (_fi_ip_scrapValue == null)
{
_fi_ip_scrapValue = type.GetField("scrapValue", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
}
}
}
}
int num = 0;
Bounds shipBounds = GetShipBounds();
Transform shipRootTransform = GetShipRootTransform();
foreach (Object val2 in grabbables)
{
if (val2 == (Object)null)
{
continue;
}
Transform val3 = ((((val2 is Component) ? val2 : null) != (Object)null) ? ((Component)val2).transform : null);
bool flag = false;
int num2 = 0;
if (!(_fi_itemProps != null))
{
continue;
}
object value2 = _fi_itemProps.GetValue(val2);
if (value2 != null && _fi_ip_isScrap != null)
{
object value3 = _fi_ip_isScrap.GetValue(value2);
if (value3 is bool && (bool)value3)
{
flag = true;
}
}
if (!flag)
{
continue;
}
if (_fi_ip_scrapValue != null)
{
object value4 = _fi_ip_scrapValue.GetValue(value2);
if (value4 is int)
{
num2 = Math.Max(num2, (int)value4);
}
}
if (_fi_scrapValue != null)
{
object value5 = _fi_scrapValue.GetValue(val2);
if (value5 is int)
{
num2 = Math.Max(num2, (int)value5);
}
}
if (num2 <= 0)
{
continue;
}
if (_fi_isHeld != null)
{
object value6 = _fi_isHeld.GetValue(val2);
if (value6 is bool && (bool)value6)
{
continue;
}
}
if (_fi_isPocketed != null)
{
object value7 = _fi_isPocketed.GetValue(val2);
if (value7 is bool && (bool)value7)
{
continue;
}
}
bool flag2 = false;
if (_fi_isInShipRoom != null)
{
object value8 = _fi_isInShipRoom.GetValue(val2);
if (value8 is bool && (bool)value8)
{
flag2 = true;
}
}
if (!flag2 && _fi_isInElevator != null)
{
object value9 = _fi_isInElevator.GetValue(val2);
if (value9 is bool && (bool)value9)
{
flag2 = true;
}
}
if (!flag2 && (Object)(object)val3 != (Object)null)
{
int num3 = 0;
Transform val4 = val3;
while ((Object)(object)val4 != (Object)null && num3 < 24)
{
string name = ((Object)val4).name;
if (!string.IsNullOrEmpty(name))
{
string text = name.ToLowerInvariant();
for (int k = 0; k < _shipNameNeedles.Length; k++)
{
if (text.IndexOf(_shipNameNeedles[k], StringComparison.Ordinal) >= 0)
{
flag2 = true;
break;
}
}
if (flag2)
{
break;
}
}
val4 = val4.parent;
num3++;
}
}
if (!flag2 && (Object)(object)val3 != (Object)null && ((Bounds)(ref shipBounds)).size != Vector3.zero && ((Bounds)(ref shipBounds)).Contains(val3.position))
{
flag2 = true;
}
if (!flag2 && (Object)(object)shipRootTransform != (Object)null && (Object)(object)val3 != (Object)null)
{
Vector3 position = val3.position;
Vector3 position2 = shipRootTransform.position;
position.y = position2.y;
if (Vector3.Distance(position, position2) < 30f)
{
flag2 = true;
}
}
if (flag2)
{
num += num2;
}
}
if (Plugin.Log != null)
{
ManualLogSource log = Plugin.Log;
string[] obj = new string[6]
{
"[DEBUG] Total=",
num.ToString(),
", Objects=",
grabbables.Length.ToString(),
", Bounds=",
null
};
Bounds shipBounds2 = GetShipBounds();
Vector3 size = ((Bounds)(ref shipBounds2)).size;
obj[5] = ((object)(Vector3)(ref size)).ToString();
log.LogInfo((object)string.Concat(obj));
}
return num;
}
public static void InvalidateGrabbablesCache()
{
_grabbablesCache = (Object[])(object)new Object[0];
_lastCacheAt = -999f;
}
}
internal static class ScrapValueSyncPatcher
{
public static void Apply(Harmony harmony)
{
//IL_010e: Unknown result type (might be due to invalid IL or missing references)
//IL_0115: Expected O, but got Unknown
Type type = AccessTools.TypeByName("GrabbableObject");
if (type == null)
{
if (Plugin.Log != null)
{
Plugin.Log.LogWarning((object)"ScrapValueSyncPatcher: GrabbableObject type not found.");
}
return;
}
BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
MethodInfo[] methods = type.GetMethods(bindingAttr);
string[] array = new string[5] { "ClientRpc", "SetScrap", "SyncScrap", "UpdateScrap", "ScrapValue" };
int num = 0;
foreach (MethodInfo methodInfo in methods)
{
string text = methodInfo.Name.ToLowerInvariant();
if (text.IndexOf("scrap", StringComparison.Ordinal) < 0)
{
continue;
}
ParameterInfo[] parameters = methodInfo.GetParameters();
if (parameters.Length == 0 || parameters[0].ParameterType != typeof(int))
{
continue;
}
bool flag = false;
for (int j = 0; j < array.Length; j++)
{
if (text.IndexOf(array[j].ToLowerInvariant(), StringComparison.Ordinal) >= 0)
{
flag = true;
break;
}
}
if (!flag)
{
continue;
}
try
{
HarmonyMethod val = new HarmonyMethod(typeof(ScrapValueSyncPatcher).GetMethod("ScrapValuePostfix", BindingFlags.Static | BindingFlags.NonPublic));
harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
num++;
}
catch (Exception ex)
{
if (Plugin.Log != null)
{
Plugin.Log.LogWarning((object)("ScrapValueSyncPatcher: failed to patch " + methodInfo.Name + " : " + ex.Message));
}
}
}
if (Plugin.Log != null)
{
Plugin.Log.LogInfo((object)("ScrapValueSyncPatcher: patched " + num + " scrap sync method(s)."));
}
}
private static void ScrapValuePostfix(object __instance, object[] __args)
{
try
{
if (__instance == null || __args == null || __args.Length == 0)
{
return;
}
object obj = __args[0];
if (obj is int)
{
int num = (int)obj;
FieldInfo field = __instance.GetType().GetField("scrapValue", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (field != null)
{
field.SetValue(__instance, num);
Utils.InvalidateGrabbablesCache();
}
}
}
catch
{
}
}
}
public class ShipBoundsRebuilder : MonoBehaviour
{
[CompilerGenerated]
private sealed class <Start>d__0 : IEnumerator<object>, IDisposable, IEnumerator
{
private int <>1__state;
private object <>2__current;
public ShipBoundsRebuilder <>4__this;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <Start>d__0(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<>1__state = -2;
}
private bool MoveNext()
{
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_002e: Expected O, but got Unknown
int num = <>1__state;
ShipBoundsRebuilder shipBoundsRebuilder = <>4__this;
switch (num)
{
default:
return false;
case 0:
<>1__state = -1;
<>2__current = (object)new WaitForSeconds(5f);
<>1__state = 1;
return true;
case 1:
{
<>1__state = -1;
Utils.InvalidateGrabbablesCache();
object obj = typeof(Utils).GetMethod("GetShipBounds", BindingFlags.Static | BindingFlags.NonPublic).Invoke(null, null);
if (Plugin.Log != null)
{
Plugin.Log.LogInfo((object)("[ShipLootTotal] Delayed ship bounds rebuilt: " + obj));
}
Object.Destroy((Object)(object)((Component)shipBoundsRebuilder).gameObject);
return false;
}
}
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
[IteratorStateMachine(typeof(<Start>d__0))]
private IEnumerator Start()
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <Start>d__0(0)
{
<>4__this = this
};
}
}
[HarmonyPatch(typeof(StartOfRound), "SyncAlreadyHeldObjectsClientRpc")]
public static class Patch_SOR_AfterHeldSync
{
private static void Postfix()
{
Plugin._lastScanPostfixAt = -999f;
}
}