Decompiled source of RetrievePlayerUpgrades v1.0.0

com.github.zehsteam.RetrievePlayerUpgrades.dll

Decompiled a week ago
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();
	}
}