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 SharedUpgradesHelper v1.2.0
SharedUpgradesHelper.dll
Decompiled 6 months agousing 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.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [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: IgnoresAccessChecksTo("")] [assembly: AssemblyCompany("Omniscye")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("SharedUpgradesHelper")] [assembly: AssemblyTitle("SharedUpgradesHelper")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [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 SharedUpgradesHelper { [BepInPlugin("Omniscye.SharedUpgradesHelper", "SharedUpgradesHelper", "1.0")] public class SharedUpgradesHelper : BaseUnityPlugin { internal static SharedUpgradesHelper Instance { get; private set; } internal static ManualLogSource Logger => Instance._logger; private ManualLogSource _logger => ((BaseUnityPlugin)this).Logger; internal Harmony? Harmony { get; set; } private void Awake() { Instance = this; ((Component)this).gameObject.transform.parent = null; ((Object)((Component)this).gameObject).hideFlags = (HideFlags)61; Patch(); Logger.LogInfo((object)$"{((BaseUnityPlugin)this).Info.Metadata.GUID} v{((BaseUnityPlugin)this).Info.Metadata.Version} has loaded!"); } internal void Patch() { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown //IL_0026: Expected O, but got Unknown if (Harmony == null) { Harmony val = new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID); Harmony val2 = val; Harmony = val; } Harmony.PatchAll(); } internal void Unpatch() { Harmony? harmony = Harmony; if (harmony != null) { harmony.UnpatchSelf(); } } private void Update() { } } } namespace RepoMods.AutoHostSharedUpgrade { [BepInPlugin("repo.autohost.sharedupgrades", "AutoHost Shared Upgrades", "4.1.2")] public class AutoHostSharedUpgradePlugin : BaseUnityPlugin { [CompilerGenerated] private static class <>O { public static LogCallback <0>__OnLogMessage; } [CompilerGenerated] private sealed class <LobbyDestroyerCoroutine>d__16 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public AutoHostSharedUpgradePlugin <>4__this; private WaitForSeconds <wait>5__1; private int <destroyed>5__2; private Exception <e>5__3; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <LobbyDestroyerCoroutine>d__16(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <wait>5__1 = null; <e>5__3 = null; <>1__state = -2; } private bool MoveNext() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <wait>5__1 = new WaitForSeconds(2f); break; case 1: <>1__state = -1; if (!SharedUpgradesDetected || !InLobbyLevel || !LobbyDestroyArmed || Time.time - LobbyEnterTime < 0.5f) { break; } try { <destroyed>5__2 = DestroyAllUpgradesInScene(); if (<destroyed>5__2 > 0) { TotalDestroyed += <destroyed>5__2; ManualLogSource logS = LogS; if (logS != null) { logS.LogInfo((object)$"\ud83d\udc80 Nuked {<destroyed>5__2} upgrade(s) in Lobby (session total: {TotalDestroyed})"); } } } catch (Exception ex) { <e>5__3 = ex; ManualLogSource logS2 = LogS; if (logS2 != null) { logS2.LogError((object)("Upgrade destroyer error: " + <e>5__3.Message)); } } break; } <>2__current = <wait>5__1; <>1__state = 1; return true; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } public const string PluginGuid = "repo.autohost.sharedupgrades"; public const string PluginName = "AutoHost Shared Upgrades"; public const string PluginVersion = "4.1.2"; internal static ManualLogSource LogS; internal static Harmony HarmonyInstance; internal static bool SharedUpgradesDetected; internal static bool InLobbyLevel; internal static bool ShopSeenThisRun; internal static bool LobbyDestroyArmed; internal static float LobbyEnterTime; internal static int TotalDestroyed; private const float DestroyTickSeconds = 2f; private const float PostLobbyGrace = 0.5f; private void Awake() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown LogS = ((BaseUnityPlugin)this).Logger; HarmonyInstance = new Harmony("repo.autohost.sharedupgrades"); object obj = <>O.<0>__OnLogMessage; if (obj == null) { LogCallback val = OnLogMessage; <>O.<0>__OnLogMessage = val; obj = (object)val; } Application.logMessageReceived += (LogCallback)obj; TryProbeForSharedUpgradesTypes(); HarmonyInstance.PatchAll(Assembly.GetExecutingAssembly()); LogS.LogInfo((object)string.Format("{0} {1} loaded. SharedUpgradesDetected={2}", "AutoHost Shared Upgrades", "4.1.2", SharedUpgradesDetected)); ((MonoBehaviour)this).StartCoroutine(LobbyDestroyerCoroutine()); } private void OnDestroy() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown object obj = <>O.<0>__OnLogMessage; if (obj == null) { LogCallback val = OnLogMessage; <>O.<0>__OnLogMessage = val; obj = (object)val; } Application.logMessageReceived -= (LogCallback)obj; try { Harmony harmonyInstance = HarmonyInstance; if (harmonyInstance != null) { harmonyInstance.UnpatchSelf(); } } catch { } } private static void OnLogMessage(string condition, string stackTrace, LogType type) { if (string.IsNullOrEmpty(condition)) { return; } string text = condition.ToLowerInvariant(); if (!SharedUpgradesDetected && (text.Contains("sharedupgrades") || text.Contains("shared upgrade"))) { SharedUpgradesDetected = true; ManualLogSource logS = LogS; if (logS != null) { logS.LogInfo((object)"SharedUpgrades detected via console log message."); } } if (text.Contains("level - shop") || text.Contains("level-shop")) { ShopSeenThisRun = true; InLobbyLevel = false; LobbyDestroyArmed = false; TotalDestroyed = 0; ManualLogSource logS2 = LogS; if (logS2 != null) { logS2.LogInfo((object)"SHOP DETECTED. Will arm destroyer when we reach Lobby."); } } else if (text.Contains("level - lobby") || text.Contains("level-lobby")) { InLobbyLevel = true; LobbyEnterTime = Time.time; LobbyDestroyArmed = ShopSeenThisRun; TotalDestroyed = 0; if (LobbyDestroyArmed) { ManualLogSource logS3 = LogS; if (logS3 != null) { logS3.LogInfo((object)"LOBBY DETECTED after SHOP. Upgrade destroyer ARMED (2s intervals). \ud83d\udc80"); } } else { ManualLogSource logS4 = LogS; if (logS4 != null) { logS4.LogInfo((object)"LOBBY DETECTED (no shop this run) — destroyer NOT armed."); } } } else { if (!text.Contains("level-") && !text.Contains("level - ")) { return; } if (InLobbyLevel || LobbyDestroyArmed) { ManualLogSource logS5 = LogS; if (logS5 != null) { logS5.LogInfo((object)$"Left Lobby — destroyer disarmed. Total destroyed this session: {TotalDestroyed}"); } TotalDestroyed = 0; } InLobbyLevel = false; LobbyDestroyArmed = false; } } [IteratorStateMachine(typeof(<LobbyDestroyerCoroutine>d__16))] private IEnumerator LobbyDestroyerCoroutine() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <LobbyDestroyerCoroutine>d__16(0) { <>4__this = this }; } private static int DestroyAllUpgradesInScene() { return DestroyUpgradesByItemAttributes(); } private static int DestroyUpgradesByItemAttributes() { int num = 0; Type type = AccessTools.TypeByName("ItemAttributes"); if (type == null) { return 0; } Object[] array = Object.FindObjectsOfType(type); if (array == null || array.Length == 0) { return 0; } Object[] array2 = array; foreach (Object val in array2) { Component val2 = (Component)(object)((val is Component) ? val : null); if ((Object)(object)val2 == (Object)null || (Object)(object)val2.gameObject == (Object)null || !IsUpgradeType(val2)) { continue; } string itemName = GetItemName(val2); try { ZeroPurchasedUpgradeStat(itemName); } catch { } try { Object.DestroyImmediate((Object)(object)val2.gameObject); num++; ManualLogSource logS = LogS; if (logS != null) { logS.LogInfo((object)("\ud83d\udc80 NUKED upgrade '" + itemName + "' from Lobby!")); } } catch (Exception ex) { ManualLogSource logS2 = LogS; if (logS2 != null) { logS2.LogWarning((object)("Failed to destroy upgrade '" + itemName + "': " + ex.Message)); } } } return num; } private static int DestroyUpgradesByName() { int num = 0; string[] source = new string[6] { "upgrade", "Upgrade", "UPGRADE", "item_upgrade", "Item_Upgrade", "SharedUpgrade" }; GameObject[] array = Object.FindObjectsOfType<GameObject>(); GameObject[] array2 = array; foreach (GameObject val in array2) { if ((Object)(object)val == (Object)null) { continue; } string goName = ((Object)val).name.ToLowerInvariant(); if (!source.Any((string p) => goName.Contains(p.ToLowerInvariant()))) { continue; } Component component = val.GetComponent(AccessTools.TypeByName("ItemAttributes")); if (!((Object)(object)component != (Object)null) || !IsUpgradeType(component)) { continue; } try { ZeroPurchasedUpgradeStat(GetItemName(component)); } catch { } try { Object.DestroyImmediate((Object)(object)val); num++; ManualLogSource logS = LogS; if (logS != null) { logS.LogInfo((object)("DESTROYED upgrade by name '" + ((Object)val).name + "' in Lobby! \ud83d\udc80\ud83d\udd0d")); } } catch { try { Object.Destroy((Object)(object)val); num++; } catch { } } } return num; } private static int DestroyUpgradesByTag() { int num = 0; string[] array = new string[4] { "Upgrade", "Item", "Pickup", "Purchasable" }; string[] array2 = array; foreach (string text in array2) { try { GameObject[] array3 = GameObject.FindGameObjectsWithTag(text); GameObject[] array4 = array3; foreach (GameObject val in array4) { if ((Object)(object)val == (Object)null) { continue; } Component component = val.GetComponent(AccessTools.TypeByName("ItemAttributes")); if (!((Object)(object)component != (Object)null) || !IsUpgradeType(component)) { continue; } try { ZeroPurchasedUpgradeStat(GetItemName(component)); } catch { } try { Object.DestroyImmediate((Object)(object)val); num++; ManualLogSource logS = LogS; if (logS != null) { logS.LogInfo((object)("DESTROYED upgrade by tag '" + text + "' in Lobby! \ud83d\udc80\ud83c\udff7\ufe0f")); } } catch { try { Object.Destroy((Object)(object)val); num++; } catch { } } } } catch { } } return num; } private static string GetItemName(Component itemAttributes) { try { object obj = AccessTools.Field(((object)itemAttributes).GetType(), "item")?.GetValue(itemAttributes); if (obj != null) { return AccessTools.Field(obj.GetType(), "itemAssetName")?.GetValue(obj)?.ToString() ?? "Unknown"; } } catch { } return "Unknown"; } private static void ZeroPurchasedUpgradeStat(string itemAssetName) { if (string.IsNullOrEmpty(itemAssetName)) { return; } try { Type type = AccessTools.TypeByName("StatsManager"); if (type == null) { return; } object obj = AccessTools.Field(type, "instance")?.GetValue(null); if (obj != null && AccessTools.Field(type, "itemsPurchased")?.GetValue(obj) is IDictionary dictionary) { if (!dictionary.Contains(itemAssetName)) { dictionary.Add(itemAssetName, 0); } else { dictionary[itemAssetName] = 0; } ManualLogSource logS = LogS; if (logS != null) { logS.LogInfo((object)("AutoHost: zeroed itemsPurchased for '" + itemAssetName + "' (prevents next-level respawn, no KeyNotFound).")); } } } catch (Exception ex) { ManualLogSource logS2 = LogS; if (logS2 != null) { logS2.LogWarning((object)("AutoHost: ZeroPurchasedUpgradeStat('" + itemAssetName + "') failed: " + ex.Message)); } } } private static void TryProbeForSharedUpgradesTypes() { try { Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { string name = assembly.GetName().Name; if (!string.IsNullOrEmpty(name) && (name.IndexOf("SharedUpgrades", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("Shared Upgrade", StringComparison.OrdinalIgnoreCase) >= 0)) { SharedUpgradesDetected = true; ManualLogSource logS = LogS; if (logS != null) { logS.LogInfo((object)("SharedUpgrades detected via assembly name: " + name)); } break; } foreach (Type item in assembly.GetTypesSafe()) { string text = item.FullName ?? item.Name; if (text.IndexOf("SharedUpgrades", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("Shared Upgrade", StringComparison.OrdinalIgnoreCase) >= 0) { SharedUpgradesDetected = true; ManualLogSource logS2 = LogS; if (logS2 != null) { logS2.LogInfo((object)("SharedUpgrades detected via type: " + text)); } return; } } } } catch (Exception ex) { ManualLogSource logS3 = LogS; if (logS3 != null) { logS3.LogDebug((object)("Probe for SharedUpgrades types failed: " + ex.Message)); } } } internal static bool ShouldAutoApply() { if (!SharedUpgradesDetected) { return false; } try { Type type = AccessTools.TypeByName("SemiFunc"); MethodInfo methodInfo = AccessTools.Method(type, "IsMasterClientOrSingleplayer", (Type[])null, (Type[])null); if (type != null && methodInfo != null) { return (bool)methodInfo.Invoke(null, null); } } catch { } return true; } internal static void TryAutoUseUpgrade(Component itemAttributes) { if ((Object)(object)itemAttributes == (Object)null) { return; } GameObject gameObject = itemAttributes.gameObject; if ((Object)(object)gameObject == (Object)null || !IsUpgradeType(itemAttributes)) { return; } if (!DeductMoneyForUpgrade(itemAttributes)) { ManualLogSource logS = LogS; if (logS != null) { logS.LogWarning((object)"AutoHost: Cannot afford upgrade, skipping auto-apply"); } return; } Type type = AccessTools.TypeByName("ItemToggle"); Component val = ((type != null) ? gameObject.GetComponent(type) : null); int num = -1; if ((Object)(object)val != (Object)null) { try { Type type2 = AccessTools.TypeByName("SemiFunc"); MethodInfo methodInfo = AccessTools.Method(type2, "PhotonViewIDPlayerAvatarLocal", (Type[])null, (Type[])null); if (methodInfo != null) { num = (int)methodInfo.Invoke(null, null); } AccessTools.Field(type, "playerTogglePhotonID")?.SetValue(val, num); ManualLogSource logS2 = LogS; if (logS2 != null) { logS2.LogInfo((object)$"AutoHost: set ItemToggle.playerTogglePhotonID={num}"); } } catch (Exception ex) { ManualLogSource logS3 = LogS; if (logS3 != null) { logS3.LogWarning((object)("AutoHost: set photonID failed: " + ex.Message)); } } } if ((Object)(object)val != (Object)null) { string[] array = new string[6] { "RPC_UseToggle", "Use", "UseItem", "ToggleUse", "Activate", "Consume" }; string[] array2 = array; foreach (string text in array2) { MethodInfo method = type.GetMethod(text, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[1] { typeof(int) }, null); MethodInfo method2 = type.GetMethod(text, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null); try { if (method != null && num != -1) { method.Invoke(val, new object[1] { num }); ManualLogSource logS4 = LogS; if (logS4 != null) { logS4.LogInfo((object)("AutoHost: ItemToggle." + text + "(int) -> OK")); } ScrubUpgradeFromDelivery(itemAttributes); try { ZeroPurchasedUpgradeStat(GetItemName(itemAttributes)); return; } catch { return; } } if (method2 != null) { method2.Invoke(val, null); ManualLogSource logS5 = LogS; if (logS5 != null) { logS5.LogInfo((object)("AutoHost: ItemToggle." + text + "() -> OK")); } ScrubUpgradeFromDelivery(itemAttributes); try { ZeroPurchasedUpgradeStat(GetItemName(itemAttributes)); return; } catch { return; } } } catch (Exception ex2) { ManualLogSource logS6 = LogS; if (logS6 != null) { logS6.LogWarning((object)("AutoHost: ItemToggle." + text + " failed: " + ex2.Message)); } } } } int num2 = 0; Component[] components = gameObject.GetComponents<Component>(); foreach (Component val2 in components) { if ((Object)(object)val2 == (Object)null) { continue; } Type type3 = ((object)val2).GetType(); if (!type3.Name.StartsWith("ItemUpgrade", StringComparison.Ordinal)) { continue; } try { if ((Object)(object)val != (Object)null) { FieldInfo fieldInfo = AccessTools.Field(type3, "itemToggle"); if (fieldInfo != null && fieldInfo.GetValue(val2) == null) { fieldInfo.SetValue(val2, val); } } } catch { } MethodInfo method3 = type3.GetMethod("Upgrade", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null); if (method3 == null) { continue; } try { method3.Invoke(val2, null); ManualLogSource logS7 = LogS; if (logS7 != null) { logS7.LogInfo((object)("AutoHost: " + type3.Name + ".Upgrade() -> OK")); } num2++; } catch (Exception ex3) { ManualLogSource logS8 = LogS; if (logS8 != null) { logS8.LogWarning((object)("AutoHost: " + type3.Name + ".Upgrade() threw: " + ex3.Message)); } } } if (num2 == 0) { ManualLogSource logS9 = LogS; if (logS9 != null) { logS9.LogWarning((object)"AutoHost: No ItemUpgrade* components found to apply."); } return; } ScrubUpgradeFromDelivery(itemAttributes); try { ZeroPurchasedUpgradeStat(GetItemName(itemAttributes)); } catch { } } private static bool DeductMoneyForUpgrade(Component itemAttributes) { try { FieldInfo fieldInfo = AccessTools.Field(((object)itemAttributes).GetType(), "value"); if (fieldInfo == null) { return false; } int num = (int)fieldInfo.GetValue(itemAttributes); Type type = AccessTools.TypeByName("SemiFunc"); MethodInfo methodInfo = AccessTools.Method(type, "StatGetRunCurrency", (Type[])null, (Type[])null); MethodInfo methodInfo2 = AccessTools.Method(type, "StatSetRunCurrency", (Type[])null, (Type[])null); if (methodInfo == null || methodInfo2 == null) { return false; } int num2 = (int)methodInfo.Invoke(null, null); if (num2 < num) { ManualLogSource logS = LogS; if (logS != null) { logS.LogWarning((object)$"AutoHost: Not enough currency ({num2}) for item cost ({num})"); } return false; } int num3 = num2 - num; methodInfo2.Invoke(null, new object[1] { num3 }); ManualLogSource logS2 = LogS; if (logS2 != null) { logS2.LogInfo((object)$"AutoHost: Deducted ${num} from currency ({num2} -> {num3})"); } try { Type type2 = AccessTools.TypeByName("StatsManager"); object obj = AccessTools.Field(type2, "instance")?.GetValue(null); if (obj != null) { object obj2 = AccessTools.Field(((object)itemAttributes).GetType(), "item")?.GetValue(itemAttributes); if (obj2 != null) { string text = AccessTools.Field(obj2.GetType(), "itemAssetName")?.GetValue(obj2)?.ToString(); if (!string.IsNullOrEmpty(text)) { AccessTools.Method(type2, "ItemPurchase", (Type[])null, (Type[])null)?.Invoke(obj, new object[1] { text }); AccessTools.Method(type2, "AddItemsUpgradesPurchased", (Type[])null, (Type[])null)?.Invoke(obj, new object[1] { text }); ManualLogSource logS3 = LogS; if (logS3 != null) { logS3.LogInfo((object)("AutoHost: Updated stats for purchase: " + text)); } } } } } catch (Exception ex) { ManualLogSource logS4 = LogS; if (logS4 != null) { logS4.LogWarning((object)("AutoHost: Stats update failed: " + ex.Message)); } } return true; } catch (Exception ex2) { ManualLogSource logS5 = LogS; if (logS5 != null) { logS5.LogError((object)("AutoHost: Money deduction failed: " + ex2.Message)); } return false; } } private static void ScrubUpgradeFromDelivery(Component itemAttributes) { try { Type type = AccessTools.TypeByName("ShopManager"); object value = AccessTools.Field(type, "instance").GetValue(null); if (value == null) { return; } FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); int num = 0; object obj = null; try { obj = AccessTools.Field(((object)itemAttributes).GetType(), "item")?.GetValue(itemAttributes); } catch { } FieldInfo[] array = fields; foreach (FieldInfo fieldInfo in array) { Type fieldType = fieldInfo.FieldType; if (!typeof(IList).IsAssignableFrom(fieldType)) { continue; } IList list = (IList)fieldInfo.GetValue(value); if (list == null || list.Count == 0) { continue; } List<int> list2 = new List<int>(); for (int j = 0; j < list.Count; j++) { object obj3 = list[j]; if (obj3 == null) { continue; } bool flag = false; if (obj3 == itemAttributes) { flag = true; } else { try { Type type2 = obj3.GetType(); object obj4 = AccessTools.Field(type2, "item")?.GetValue(obj3); if (obj4 != null && obj != null && obj4 == obj) { flag = true; } } catch { } } if (flag) { list2.Add(j); } } for (int num2 = list2.Count - 1; num2 >= 0; num2--) { list.RemoveAt(list2[num2]); num++; } } if (num > 0) { ManualLogSource logS = LogS; if (logS != null) { logS.LogInfo((object)$"AutoHost: scrubbed upgrade from delivery lists (removed {num})."); } } else { ManualLogSource logS2 = LogS; if (logS2 != null) { logS2.LogDebug((object)"AutoHost: no delivery entries to scrub (likely already cleaned by base game)."); } } } catch (Exception ex) { ManualLogSource logS3 = LogS; if (logS3 != null) { logS3.LogWarning((object)("AutoHost: ScrubUpgradeFromDelivery failed: " + ex.Message)); } } } private static bool IsUpgradeType(Component itemAttributes) { try { object obj = AccessTools.Field(((object)itemAttributes).GetType(), "item")?.GetValue(itemAttributes); if (obj == null) { return false; } FieldInfo fieldInfo = AccessTools.Field(obj.GetType(), "itemType"); if (fieldInfo == null) { return false; } string a = fieldInfo.GetValue(obj)?.ToString(); return string.Equals(a, "item_upgrade", StringComparison.Ordinal); } catch { return false; } } } internal static class ReflectionSafe { public static IEnumerable<Type> GetTypesSafe(this Assembly asm) { try { return asm.GetTypes(); } catch { return Enumerable.Empty<Type>(); } } } [HarmonyPatch] internal static class Patch_DestroyFirst { private static MethodBase TargetMethod() { Type type = AccessTools.TypeByName("ExtractionPoint"); return AccessTools.Method(type, "DestroyTheFirstPhysObjectsInShopList", (Type[])null, (Type[])null); } private static void Prefix() { if (!AutoHostSharedUpgradePlugin.ShouldAutoApply()) { return; } try { Type type = AccessTools.TypeByName("ShopManager"); object value = AccessTools.Field(type, "instance").GetValue(null); IList<Component> list = (IList<Component>)AccessTools.Field(type, "shoppingList").GetValue(value); if (list != null && list.Count != 0) { Component val = list[0]; FieldInfo fieldInfo = AccessTools.Field(((object)val).GetType(), "value"); int num = ((fieldInfo != null) ? ((int)fieldInfo.GetValue(val)) : 0); Type type2 = AccessTools.TypeByName("SemiFunc"); MethodInfo methodInfo = ((type2 != null) ? AccessTools.Method(type2, "StatGetRunCurrency", (Type[])null, (Type[])null) : null); int num2 = ((methodInfo != null) ? ((int)methodInfo.Invoke(null, null)) : int.MaxValue); if (num2 - num >= 0) { AutoHostSharedUpgradePlugin.TryAutoUseUpgrade(val); } } } catch (Exception ex) { ManualLogSource logS = AutoHostSharedUpgradePlugin.LogS; if (logS != null) { logS.LogWarning((object)("[Patch_DestroyFirst] " + ex.Message)); } } } } [HarmonyPatch] internal static class Patch_DestroyAll { private static MethodBase TargetMethod() { Type type = AccessTools.TypeByName("ExtractionPoint"); return AccessTools.Method(type, "DestroyAllPhysObjectsInShoppingList", (Type[])null, (Type[])null); } private static void Prefix() { if (!AutoHostSharedUpgradePlugin.ShouldAutoApply()) { return; } try { Type type = AccessTools.TypeByName("ShopManager"); object value = AccessTools.Field(type, "instance").GetValue(null); IEnumerable<Component> enumerable = (IEnumerable<Component>)AccessTools.Field(type, "shoppingList").GetValue(value); if (enumerable == null) { return; } Type type2 = AccessTools.TypeByName("SemiFunc"); MethodInfo methodInfo = ((type2 != null) ? AccessTools.Method(type2, "StatGetRunCurrency", (Type[])null, (Type[])null) : null); int num = ((methodInfo != null) ? ((int)methodInfo.Invoke(null, null)) : int.MaxValue); foreach (Component item in enumerable.ToList()) { if ((Object)(object)item == (Object)null) { continue; } FieldInfo fieldInfo = AccessTools.Field(((object)item).GetType(), "value"); int num2 = ((fieldInfo != null) ? ((int)fieldInfo.GetValue(item)) : 0); if (num - num2 < 0) { continue; } bool flag = false; try { int num3 = num; AutoHostSharedUpgradePlugin.TryAutoUseUpgrade(item); int num4 = ((methodInfo != null) ? ((int)methodInfo.Invoke(null, null)) : num); if (num4 < num3) { num = num4; flag = true; } } catch (Exception ex) { ManualLogSource logS = AutoHostSharedUpgradePlugin.LogS; if (logS != null) { logS.LogWarning((object)("AutoHost: Error in TryAutoUseUpgrade: " + ex.Message)); } } if (!flag) { num -= num2; } } } catch (Exception ex2) { ManualLogSource logS2 = AutoHostSharedUpgradePlugin.LogS; if (logS2 != null) { logS2.LogWarning((object)("[Patch_DestroyAll] " + ex2.Message)); } } } } [HarmonyPatch] internal static class Patch_SemiFunc_StatGetItemsPurchased { private static MethodBase TargetMethod() { Type type = AccessTools.TypeByName("SemiFunc"); return AccessTools.Method(type, "StatGetItemsPurchased", new Type[1] { typeof(string) }, (Type[])null); } private static bool Prefix(ref int __result, string itemName) { try { if (string.IsNullOrEmpty(itemName)) { __result = 0; return false; } Type type = AccessTools.TypeByName("StatsManager"); object obj = AccessTools.Field(type, "instance")?.GetValue(null); if (!(AccessTools.Field(type, "itemsPurchased")?.GetValue(obj) is IDictionary dictionary)) { __result = 0; return false; } if (!dictionary.Contains(itemName)) { dictionary[itemName] = 0; __result = 0; return false; } return true; } catch { __result = 0; return false; } } } }