using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using ExitGames.Client.Photon;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using REPOLib.Modules;
using UnityEngine;
using UnityEngine.Events;
using com.github.zehsteam.RetrievePlayerUpgrades.Dependencies;
using com.github.zehsteam.RetrievePlayerUpgrades.Extensions;
using com.github.zehsteam.RetrievePlayerUpgrades.Helpers;
using com.github.zehsteam.RetrievePlayerUpgrades.MonoBehaviours;
using com.github.zehsteam.RetrievePlayerUpgrades.Objects;
using com.github.zehsteam.RetrievePlayerUpgrades.Patches;
[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: AssemblyCompany("Zehs")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyCopyright("Copyright © 2025 Zehs")]
[assembly: AssemblyDescription("Retrieve upgrades from players who’ve left the lobby. Great for lobbies where players leave and new ones join. A solid alternative to TeamUpgrades or SharedUpgrades — keeps progress fair without feeling too easy.")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+8364bce351a4043913a18d6dc021e0f7170e0d4d")]
[assembly: AssemblyProduct("RetrievePlayerUpgrades")]
[assembly: AssemblyTitle("com.github.zehsteam.RetrievePlayerUpgrades")]
[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.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace com.github.zehsteam.RetrievePlayerUpgrades
{
internal static class Assets
{
public static GameObject ItemVolumeSetCollectionPrefab { get; private set; }
public static void Load()
{
LoadAssetsFromAssetBundle();
}
private static void LoadAssetsFromAssetBundle()
{
AssetBundle val = LoadAssetBundle("retrieveplayerupgrades_assets");
if (!((Object)(object)val == (Object)null))
{
ItemVolumeSetCollectionPrefab = LoadAssetFromAssetBundle<GameObject>("ItemVolumeSetCollection", val);
Logger.LogInfo("Successfully loaded assets from AssetBundle!");
}
}
private static AssetBundle LoadAssetBundle(string fileName)
{
try
{
string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
string text = Path.Combine(directoryName, fileName);
if (!File.Exists(text))
{
Logger.LogError("Failed to load AssetBundle \"" + fileName + "\". AssetBundle file does not exist at path \"" + text + "\"");
return null;
}
return AssetBundle.LoadFromFile(text);
}
catch (Exception arg)
{
Logger.LogError($"Failed to load AssetBundle \"{fileName}\". {arg}");
}
return null;
}
private static T LoadAssetFromAssetBundle<T>(string name, AssetBundle assetBundle) where T : Object
{
if (string.IsNullOrWhiteSpace(name))
{
Logger.LogError("Failed to load asset of type \"" + typeof(T).Name + "\" from AssetBundle. Name is null or whitespace.");
return default(T);
}
if ((Object)(object)assetBundle == (Object)null)
{
Logger.LogError("Failed to load asset of type \"" + typeof(T).Name + "\" with name \"" + name + "\" from AssetBundle. AssetBundle is null.");
return default(T);
}
T val = assetBundle.LoadAsset<T>(name);
if ((Object)(object)val == (Object)null)
{
Logger.LogError("Failed to load asset of type \"" + typeof(T).Name + "\" with name \"" + name + "\" from AssetBundle. No asset found with that type and name.");
return default(T);
}
return val;
}
}
internal static class ConfigManager
{
public static ConfigFile ConfigFile { get; private set; }
public static ConfigEntry<bool> ExtendedLogging { get; private set; }
public static ConfigEntry<bool> Upgrades_Enabled { get; private set; }
public static ConfigEntry<bool> Upgrades_DisableWithSharedUpgrades { get; private set; }
public static ConfigEntry<bool> Upgrades_RemoveLateJoinUpgradeItems { get; private set; }
public static void Initialize(ConfigFile configFile)
{
ConfigFile = configFile;
BindConfigs();
}
private static void BindConfigs()
{
ExtendedLogging = ConfigFile.Bind<bool>("General", "ExtendedLogging", false, "Enable extended logging.");
Upgrades_Enabled = ConfigFile.Bind<bool>("Upgrades", "Enabled", true, "If enabled, will spawn upgrades that missing players had.");
Upgrades_DisableWithSharedUpgrades = ConfigFile.Bind<bool>("Upgrades", "DisableWithSharedUpgrades", true, "If enabled, will disable this mod when any shared upgrades mod is installed.");
Upgrades_RemoveLateJoinUpgradeItems = ConfigFile.Bind<bool>("Upgrades", "RemoveLateJoinUpgradeItems", true, "If enabled, will remove spawned upgrade items that are from late joining players.");
}
}
internal static class Logger
{
public static ManualLogSource ManualLogSource { get; private set; }
public static void Initialize(ManualLogSource manualLogSource)
{
ManualLogSource = manualLogSource;
}
public static void LogInfo(object data, bool extended = false)
{
Log((LogLevel)16, data, extended);
}
public static void LogWarning(object data, bool extended = false)
{
Log((LogLevel)4, data, extended);
}
public static void LogError(object data, bool extended = false)
{
Log((LogLevel)2, data, extended);
}
public static void Log(LogLevel logLevel, object data, bool extended = false)
{
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
if (!extended || IsExtendedLoggingEnabled())
{
ManualLogSource manualLogSource = ManualLogSource;
if (manualLogSource != null)
{
manualLogSource.Log(logLevel, data);
}
}
}
public static bool IsExtendedLoggingEnabled()
{
if (ConfigManager.ExtendedLogging == null)
{
return false;
}
return ConfigManager.ExtendedLogging.Value;
}
}
[BepInPlugin("com.github.zehsteam.RetrievePlayerUpgrades", "RetrievePlayerUpgrades", "1.0.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
internal class Plugin : BaseUnityPlugin
{
private readonly Harmony _harmony = new Harmony("com.github.zehsteam.RetrievePlayerUpgrades");
internal static Plugin Instance { get; private set; }
private void Awake()
{
Instance = this;
Logger.Initialize(Logger.CreateLogSource("com.github.zehsteam.RetrievePlayerUpgrades"));
Logger.LogInfo("RetrievePlayerUpgrades has awoken!");
_harmony.PatchAll(typeof(PunManagerPatch));
_harmony.PatchAll(typeof(PlayerAvatarPatch));
ConfigManager.Initialize(((BaseUnityPlugin)this).Config);
Assets.Load();
PlayerHelper.Initialize();
}
}
public static class MyPluginInfo
{
public const string PLUGIN_GUID = "com.github.zehsteam.RetrievePlayerUpgrades";
public const string PLUGIN_NAME = "RetrievePlayerUpgrades";
public const string PLUGIN_VERSION = "1.0.0";
}
}
namespace com.github.zehsteam.RetrievePlayerUpgrades.Patches
{
[HarmonyPatch(typeof(PlayerAvatar))]
internal static class PlayerAvatarPatch
{
[HarmonyPatch("AddToStatsManagerRPC")]
[HarmonyPostfix]
private static void AddToStatsManagerRPCPatch(string _steamID)
{
if (ConfigManager.Upgrades_RemoveLateJoinUpgradeItems.Value)
{
ItemUpgradeAddon.DestroyUpgradesFromPlayer(_steamID);
}
}
}
[HarmonyPatch(typeof(PunManager))]
internal static class PunManagerPatch
{
[HarmonyPatch("TruckPopulateItemVolumes")]
[HarmonyPostfix]
private static void TruckPopulateItemVolumesPatch()
{
if (ConfigManager.Upgrades_Enabled.Value && (!SharedUpgradesProxy.Enabled || !ConfigManager.Upgrades_DisableWithSharedUpgrades.Value))
{
SpawnUpgardesForMissingPlayers();
}
}
public static void SpawnUpgardesForMissingPlayers()
{
if (!SemiFunc.IsMultiplayer() || !SemiFunc.IsMasterClient())
{
return;
}
if ((Object)(object)ItemManager.instance == (Object)null)
{
Logger.LogError("PunManagerPatch: Failed to spawn upgrades for missing players. ItemManager instance is null.");
return;
}
List<string> playerSteamIdsNotInLobby = PlayerHelper.GetPlayerSteamIdsNotInLobby();
if (playerSteamIdsNotInLobby.Count == 0)
{
return;
}
List<ItemStack> upgradeItemsFromPlayers = PlayerHelper.GetUpgradeItemsFromPlayers(playerSteamIdsNotInLobby);
if (upgradeItemsFromPlayers.Count != 0)
{
List<ItemStack> itemStacks = upgradeItemsFromPlayers.SortCustom().ToList();
((MonoBehaviour)ItemManager.instance).StartCoroutine(TruckHelper.SpawnUpgradesCoroutine(itemStacks, null, delegate(string reason)
{
Logger.LogError("PunManagerPatch: Failed to spawn upgrades for missing players. " + reason);
}));
}
}
}
}
namespace com.github.zehsteam.RetrievePlayerUpgrades.Objects
{
public class ItemStack
{
public Item Item { get; private set; }
public Dictionary<string, int> OwnerSteamIds { get; private set; } = new Dictionary<string, int>();
public int Count => GetCount();
public ItemStack(Item item)
{
Item = item;
}
public ItemStack(Item item, string steamId, int count)
: this(item)
{
Add(steamId, count);
}
public ItemStack(Item item, Dictionary<string, int> ownerSteamIds)
: this(item)
{
OwnerSteamIds = ownerSteamIds;
}
public bool IsValid()
{
return (Object)(object)Item != (Object)null && !string.IsNullOrWhiteSpace(Item.itemName) && Count > 0;
}
private int GetCount()
{
if (OwnerSteamIds == null || OwnerSteamIds.Count == 0)
{
return 0;
}
return OwnerSteamIds.Sum((KeyValuePair<string, int> x) => x.Value);
}
public void Add(string steamId, int count = 1)
{
if (OwnerSteamIds.TryGetValue(steamId, out var value))
{
OwnerSteamIds[steamId] = value + count;
}
else
{
OwnerSteamIds[steamId] = count;
}
}
public void Add(Dictionary<string, int> ownerSteamIds)
{
OwnerSteamIds = OwnerSteamIds.Combine(ownerSteamIds);
}
public void Remove(string steamId)
{
OwnerSteamIds.Remove(steamId);
}
public void Remove(string steamId, int count)
{
if (OwnerSteamIds.TryGetValue(steamId, out var value))
{
int num = value - count;
if (num > 0)
{
OwnerSteamIds[steamId] = num;
}
else
{
OwnerSteamIds.Remove(steamId);
}
}
}
}
public struct UpgradeNameMapping
{
public string ItemName { get; private set; }
public string DictionaryName { get; private set; }
public UpgradeNameMapping(string itemName, string dictionaryName)
{
ItemName = itemName;
DictionaryName = dictionaryName;
}
}
}
namespace com.github.zehsteam.RetrievePlayerUpgrades.MonoBehaviours
{
public class ItemUpgradeAddon : MonoBehaviour
{
public string OwnerSteamId;
private ItemAttributes _itemAttributes;
private ItemUpgrade _itemUpgrade;
private PhysGrabObject _physGrabObject;
private Rigidbody _rigidbody;
private int _defaultSolverIterations;
private int _defaultSolverVelocityIterations;
private CollisionDetectionMode _defaultCollisionDetectionMode;
private RigidbodyConstraints _defaultRigidbodyConstraints;
private bool _wasGrabbed;
public static List<ItemUpgradeAddon> Instances { get; private set; } = new List<ItemUpgradeAddon>();
private void Start()
{
//IL_005e: Unknown result type (might be due to invalid IL or missing references)
//IL_0068: Expected O, but got Unknown
if (!SemiFunc.IsMasterClient())
{
Object.Destroy((Object)(object)this);
}
_itemAttributes = ((Component)this).GetComponent<ItemAttributes>();
_itemUpgrade = ((Component)this).GetComponent<ItemUpgrade>();
_physGrabObject = ((Component)this).GetComponent<PhysGrabObject>();
_rigidbody = ((Component)this).GetComponent<Rigidbody>();
UnityEvent upgradeEvent = _itemUpgrade.upgradeEvent;
if (upgradeEvent != null)
{
upgradeEvent.AddListener(new UnityAction(OnUpdateEvent));
}
CacheDefaultRigidbodySettings();
UseCustomRigidbodySettings();
Instances.Add(this);
}
private void Update()
{
if (!_wasGrabbed && _physGrabObject.grabbed)
{
_wasGrabbed = true;
OnFirstGrab();
}
}
private void OnDestroy()
{
Instances.Remove(this);
}
private void OnFirstGrab()
{
UseDefaultRigidbodySettings();
}
private void OnUpdateEvent()
{
PlayerHelper.RemoveUpgradeForPlayer(OwnerSteamId, _itemAttributes.item.itemName);
}
private void CacheDefaultRigidbodySettings()
{
//IL_002a: Unknown result type (might be due to invalid IL or missing references)
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
//IL_003b: Unknown result type (might be due to invalid IL or missing references)
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
_defaultSolverIterations = _rigidbody.solverIterations;
_defaultSolverVelocityIterations = _rigidbody.solverVelocityIterations;
_defaultCollisionDetectionMode = _rigidbody.collisionDetectionMode;
_defaultRigidbodyConstraints = _rigidbody.constraints;
}
private void UseDefaultRigidbodySettings()
{
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
//IL_003e: Unknown result type (might be due to invalid IL or missing references)
_rigidbody.solverIterations = _defaultSolverIterations;
_rigidbody.solverVelocityIterations = _defaultSolverVelocityIterations;
_rigidbody.collisionDetectionMode = _defaultCollisionDetectionMode;
_rigidbody.constraints = _defaultRigidbodyConstraints;
}
private void UseCustomRigidbodySettings()
{
_rigidbody.solverIterations = 15;
_rigidbody.solverVelocityIterations = 6;
_rigidbody.collisionDetectionMode = (CollisionDetectionMode)3;
_rigidbody.constraints = (RigidbodyConstraints)112;
}
public static void DestroyUpgradesFromPlayer(string steamId)
{
if (!SemiFunc.IsMasterClient())
{
return;
}
foreach (ItemUpgradeAddon instance in Instances)
{
if (!(instance.OwnerSteamId != steamId))
{
instance._physGrabObject.DestroyPhysGrabObject();
}
}
}
}
public class ItemVolumeSet : MonoBehaviour
{
public ItemVolume[] itemVolumes = Array.Empty<ItemVolume>();
}
public class ItemVolumeSetCollection : MonoBehaviour
{
public ItemVolumeSet[] itemVolumeSets = Array.Empty<ItemVolumeSet>();
}
}
namespace com.github.zehsteam.RetrievePlayerUpgrades.Helpers
{
internal static class ItemHelper
{
public static List<Item> GetUpgradeItems()
{
return Items.AllItems.Where((Item item) => (int)item.itemType == 3).ToList();
}
public static Item GetUpgradeByName(string itemName)
{
return ((IEnumerable<Item>)GetUpgradeItems()).FirstOrDefault((Func<Item, bool>)((Item item) => item.itemName.Contains(itemName, StringComparison.OrdinalIgnoreCase)));
}
public static bool TryGetUpgradeByName(string itemName, out Item item)
{
item = GetUpgradeByName(itemName);
return (Object)(object)item != (Object)null;
}
}
internal static class PlayerHelper
{
private static NetworkedEvent _updateUpgradeForPlayerEvent;
public static void Initialize()
{
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
//IL_002b: Expected O, but got Unknown
_updateUpgradeForPlayerEvent = new NetworkedEvent("Update upgrade for player", (Action<EventData>)HandleUpdateUpgradeForPlayerEvent);
}
public static List<string> GetPlayerSteamIds()
{
if ((Object)(object)StatsManager.instance == (Object)null)
{
return new List<string>();
}
return StatsManager.instance.playerNames.Keys.ToList();
}
public static List<string> GetPlayerSteamIdsInLobby()
{
if ((Object)(object)GameDirector.instance == (Object)null)
{
return new List<string>();
}
return GameDirector.instance.PlayerList.Select((PlayerAvatar player) => player.steamID).ToList();
}
public static List<string> GetPlayerSteamIdsNotInLobby()
{
List<string> steamIdsInLobby = GetPlayerSteamIdsInLobby();
return (from steamId in GetPlayerSteamIds()
where !steamIdsInLobby.Contains(steamId)
select steamId).ToList();
}
public static Dictionary<string, int> GetUpgradesFromPlayer(string steamId)
{
if ((Object)(object)StatsManager.instance == (Object)null || string.IsNullOrWhiteSpace(steamId))
{
return new Dictionary<string, int>();
}
Dictionary<string, int> dictionary = new Dictionary<string, int>();
foreach (KeyValuePair<string, Dictionary<string, int>> upgradeDictionary in StatsManager.instance.GetUpgradeDictionaries())
{
if (upgradeDictionary.Value.TryGetValue(steamId, out var value) && value > 0 && StatsManager.instance.TryGetUpgradeItemName(upgradeDictionary.Key, out var itemName))
{
dictionary.Add(itemName, value);
}
}
Logger.LogInfo("\n\nGetUpgradesFromPlayer(" + steamId + ");\n" + JsonConvert.SerializeObject((object)dictionary, (Formatting)1) + "\n", extended: true);
return dictionary;
}
public static void RemoveUpgradeForPlayer(string steamId, string itemName)
{
UpdateUpgradeForPlayer(steamId, itemName, -1);
}
public static void UpdateUpgradeForPlayer(string steamId, string itemName, int amount)
{
//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
//IL_00d8: Expected O, but got Unknown
//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
//IL_00e5: Expected O, but got Unknown
//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
//IL_00f7: Expected O, but got Unknown
//IL_00fa: Expected O, but got Unknown
//IL_010c: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)StatsManager.instance == (Object)null || string.IsNullOrWhiteSpace(steamId) || !StatsManager.instance.TryGetUpgradeDictionaryName(itemName, out var dictionaryName) || !StatsManager.instance.TryGetUpgradeDictionary(dictionaryName, out var dictionary) || !dictionary.TryGetValue(steamId, out var value))
{
return;
}
int num = value + amount;
if (num > 0)
{
dictionary[steamId] = num;
}
else
{
dictionary.Remove(steamId);
}
Logger.LogInfo($"PlayerHelper: Updated \"{itemName}\" for player {steamId} by {amount}", extended: true);
if (SemiFunc.IsMultiplayer() && SemiFunc.IsMasterClient())
{
Hashtable val = new Hashtable();
((Dictionary<object, object>)val).Add((object)"SteamId", (object)steamId);
((Dictionary<object, object>)val).Add((object)"ItemName", (object)itemName);
((Dictionary<object, object>)val).Add((object)"Amount", (object)amount);
Hashtable val2 = val;
NetworkedEvent updateUpgradeForPlayerEvent = _updateUpgradeForPlayerEvent;
if (updateUpgradeForPlayerEvent != null)
{
updateUpgradeForPlayerEvent.RaiseEvent((object)val2, NetworkingEvents.RaiseOthers, SendOptions.SendReliable);
}
}
}
private static void HandleUpdateUpgradeForPlayerEvent(EventData eventData)
{
object customData = eventData.CustomData;
Hashtable val = (Hashtable)((customData is Hashtable) ? customData : null);
if (val != null)
{
UpdateUpgradeForPlayer((string)val[(object)"SteamId"], (string)val[(object)"ItemName"], (int)val[(object)"Amount"]);
}
}
public static List<ItemStack> GetUpgradeItemsFromPlayer(string steamId)
{
if ((Object)(object)StatsManager.instance == (Object)null || string.IsNullOrWhiteSpace(steamId))
{
return new List<ItemStack>();
}
Dictionary<string, int> upgradesFromPlayer = GetUpgradesFromPlayer(steamId);
if (upgradesFromPlayer.Count == 0)
{
return new List<ItemStack>();
}
List<ItemStack> list = new List<ItemStack>();
foreach (KeyValuePair<string, int> item2 in upgradesFromPlayer)
{
if (ItemHelper.TryGetUpgradeByName(item2.Key, out var item))
{
list.Add(new ItemStack(item, steamId, item2.Value));
}
}
return list;
}
public static List<ItemStack> GetUpgradeItemsFromPlayers(List<string> steamIds)
{
if (steamIds.Count == 0)
{
return new List<ItemStack>();
}
List<List<ItemStack>> list = new List<List<ItemStack>>();
foreach (string steamId in steamIds)
{
List<ItemStack> upgradeItemsFromPlayer = GetUpgradeItemsFromPlayer(steamId);
if (upgradeItemsFromPlayer.Count != 0)
{
list.Add(upgradeItemsFromPlayer);
}
}
List<ItemStack> list2 = list.CombineMany().ToList();
if (Logger.IsExtendedLoggingEnabled())
{
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.AppendLine("GetUpgradeItemsFromPlayers(" + string.Join(", ", steamIds) + ");\n");
foreach (ItemStack item in list2)
{
foreach (KeyValuePair<string, int> ownerSteamId in item.OwnerSteamIds)
{
stringBuilder.AppendLine($"Upgrade: \"{item.Item.itemName}\", SteamId: {ownerSteamId.Key}, Amount: {ownerSteamId.Value}");
}
}
Logger.LogInfo("\n\n" + stringBuilder.ToString().Trim() + "\n", extended: true);
}
return list2;
}
}
internal static class TruckHelper
{
[CompilerGenerated]
private sealed class <SpawnUpgradeCoroutine>d__3 : IEnumerator<object>, IEnumerator, IDisposable
{
private int <>1__state;
private object <>2__current;
public ItemVolume itemVolume;
public Item item;
public string ownerSteamId;
private Vector3 <position>5__1;
private Quaternion <rotation>5__2;
private GameObject <upgradeObject>5__3;
private ItemUpgradeAddon <itemUpgradeAddon>5__4;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <SpawnUpgradeCoroutine>d__3(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<upgradeObject>5__3 = null;
<itemUpgradeAddon>5__4 = null;
<>1__state = -2;
}
private bool MoveNext()
{
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
//IL_0034: Unknown result type (might be due to invalid IL or missing references)
//IL_0056: Unknown result type (might be due to invalid IL or missing references)
//IL_005b: Unknown result type (might be due to invalid IL or missing references)
//IL_006c: Unknown result type (might be due to invalid IL or missing references)
//IL_0071: Unknown result type (might be due to invalid IL or missing references)
//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
//IL_0103: Expected O, but got Unknown
//IL_0094: Unknown result type (might be due to invalid IL or missing references)
//IL_0099: Unknown result type (might be due to invalid IL or missing references)
//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
<position>5__1 = Vector3.zero;
<rotation>5__2 = Quaternion.identity;
if ((Object)(object)itemVolume != (Object)null)
{
<position>5__1 = ((Component)itemVolume).transform.position;
<rotation>5__2 = ((Component)itemVolume).transform.rotation;
}
else if ((Object)(object)PlayerAvatar.instance != (Object)null)
{
<position>5__1 = ((Component)PlayerAvatar.instance).transform.position;
<rotation>5__2 = ((Component)PlayerAvatar.instance).transform.rotation;
}
<upgradeObject>5__3 = Items.SpawnItem(item, <position>5__1, <rotation>5__2);
<itemUpgradeAddon>5__4 = <upgradeObject>5__3.AddComponent<ItemUpgradeAddon>();
<itemUpgradeAddon>5__4.OwnerSteamId = ownerSteamId;
<>2__current = (object)new WaitForSeconds(0.01f);
<>1__state = 1;
return true;
case 1:
<>1__state = -1;
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();
}
}
[CompilerGenerated]
private sealed class <SpawnUpgradesCoroutine>d__1 : IEnumerator<object>, IEnumerator, IDisposable
{
private int <>1__state;
private object <>2__current;
public List<ItemStack> itemStacks;
public Action onSuccess;
public Action<string> onFailure;
private Transform <truckMeshTransform>5__1;
private GameObject <collectionObject>5__2;
private ItemVolumeSetCollection <itemVolumeSetCollection>5__3;
private ItemVolumeSet[] <itemVolumeSets>5__4;
private int <i>5__5;
private ItemVolumeSet <itemVolumeSet>5__6;
private ItemStack <itemStack>5__7;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <SpawnUpgradesCoroutine>d__1(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<truckMeshTransform>5__1 = null;
<collectionObject>5__2 = null;
<itemVolumeSetCollection>5__3 = null;
<itemVolumeSets>5__4 = null;
<itemVolumeSet>5__6 = null;
<itemStack>5__7 = null;
<>1__state = -2;
}
private bool MoveNext()
{
//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
//IL_00cd: Expected O, but got Unknown
//IL_009f: Unknown result type (might be due to invalid IL or missing references)
//IL_00a9: Expected O, but got Unknown
//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)
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
if ((Object)(object)ItemManager.instance == (Object)null)
{
onFailure?.Invoke("ItemManager instance is null.");
return false;
}
if (itemStacks.Count == 0)
{
onFailure?.Invoke("No items to spawn.");
return false;
}
if (SemiFunc.RunIsLobby())
{
<>2__current = (object)new WaitForSeconds(2f);
<>1__state = 1;
return true;
}
<>2__current = (object)new WaitForSeconds(7f);
<>1__state = 2;
return true;
case 1:
<>1__state = -1;
goto IL_00de;
case 2:
<>1__state = -1;
goto IL_00de;
case 3:
{
<>1__state = -1;
<itemVolumeSet>5__6 = null;
<itemStack>5__7 = null;
<i>5__5++;
break;
}
IL_00de:
if (!TryGetTruckMeshTransform(out <truckMeshTransform>5__1))
{
onFailure?.Invoke("Could not find truck mesh transform.");
return false;
}
<collectionObject>5__2 = Object.Instantiate<GameObject>(Assets.ItemVolumeSetCollectionPrefab);
if ((Object)(object)<collectionObject>5__2 == (Object)null)
{
onFailure?.Invoke("ItemVolumeSetCollection prefab is null.");
return false;
}
<collectionObject>5__2.transform.SetParent(<truckMeshTransform>5__1);
<collectionObject>5__2.transform.SetLocalPositionAndRotation(Vector3.zero, Quaternion.identity);
if (!<collectionObject>5__2.TryGetComponent<ItemVolumeSetCollection>(ref <itemVolumeSetCollection>5__3))
{
Object.Destroy((Object)(object)<collectionObject>5__2);
onFailure?.Invoke("ItemVolumeSetCollection is null.");
return false;
}
<itemVolumeSets>5__4 = <itemVolumeSetCollection>5__3.itemVolumeSets;
<i>5__5 = 0;
break;
}
if (<i>5__5 < itemStacks.Count)
{
<itemVolumeSet>5__6 = null;
if (<i>5__5 < <itemVolumeSets>5__4.Length)
{
<itemVolumeSet>5__6 = <itemVolumeSets>5__4[<i>5__5];
}
<itemStack>5__7 = itemStacks[<i>5__5];
<>2__current = SpawnUpgradesCoroutine(<itemVolumeSet>5__6, <itemStack>5__7);
<>1__state = 3;
return true;
}
Object.Destroy((Object)(object)<collectionObject>5__2);
onSuccess?.Invoke();
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();
}
}
[CompilerGenerated]
private sealed class <SpawnUpgradesCoroutine>d__2 : IEnumerator<object>, IEnumerator, IDisposable
{
private int <>1__state;
private object <>2__current;
public ItemVolumeSet itemVolumeSet;
public ItemStack itemStack;
private ItemVolume[] <itemVolumes>5__1;
private int <index>5__2;
private Dictionary<string, int>.Enumerator <>s__3;
private KeyValuePair<string, int> <ownerSteamId>5__4;
private int <i>5__5;
private ItemVolume <itemVolume>5__6;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <SpawnUpgradesCoroutine>d__2(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
int num = <>1__state;
if (num == -3 || num == 1)
{
try
{
}
finally
{
<>m__Finally1();
}
}
<itemVolumes>5__1 = null;
<>s__3 = default(Dictionary<string, int>.Enumerator);
<ownerSteamId>5__4 = default(KeyValuePair<string, int>);
<itemVolume>5__6 = null;
<>1__state = -2;
}
private bool MoveNext()
{
//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
//IL_01bf: Expected O, but got Unknown
try
{
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
if (!itemStack.IsValid())
{
return false;
}
<itemVolumes>5__1 = Array.Empty<ItemVolume>();
if ((Object)(object)itemVolumeSet != (Object)null)
{
<itemVolumes>5__1 = itemVolumeSet.itemVolumes;
}
<index>5__2 = 0;
<>s__3 = itemStack.OwnerSteamIds.GetEnumerator();
<>1__state = -3;
goto IL_018c;
case 1:
<>1__state = -3;
<index>5__2++;
<itemVolume>5__6 = null;
<i>5__5++;
goto IL_0163;
case 2:
{
<>1__state = -1;
return false;
}
IL_0163:
if (<i>5__5 < <ownerSteamId>5__4.Value)
{
<itemVolume>5__6 = null;
if (<index>5__2 < <itemVolumes>5__1.Length)
{
<itemVolume>5__6 = <itemVolumes>5__1[<index>5__2];
}
<>2__current = SpawnUpgradeCoroutine(<itemVolume>5__6, itemStack.Item, <ownerSteamId>5__4.Key);
<>1__state = 1;
return true;
}
<ownerSteamId>5__4 = default(KeyValuePair<string, int>);
goto IL_018c;
IL_018c:
if (<>s__3.MoveNext())
{
<ownerSteamId>5__4 = <>s__3.Current;
<i>5__5 = 0;
goto IL_0163;
}
<>m__Finally1();
<>s__3 = default(Dictionary<string, int>.Enumerator);
<>2__current = (object)new WaitForSeconds(0.01f);
<>1__state = 2;
return true;
}
}
catch
{
//try-fault
((IDisposable)this).Dispose();
throw;
}
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
private void <>m__Finally1()
{
<>1__state = -1;
((IDisposable)<>s__3).Dispose();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
public static bool TryGetTruckMeshTransform(out Transform transform)
{
transform = null;
if ((Object)(object)TruckScreenText.instance == (Object)null)
{
Logger.LogInfo("TruckHelper: Failed to get truck mesh transform. TruckScreenText instance is null.");
return false;
}
try
{
transform = ((Component)TruckScreenText.instance).transform.parent.Find("Mesh");
return true;
}
catch (Exception arg)
{
Logger.LogInfo($"TruckHelper: Failed to get truck mesh transform. {arg}");
return false;
}
}
[IteratorStateMachine(typeof(<SpawnUpgradesCoroutine>d__1))]
public static IEnumerator SpawnUpgradesCoroutine(List<ItemStack> itemStacks, Action onSuccess = null, Action<string> onFailure = null)
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <SpawnUpgradesCoroutine>d__1(0)
{
itemStacks = itemStacks,
onSuccess = onSuccess,
onFailure = onFailure
};
}
[IteratorStateMachine(typeof(<SpawnUpgradesCoroutine>d__2))]
private static IEnumerator SpawnUpgradesCoroutine(ItemVolumeSet itemVolumeSet, ItemStack itemStack)
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <SpawnUpgradesCoroutine>d__2(0)
{
itemVolumeSet = itemVolumeSet,
itemStack = itemStack
};
}
[IteratorStateMachine(typeof(<SpawnUpgradeCoroutine>d__3))]
private static IEnumerator SpawnUpgradeCoroutine(ItemVolume itemVolume, Item item, string ownerSteamId)
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <SpawnUpgradeCoroutine>d__3(0)
{
itemVolume = itemVolume,
item = item,
ownerSteamId = ownerSteamId
};
}
}
}
namespace com.github.zehsteam.RetrievePlayerUpgrades.Extensions
{
internal static class DictionaryExtensions
{
public static Dictionary<T, int> Combine<T>(this Dictionary<T, int> dictionary1, Dictionary<T, int> dictionary2)
{
return new <>z__ReadOnlyArray<Dictionary<T, int>>(new Dictionary<T, int>[2] { dictionary1, dictionary2 }).CombineMany();
}
public static Dictionary<T, int> CombineMany<T>(this IEnumerable<Dictionary<T, int>> dictionaries)
{
Dictionary<T, int> dictionary = new Dictionary<T, int>();
foreach (Dictionary<T, int> dictionary2 in dictionaries)
{
if (dictionary2 == null)
{
continue;
}
foreach (KeyValuePair<T, int> item in dictionary2)
{
T key = item.Key;
if (dictionary.TryGetValue(key, out var value))
{
dictionary[key] = value + item.Value;
}
else
{
dictionary.Add(key, item.Value);
}
}
}
return dictionary;
}
}
internal static class ItemStackExtensions
{
public static IEnumerable<ItemStack> Combine(this IEnumerable<ItemStack> list1, IEnumerable<ItemStack> list2)
{
return new <>z__ReadOnlyArray<IEnumerable<ItemStack>>(new IEnumerable<ItemStack>[2] { list1, list2 }).CombineMany();
}
public static IEnumerable<ItemStack> CombineMany(this IEnumerable<IEnumerable<ItemStack>> lists)
{
Dictionary<string, ItemStack> dictionary = new Dictionary<string, ItemStack>();
foreach (IEnumerable<ItemStack> list in lists)
{
foreach (ItemStack item in list)
{
if (item.IsValid())
{
string itemName = item.Item.itemName;
if (dictionary.TryGetValue(itemName, out var value))
{
value.Add(item.OwnerSteamIds);
}
else
{
dictionary.Add(itemName, item);
}
}
}
}
return dictionary.Values;
}
public static IEnumerable<ItemStack> SortCustom(this IEnumerable<ItemStack> list)
{
string[] source = new string[8] { "Strength Upgrade", "Health Upgrade", "Stamina Upgrade", "Sprint Speed Upgrade", "Extra Jump Upgrade", "Range Upgrade", "Tumble Launch Upgrade", "Map Player Count Upgrade" };
Dictionary<string, int> orderLookup = source.Select((string name, int index) => new { name, index }).ToDictionary(x => x.name, x => x.index);
int value;
return list.OrderBy((ItemStack stack) => orderLookup.TryGetValue(stack.Item.itemName, out value) ? value : int.MaxValue);
}
}
internal static class StatsManagerExtensions
{
public static List<UpgradeNameMapping> UpgradeNameMappings { get; private set; }
static StatsManagerExtensions()
{
UpgradeNameMappings = new List<UpgradeNameMapping>();
UpgradeNameMappings.Add(new UpgradeNameMapping("Health Upgrade", "playerUpgradeHealth"));
UpgradeNameMappings.Add(new UpgradeNameMapping("Stamina Upgrade", "playerUpgradeStamina"));
UpgradeNameMappings.Add(new UpgradeNameMapping("Extra Jump Upgrade", "playerUpgradeExtraJump"));
UpgradeNameMappings.Add(new UpgradeNameMapping("Tumble Launch Upgrade", "playerUpgradeLaunch"));
UpgradeNameMappings.Add(new UpgradeNameMapping("Map Player Count Upgrade", "playerUpgradeMapPlayerCount"));
UpgradeNameMappings.Add(new UpgradeNameMapping("Sprint Speed Upgrade", "playerUpgradeSpeed"));
UpgradeNameMappings.Add(new UpgradeNameMapping("Strength Upgrade", "playerUpgradeStrength"));
UpgradeNameMappings.Add(new UpgradeNameMapping("Range Upgrade", "playerUpgradeRange"));
}
public static Dictionary<string, Dictionary<string, int>> GetDictionariesWithPrefix(this StatsManager statsManager, string value)
{
if ((Object)(object)statsManager == (Object)null || string.IsNullOrWhiteSpace(value))
{
return new Dictionary<string, Dictionary<string, int>>();
}
Dictionary<string, Dictionary<string, int>> dictionary = new Dictionary<string, Dictionary<string, int>>();
foreach (KeyValuePair<string, Dictionary<string, int>> dictionaryOfDictionary in statsManager.dictionaryOfDictionaries)
{
if (dictionaryOfDictionary.Key.StartsWith(value, StringComparison.OrdinalIgnoreCase))
{
dictionary.Add(dictionaryOfDictionary.Key, dictionaryOfDictionary.Value);
}
}
return dictionary;
}
public static Dictionary<string, Dictionary<string, int>> GetUpgradeDictionaries(this StatsManager statsManager)
{
if ((Object)(object)statsManager == (Object)null)
{
return new Dictionary<string, Dictionary<string, int>>();
}
return statsManager.GetDictionariesWithPrefix("playerUpgrade");
}
public static bool TryGetUpgradeDictionary(this StatsManager statsManager, string dictionaryName, out Dictionary<string, int> dictionary)
{
dictionary = null;
if ((Object)(object)statsManager == (Object)null || string.IsNullOrWhiteSpace(dictionaryName))
{
return false;
}
foreach (KeyValuePair<string, Dictionary<string, int>> upgradeDictionary in statsManager.GetUpgradeDictionaries())
{
if (!upgradeDictionary.Key.Equals(dictionaryName, StringComparison.OrdinalIgnoreCase))
{
continue;
}
dictionary = upgradeDictionary.Value;
return true;
}
return false;
}
public static bool TryGetUpgradeItemName(this StatsManager statsManager, string dictionaryName, out string itemName)
{
itemName = null;
if ((Object)(object)statsManager == (Object)null || string.IsNullOrWhiteSpace(dictionaryName))
{
return false;
}
foreach (UpgradeNameMapping upgradeNameMapping in UpgradeNameMappings)
{
if (!upgradeNameMapping.DictionaryName.Equals(dictionaryName, StringComparison.OrdinalIgnoreCase))
{
continue;
}
itemName = upgradeNameMapping.ItemName;
return true;
}
return false;
}
public static bool TryGetUpgradeDictionaryName(this StatsManager statsManager, string itemName, out string dictionaryName)
{
dictionaryName = null;
if ((Object)(object)statsManager == (Object)null || string.IsNullOrWhiteSpace(itemName))
{
return false;
}
foreach (UpgradeNameMapping upgradeNameMapping in UpgradeNameMappings)
{
if (!upgradeNameMapping.ItemName.Equals(itemName, StringComparison.OrdinalIgnoreCase))
{
continue;
}
dictionaryName = upgradeNameMapping.DictionaryName;
return true;
}
return false;
}
}
}
namespace com.github.zehsteam.RetrievePlayerUpgrades.Dependencies
{
internal static class SharedUpgradesProxy
{
private static List<string> _pluginGuids;
private static bool? _enabled;
public static bool Enabled
{
get
{
bool valueOrDefault = _enabled.GetValueOrDefault();
if (!_enabled.HasValue)
{
valueOrDefault = IsModInstalled();
_enabled = valueOrDefault;
}
return _enabled.Value;
}
}
static SharedUpgradesProxy()
{
_pluginGuids = new List<string>();
_pluginGuids.Add("EvilCheetah.REPO.TeamBoosters");
_pluginGuids.Add("Traktool.SharedUpgrades");
_pluginGuids.Add("SharkLucas.REPO.SyncHostUpgrades");
_pluginGuids.Add("NastyPabloDLL.LateJoinSharedUpgrades");
_pluginGuids.Add("hairo.SharedUpgrades");
_pluginGuids.Add("DuckyVR.UpgradesForAll");
_pluginGuids.Add("khalliv.SharedUpgradesChance");
_pluginGuids.Add("TGO.SyncUpgrades");
_pluginGuids.Add("AutoChrome.SharedConfigurableUpgradesChance");
}
private static bool IsModInstalled()
{
return Chainloader.PluginInfos.Keys.Any(_pluginGuids.Contains);
}
}
}
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
internal sealed class IgnoresAccessChecksToAttribute : Attribute
{
public IgnoresAccessChecksToAttribute(string assemblyName)
{
}
}
}
[CompilerGenerated]
internal sealed class <>z__ReadOnlyArray<T> : IEnumerable, ICollection, IList, IEnumerable<T>, IReadOnlyCollection<T>, IReadOnlyList<T>, ICollection<T>, IList<T>
{
int ICollection.Count => _items.Length;
bool ICollection.IsSynchronized => false;
object ICollection.SyncRoot => this;
object IList.this[int index]
{
get
{
return _items[index];
}
set
{
throw new NotSupportedException();
}
}
bool IList.IsFixedSize => true;
bool IList.IsReadOnly => true;
int IReadOnlyCollection<T>.Count => _items.Length;
T IReadOnlyList<T>.this[int index] => _items[index];
int ICollection<T>.Count => _items.Length;
bool ICollection<T>.IsReadOnly => true;
T IList<T>.this[int index]
{
get
{
return _items[index];
}
set
{
throw new NotSupportedException();
}
}
public <>z__ReadOnlyArray(T[] items)
{
_items = items;
}
IEnumerator IEnumerable.GetEnumerator()
{
return ((IEnumerable)_items).GetEnumerator();
}
void ICollection.CopyTo(Array array, int index)
{
((ICollection)_items).CopyTo(array, index);
}
int IList.Add(object value)
{
throw new NotSupportedException();
}
void IList.Clear()
{
throw new NotSupportedException();
}
bool IList.Contains(object value)
{
return ((IList)_items).Contains(value);
}
int IList.IndexOf(object value)
{
return ((IList)_items).IndexOf(value);
}
void IList.Insert(int index, object value)
{
throw new NotSupportedException();
}
void IList.Remove(object value)
{
throw new NotSupportedException();
}
void IList.RemoveAt(int index)
{
throw new NotSupportedException();
}
IEnumerator<T> IEnumerable<T>.GetEnumerator()
{
return ((IEnumerable<T>)_items).GetEnumerator();
}
void ICollection<T>.Add(T item)
{
throw new NotSupportedException();
}
void ICollection<T>.Clear()
{
throw new NotSupportedException();
}
bool ICollection<T>.Contains(T item)
{
return ((ICollection<T>)_items).Contains(item);
}
void ICollection<T>.CopyTo(T[] array, int arrayIndex)
{
((ICollection<T>)_items).CopyTo(array, arrayIndex);
}
bool ICollection<T>.Remove(T item)
{
throw new NotSupportedException();
}
int IList<T>.IndexOf(T item)
{
return ((IList<T>)_items).IndexOf(item);
}
void IList<T>.Insert(int index, T item)
{
throw new NotSupportedException();
}
void IList<T>.RemoveAt(int index)
{
throw new NotSupportedException();
}
}