Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of RetrievePlayerUpgrades v1.1.0
com.github.zehsteam.RetrievePlayerUpgrades.dll
Decompiled 5 months agousing 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; 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.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("Zehs")] [assembly: AssemblyConfiguration("Release")] [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.1.0.0")] [assembly: AssemblyInformationalVersion("1.1.0+0a3fb1d357c5fc9d0ca5cbb212872fb6de6685b2")] [assembly: AssemblyProduct("RetrievePlayerUpgrades")] [assembly: AssemblyTitle("com.github.zehsteam.RetrievePlayerUpgrades")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.1.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 Initialize() { string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); string text = "retrieveplayerupgrades_assets"; string text2 = Path.Combine(directoryName, text); if (!File.Exists(text2)) { Logger.LogFatal("Failed to initialize assets. AssetBundle file could not be found at path \"" + text2 + "\". Make sure the \"" + text + "\" file is in the same folder as the mod's DLL file."); } else { BundleLoader.LoadBundle(text2, (Action<AssetBundle>)HandleAssetBundleLoaded, false); } } private static void HandleAssetBundleLoaded(AssetBundle assetBundle) { ItemVolumeSetCollectionPrefab = LoadAsset<GameObject>("ItemVolumeSetCollection", assetBundle); } private static T LoadAsset<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; } private static bool TryLoadAsset<T>(string name, AssetBundle assetBundle, out T asset) where T : Object { asset = LoadAsset<T>(name, assetBundle); return (Object)(object)asset != (Object)null; } } 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 LogDebug(object data) { Log((LogLevel)32, data); } 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 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); } } } public static bool IsExtendedLoggingEnabled() { if (ConfigManager.ExtendedLogging == null) { return false; } return ConfigManager.ExtendedLogging.Value; } } [BepInPlugin("com.github.zehsteam.RetrievePlayerUpgrades", "RetrievePlayerUpgrades", "1.1.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.Initialize(); 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.1.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() { 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<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 { [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<ItemUpgradeAddon> Instances { get; private set; } = new List<ItemUpgradeAddon>(); 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<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(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<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_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<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_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<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; 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() { <>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>(); 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 <SpawnUpgradesCoroutine>d__1 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public Action<string> onFailure; public List<ItemStack> itemStacks; public Action onSuccess; private GameObject <collectionObject>5__2; private ItemVolumeSet[] <itemVolumeSets>5__3; private int <i>5__4; 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() { <collectionObject>5__2 = null; <itemVolumeSets>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; <i>5__4++; break; } IL_00b9: if (!TryGetTruckMeshTransform(out transform)) { 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(transform); <collectionObject>5__2.transform.SetLocalPositionAndRotation(Vector3.zero, Quaternion.identity); if (!<collectionObject>5__2.TryGetComponent<ItemVolumeSetCollection>(ref itemVolumeSetCollection)) { Object.Destroy((Object)(object)<collectionObject>5__2); onFailure?.Invoke("ItemVolumeSetCollection is null."); return false; } <itemVolumeSets>5__3 = itemVolumeSetCollection.itemVolumeSets; <i>5__4 = 0; break; } if (<i>5__4 < itemStacks.Count) { ItemVolumeSet itemVolumeSet = null; if (<i>5__4 < <itemVolumeSets>5__3.Length) { itemVolumeSet = <itemVolumeSets>5__3[<i>5__4]; } ItemStack itemStack = itemStacks[<i>5__4]; <>2__current = SpawnUpgradesCoroutine(itemVolumeSet, itemStack); <>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 ItemStack itemStack; public ItemVolumeSet itemVolumeSet; private ItemVolume[] <itemVolumes>5__2; private int <index>5__3; private Dictionary<string, int>.Enumerator <>7__wrap3; private KeyValuePair<string, int> <ownerSteamId>5__5; private int <i>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__2 = null; <>7__wrap3 = default(Dictionary<string, int>.Enumerator); <ownerSteamId>5__5 = default(KeyValuePair<string, int>); <>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; } <itemVolumes>5__2 = Array.Empty<ItemVolume>(); if ((Object)(object)itemVolumeSet != (Object)null) { <itemVolumes>5__2 = itemVolumeSet.itemVolumes; } <index>5__3 = 0; <>7__wrap3 = itemStack.OwnerSteamIds.GetEnumerator(); <>1__state = -3; goto IL_0143; case 1: <>1__state = -3; <index>5__3++; <i>5__6++; goto IL_0121; case 2: { <>1__state = -1; return false; } IL_0121: if (<i>5__6 < <ownerSteamId>5__5.Value) { ItemVolume itemVolume = null; if (<index>5__3 < <itemVolumes>5__2.Length) { itemVolume = <itemVolumes>5__2[<index>5__3]; } <>2__current = SpawnUpgradeCoroutine(itemVolume, itemStack.Item, <ownerSteamId>5__5.Key); <>1__state = 1; return true; } <ownerSteamId>5__5 = default(KeyValuePair<string, int>); goto IL_0143; IL_0143: if (<>7__wrap3.MoveNext()) { <ownerSteamId>5__5 = <>7__wrap3.Current; <i>5__6 = 0; goto IL_0121; } <>m__Finally1(); <>7__wrap3 = 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)<>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(<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)) ? int.MaxValue : value); } } internal static class StatsManagerExtensions { public static List<UpgradeNameMapping> UpgradeNameMappings { get; private set; } static StatsManagerExtensions() { UpgradeNameMappings = new List<UpgradeNameMapping>(); UpgradeNameMappings.Add(new UpgradeNameMapping("Death Head Battery Upgrade", "playerUpgradeDeathHeadBattery")); UpgradeNameMappings.Add(new UpgradeNameMapping("Map Player Count Upgrade", "playerUpgradeMapPlayerCount")); UpgradeNameMappings.Add(new UpgradeNameMapping("Crouch Rest Upgrade", "playerUpgradeCrouchRest")); UpgradeNameMappings.Add(new UpgradeNameMapping("Stamina Upgrade", "playerUpgradeStamina")); UpgradeNameMappings.Add(new UpgradeNameMapping("Extra Jump Upgrade", "playerUpgradeExtraJump")); UpgradeNameMappings.Add(new UpgradeNameMapping("Range Upgrade", "playerUpgradeRange")); UpgradeNameMappings.Add(new UpgradeNameMapping("Strength Upgrade", "playerUpgradeStrength")); UpgradeNameMappings.Add(new UpgradeNameMapping("Health Upgrade", "playerUpgradeHealth")); UpgradeNameMappings.Add(new UpgradeNameMapping("Sprint Speed Upgrade", "playerUpgradeSpeed")); UpgradeNameMappings.Add(new UpgradeNameMapping("Tumble Climb Upgrade", "playerUpgradeTumbleClimb")); UpgradeNameMappings.Add(new UpgradeNameMapping("Tumble Launch Upgrade", "playerUpgradeLaunch")); UpgradeNameMappings.Add(new UpgradeNameMapping("Tumble Wings Upgrade", "playerUpgradeTumbleWings")); } 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)) { 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 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"); _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) { } } } [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(); } }