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.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;
}
}
}
}