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.Managers; 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.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("Zehs")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyCopyright("Copyright © 2026 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.2.0.0")] [assembly: AssemblyInformationalVersion("1.2.0+e2f33e873f9a0e76a29cdc6e8ef6bf2ec1e7ca14")] [assembly: AssemblyProduct("RetrievePlayerUpgrades")] [assembly: AssemblyTitle("com.github.zehsteam.RetrievePlayerUpgrades")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.2.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] [CompilerGenerated] internal sealed class <>z__ReadOnlyArray : IEnumerable, ICollection, IList, IEnumerable, IReadOnlyCollection, IReadOnlyList, ICollection, IList { 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.Count => _items.Length; T IReadOnlyList.this[int index] => _items[index]; int ICollection.Count => _items.Length; bool ICollection.IsReadOnly => true; T IList.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 IEnumerable.GetEnumerator() { return ((IEnumerable)_items).GetEnumerator(); } void ICollection.Add(T item) { throw new NotSupportedException(); } void ICollection.Clear() { throw new NotSupportedException(); } bool ICollection.Contains(T item) { return ((ICollection)_items).Contains(item); } void ICollection.CopyTo(T[] array, int arrayIndex) { ((ICollection)_items).CopyTo(array, arrayIndex); } bool ICollection.Remove(T item) { throw new NotSupportedException(); } int IList.IndexOf(T item) { return ((IList)_items).IndexOf(item); } void IList.Insert(int index, T item) { throw new NotSupportedException(); } void IList.RemoveAt(int index) { throw new NotSupportedException(); } } 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 readonly string AssetBundleFileName = "retrieveplayerupgrades_assets"; public static AssetBundle AssetBundle { get; private set; } public static bool IsLoaded { get; private set; } public static GameObject ItemVolumeSetCollectionPrefab { get; private set; } public static void Load() { string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); string text = Path.Combine(directoryName, AssetBundleFileName); if (!File.Exists(text)) { Logger.LogFatal("Failed to load assets. AssetBundle file could not be found at path \"" + text + "\". Make sure the \"" + AssetBundleFileName + "\" file is in the same folder as the mod's DLL file."); } else { AssetBundle = AssetBundle.LoadFromFile(text); if ((Object)(object)AssetBundle == (Object)null) { Logger.LogFatal("Failed to load assets. AssetBundle is null."); return; } OnAssetBundleLoaded(AssetBundle); IsLoaded = true; } } private static void OnAssetBundleLoaded(AssetBundle assetBundle) { ItemVolumeSetCollectionPrefab = LoadAsset("ItemVolumeSetCollection", assetBundle); } private static T LoadAsset(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(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; } private static bool TryLoadAsset(string name, AssetBundle assetBundle, out T asset) where T : Object { asset = LoadAsset(name, assetBundle); return (Object)(object)asset != (Object)null; } } internal static class Logger { public static ManualLogSource ManualLogSource { get; private set; } public static bool IsExtendedLoggingEnabled => ConfigManager.Misc_ExtendedLogging?.Value ?? false; public static void Initialize(ManualLogSource manualLogSource) { ManualLogSource = manualLogSource; } public static void LogDebug(object data) { Log((LogLevel)32, data); } public static void LogInfo(object data, bool extended = false) { Log((LogLevel)16, data, extended); } public static void LogMessage(object data, bool extended = false) { Log((LogLevel)8, 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 LogFatal(object data, bool extended = false) { Log((LogLevel)1, data, extended); } public static void Log(LogLevel logLevel, object data, bool extended = false) { //IL_0015: 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); } } } } [BepInPlugin("com.github.zehsteam.RetrievePlayerUpgrades", "RetrievePlayerUpgrades", "1.2.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(PunManager_Patches)); _harmony.PatchAll(typeof(PlayerAvatar_Patches)); 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.2.0"; } } namespace com.github.zehsteam.RetrievePlayerUpgrades.Patches { [HarmonyPatch(typeof(PlayerAvatar))] internal static class PlayerAvatar_Patches { [HarmonyPatch("AddToStatsManagerRPC")] [HarmonyPostfix] private static void AddToStatsManagerRPC_Patch(string _steamID) { if (ConfigManager.Upgrades_RemoveLateJoinUpgradeItems.Value) { ItemUpgradeAddon.DestroyUpgradesFromPlayer(_steamID); } } } [HarmonyPatch(typeof(PunManager))] internal static class PunManager_Patches { [HarmonyPatch("TruckPopulateItemVolumes")] [HarmonyPostfix] private static void TruckPopulateItemVolumes_Patch() { 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("Failed to spawn upgrades for missing players. ItemManager instance is null."); return; } List playerSteamIdsNotInLobby = PlayerHelper.GetPlayerSteamIdsNotInLobby(); if (playerSteamIdsNotInLobby.Count == 0) { return; } List upgradeItemsFromPlayers = PlayerHelper.GetUpgradeItemsFromPlayers(playerSteamIdsNotInLobby); if (upgradeItemsFromPlayers.Count != 0) { List itemStacks = upgradeItemsFromPlayers.SortCustom().ToList(); ((MonoBehaviour)ItemManager.instance).StartCoroutine(TruckHelper.SpawnUpgradesCoroutine(itemStacks, null, delegate(string reason) { Logger.LogError("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 OwnerSteamIds { get; private set; } = new Dictionary(); 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 ownerSteamIds) : this(item) { OwnerSteamIds = ownerSteamIds; } public bool IsValid() { if ((Object)(object)Item != (Object)null && !string.IsNullOrWhiteSpace(Item.itemName)) { return Count > 0; } return false; } private int GetCount() { if (OwnerSteamIds == null || OwnerSteamIds.Count == 0) { return 0; } return OwnerSteamIds.Sum((KeyValuePair 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 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 { [HideInInspector] 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 Instances { get; private set; } = new List(); private void Start() { //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Expected O, but got Unknown if (!SemiFunc.IsMasterClient()) { Object.Destroy((Object)(object)this); } _itemAttributes = ((Component)this).GetComponent(); _itemUpgrade = ((Component)this).GetComponent(); _physGrabObject = ((Component)this).GetComponent(); _rigidbody = ((Component)this).GetComponent(); UnityEvent upgradeEvent = _itemUpgrade.upgradeEvent; if (upgradeEvent != null) { upgradeEvent.AddListener(new UnityAction(OnUpgradeEvent)); } 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 OnUpgradeEvent() { PlayerHelper.RemoveUpgradeForPlayer(OwnerSteamId, _itemAttributes.item.itemName); } private void CacheDefaultRigidbodySettings() { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: 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_0029: Unknown result type (might be due to invalid IL or missing references) //IL_003a: 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(); } public class ItemVolumeSetCollection : MonoBehaviour { public ItemVolumeSet[] itemVolumeSets = Array.Empty(); } } namespace com.github.zehsteam.RetrievePlayerUpgrades.Managers { internal static class ConfigManager { public static ConfigFile ConfigFile { get; private set; } public static ConfigEntry Misc_ExtendedLogging { get; private set; } public static ConfigEntry Upgrades_Enabled { get; private set; } public static ConfigEntry Upgrades_DisableWithSharedUpgrades { get; private set; } public static ConfigEntry Upgrades_RemoveLateJoinUpgradeItems { get; private set; } public static void Initialize(ConfigFile configFile) { ConfigFile = configFile; BindConfigs(); } private static void BindConfigs() { Misc_ExtendedLogging = ConfigFile.Bind("General", "ExtendedLogging", false, "Enable extended logging."); Upgrades_Enabled = ConfigFile.Bind("Upgrades", "Enabled", true, "If enabled, will spawn upgrades that missing players had."); Upgrades_DisableWithSharedUpgrades = ConfigFile.Bind("Upgrades", "DisableWithSharedUpgrades", true, "If enabled, will disable this mod when any shared upgrades mod is installed."); Upgrades_RemoveLateJoinUpgradeItems = ConfigFile.Bind("Upgrades", "RemoveLateJoinUpgradeItems", true, "If enabled, will remove spawned upgrade items that are from late joining players."); } } } namespace com.github.zehsteam.RetrievePlayerUpgrades.Helpers { internal static class ItemHelper { public static List GetUpgradeItems() { return Items.AllItems.Where((Item item) => (int)item.itemType == 3).ToList(); } public static Item GetUpgradeByName(string itemName) { return ((IEnumerable)GetUpgradeItems()).FirstOrDefault((Func)((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_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown _updateUpgradeForPlayerEvent = new NetworkedEvent("Update upgrade for player", (Action)HandleUpdateUpgradeForPlayerEvent); } public static List GetPlayerSteamIds() { if ((Object)(object)StatsManager.instance == (Object)null) { return new List(); } return StatsManager.instance.playerNames.Keys.ToList(); } public static List GetPlayerSteamIdsInLobby() { if ((Object)(object)GameDirector.instance == (Object)null) { return new List(); } return GameDirector.instance.PlayerList.Select((PlayerAvatar player) => player.steamID).ToList(); } public static List GetPlayerSteamIdsNotInLobby() { List steamIdsInLobby = GetPlayerSteamIdsInLobby(); return (from steamId in GetPlayerSteamIds() where !steamIdsInLobby.Contains(steamId) select steamId).ToList(); } public static Dictionary GetUpgradesFromPlayer(string steamId) { if ((Object)(object)StatsManager.instance == (Object)null || string.IsNullOrWhiteSpace(steamId)) { return new Dictionary(); } Dictionary dictionary = new Dictionary(); foreach (KeyValuePair> 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_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Expected O, but got Unknown //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Expected O, but got Unknown //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Expected O, but got Unknown //IL_00b2: Expected O, but got Unknown //IL_00c3: 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)val).Add((object)"SteamId", (object)steamId); ((Dictionary)val).Add((object)"ItemName", (object)itemName); ((Dictionary)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 GetUpgradeItemsFromPlayer(string steamId) { if ((Object)(object)StatsManager.instance == (Object)null || string.IsNullOrWhiteSpace(steamId)) { return new List(); } Dictionary upgradesFromPlayer = GetUpgradesFromPlayer(steamId); if (upgradesFromPlayer.Count == 0) { return new List(); } List list = new List(); foreach (KeyValuePair item2 in upgradesFromPlayer) { if (ItemHelper.TryGetUpgradeByName(item2.Key, out var item)) { list.Add(new ItemStack(item, steamId, item2.Value)); } } return list; } public static List GetUpgradeItemsFromPlayers(List steamIds) { if (steamIds.Count == 0) { return new List(); } List> list = new List>(); foreach (string steamId in steamIds) { List upgradeItemsFromPlayer = GetUpgradeItemsFromPlayer(steamId); if (upgradeItemsFromPlayer.Count != 0) { list.Add(upgradeItemsFromPlayer); } } List 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 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 d__3 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public ItemVolume itemVolume; public Item item; public string ownerSteamId; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__3(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //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_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_008c: 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) //IL_00b8: Expected O, but got Unknown //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) switch (<>1__state) { default: return false; case 0: { <>1__state = -1; Vector3 val = Vector3.zero; Quaternion val2 = Quaternion.identity; if ((Object)(object)itemVolume != (Object)null) { val = ((Component)itemVolume).transform.position; val2 = ((Component)itemVolume).transform.rotation; } else if ((Object)(object)PlayerAvatar.instance != (Object)null) { val = ((Component)PlayerAvatar.instance).transform.position; val2 = ((Component)PlayerAvatar.instance).transform.rotation; } GameObject val3 = Items.SpawnItem(item, val, val2); ItemUpgradeAddon itemUpgradeAddon = val3.AddComponent(); itemUpgradeAddon.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 d__1 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public Action onFailure; public List itemStacks; public Action onSuccess; private GameObject 5__2; private ItemVolumeSet[] 5__3; private int 5__4; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__1(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { 5__2 = null; 5__3 = null; <>1__state = -2; } private bool MoveNext() { //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Expected O, but got Unknown //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Expected O, but got Unknown //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) Transform transform; ItemVolumeSetCollection itemVolumeSetCollection = default(ItemVolumeSetCollection); 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_00b9; case 2: <>1__state = -1; goto IL_00b9; case 3: { <>1__state = -1; 5__4++; break; } IL_00b9: if (!TryGetTruckMeshTransform(out transform)) { onFailure?.Invoke("Could not find truck mesh transform."); return false; } 5__2 = Object.Instantiate(Assets.ItemVolumeSetCollectionPrefab); if ((Object)(object)5__2 == (Object)null) { onFailure?.Invoke("ItemVolumeSetCollection prefab is null."); return false; } 5__2.transform.SetParent(transform); 5__2.transform.SetLocalPositionAndRotation(Vector3.zero, Quaternion.identity); if (!5__2.TryGetComponent(ref itemVolumeSetCollection)) { Object.Destroy((Object)(object)5__2); onFailure?.Invoke("ItemVolumeSetCollection is null."); return false; } 5__3 = itemVolumeSetCollection.itemVolumeSets; 5__4 = 0; break; } if (5__4 < itemStacks.Count) { ItemVolumeSet itemVolumeSet = null; if (5__4 < 5__3.Length) { itemVolumeSet = 5__3[5__4]; } ItemStack itemStack = itemStacks[5__4]; <>2__current = SpawnUpgradesCoroutine(itemVolumeSet, itemStack); <>1__state = 3; return true; } Object.Destroy((Object)(object)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 d__2 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public ItemStack itemStack; public ItemVolumeSet itemVolumeSet; private ItemVolume[] 5__2; private int 5__3; private Dictionary.Enumerator <>7__wrap3; private KeyValuePair 5__5; private int 5__6; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public 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(); } } 5__2 = null; <>7__wrap3 = default(Dictionary.Enumerator); 5__5 = default(KeyValuePair); <>1__state = -2; } private bool MoveNext() { //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Expected O, but got Unknown try { switch (<>1__state) { default: return false; case 0: <>1__state = -1; if (!itemStack.IsValid()) { return false; } 5__2 = Array.Empty(); if ((Object)(object)itemVolumeSet != (Object)null) { 5__2 = itemVolumeSet.itemVolumes; } 5__3 = 0; <>7__wrap3 = itemStack.OwnerSteamIds.GetEnumerator(); <>1__state = -3; goto IL_0143; case 1: <>1__state = -3; 5__3++; 5__6++; goto IL_0121; case 2: { <>1__state = -1; return false; } IL_0121: if (5__6 < 5__5.Value) { ItemVolume itemVolume = null; if (5__3 < 5__2.Length) { itemVolume = 5__2[5__3]; } <>2__current = SpawnUpgradeCoroutine(itemVolume, itemStack.Item, 5__5.Key); <>1__state = 1; return true; } 5__5 = default(KeyValuePair); goto IL_0143; IL_0143: if (<>7__wrap3.MoveNext()) { 5__5 = <>7__wrap3.Current; 5__6 = 0; goto IL_0121; } <>m__Finally1(); <>7__wrap3 = default(Dictionary.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)<>7__wrap3).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(d__1))] public static IEnumerator SpawnUpgradesCoroutine(List itemStacks, Action onSuccess = null, Action onFailure = null) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__1(0) { itemStacks = itemStacks, onSuccess = onSuccess, onFailure = onFailure }; } [IteratorStateMachine(typeof(d__2))] private static IEnumerator SpawnUpgradesCoroutine(ItemVolumeSet itemVolumeSet, ItemStack itemStack) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__2(0) { itemVolumeSet = itemVolumeSet, itemStack = itemStack }; } [IteratorStateMachine(typeof(d__3))] private static IEnumerator SpawnUpgradeCoroutine(ItemVolume itemVolume, Item item, string ownerSteamId) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__3(0) { itemVolume = itemVolume, item = item, ownerSteamId = ownerSteamId }; } } } namespace com.github.zehsteam.RetrievePlayerUpgrades.Extensions { internal static class DictionaryExtensions { public static Dictionary Combine(this Dictionary dictionary1, Dictionary dictionary2) { return new <>z__ReadOnlyArray>(new Dictionary[2] { dictionary1, dictionary2 }).CombineMany(); } public static Dictionary CombineMany(this IEnumerable> dictionaries) { Dictionary dictionary = new Dictionary(); foreach (Dictionary dictionary2 in dictionaries) { if (dictionary2 == null) { continue; } foreach (KeyValuePair 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 Combine(this IEnumerable list1, IEnumerable list2) { return new <>z__ReadOnlyArray>(new IEnumerable[2] { list1, list2 }).CombineMany(); } public static IEnumerable CombineMany(this IEnumerable> lists) { Dictionary dictionary = new Dictionary(); foreach (IEnumerable 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 SortCustom(this IEnumerable 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 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)) ? int.MaxValue : value); } } internal static class StatsManagerExtensions { public static List UpgradeNameMappings { get; private set; } static StatsManagerExtensions() { UpgradeNameMappings = new List(); UpgradeNameMappings.Add(new UpgradeNameMapping("Crouch Rest Upgrade", "playerUpgradeCrouchRest")); UpgradeNameMappings.Add(new UpgradeNameMapping("Death Head Battery Upgrade", "playerUpgradeDeathHeadBattery")); UpgradeNameMappings.Add(new UpgradeNameMapping("Extra Jump Upgrade", "playerUpgradeExtraJump")); UpgradeNameMappings.Add(new UpgradeNameMapping("Health Upgrade", "playerUpgradeHealth")); UpgradeNameMappings.Add(new UpgradeNameMapping("Tumble Launch Upgrade", "playerUpgradeLaunch")); UpgradeNameMappings.Add(new UpgradeNameMapping("Map Player Count Upgrade", "playerUpgradeMapPlayerCount")); UpgradeNameMappings.Add(new UpgradeNameMapping("Range Upgrade", "playerUpgradeRange")); UpgradeNameMappings.Add(new UpgradeNameMapping("Sprint Speed Upgrade", "playerUpgradeSpeed")); UpgradeNameMappings.Add(new UpgradeNameMapping("Stamina Upgrade", "playerUpgradeStamina")); UpgradeNameMappings.Add(new UpgradeNameMapping("Strength Upgrade", "playerUpgradeStrength")); UpgradeNameMappings.Add(new UpgradeNameMapping("Tumble Climb Upgrade", "playerUpgradeTumbleClimb")); UpgradeNameMappings.Add(new UpgradeNameMapping("Tumble Wings Upgrade", "playerUpgradeTumbleWings")); } public static Dictionary> GetDictionariesWithPrefix(this StatsManager statsManager, string value) { if ((Object)(object)statsManager == (Object)null || string.IsNullOrWhiteSpace(value)) { return new Dictionary>(); } Dictionary> dictionary = new Dictionary>(); foreach (KeyValuePair> dictionaryOfDictionary in statsManager.dictionaryOfDictionaries) { if (dictionaryOfDictionary.Key.StartsWith(value, StringComparison.OrdinalIgnoreCase)) { dictionary.Add(dictionaryOfDictionary.Key, dictionaryOfDictionary.Value); } } return dictionary; } public static Dictionary> GetUpgradeDictionaries(this StatsManager statsManager) { if ((Object)(object)statsManager == (Object)null) { return new Dictionary>(); } return statsManager.GetDictionariesWithPrefix("playerUpgrade"); } public static bool TryGetUpgradeDictionary(this StatsManager statsManager, string dictionaryName, out Dictionary dictionary) { dictionary = null; if ((Object)(object)statsManager == (Object)null || string.IsNullOrWhiteSpace(dictionaryName)) { return false; } foreach (KeyValuePair> upgradeDictionary in statsManager.GetUpgradeDictionaries()) { if (upgradeDictionary.Key.Equals(dictionaryName, StringComparison.OrdinalIgnoreCase)) { 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)) { 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)) { dictionaryName = upgradeNameMapping.DictionaryName; return true; } } return false; } } } namespace com.github.zehsteam.RetrievePlayerUpgrades.Dependencies { internal static class SharedUpgradesProxy { private static readonly List _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(); _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"); _pluginGuids.Add("FluxTeam.SharingIsCaring"); } 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) { } } }