Decompiled source of AutoRestockIL2CPP v1.0.3

Mods\AutoRestockIL2CPP.dll

Decompiled 6 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Threading;
using AutoRestock;
using HarmonyLib;
using Il2CppFishNet;
using Il2CppFishNet.Object;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppScheduleOne;
using Il2CppScheduleOne.DevUtilities;
using Il2CppScheduleOne.EntityFramework;
using Il2CppScheduleOne.GameTime;
using Il2CppScheduleOne.ItemFramework;
using Il2CppScheduleOne.Management;
using Il2CppScheduleOne.Messaging;
using Il2CppScheduleOne.Money;
using Il2CppScheduleOne.NPCs;
using Il2CppScheduleOne.NPCs.Behaviour;
using Il2CppScheduleOne.ObjectScripts;
using Il2CppScheduleOne.Persistence;
using Il2CppScheduleOne.Property;
using Il2CppScheduleOne.StationFramework;
using Il2CppScheduleOne.Storage;
using Il2CppScheduleOne.UI;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using MelonLoader;
using MelonLoader.Preferences;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using UnityEngine;
using UnityEngine.Events;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: MelonInfo(typeof(AutoRestockMod), "AutoRestock", "1.0.3", "lasersquid", null)]
[assembly: MelonGame("TVGS", "Schedule I")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("AutoRestockIL2CPP")]
[assembly: AssemblyConfiguration("IL2CPP")]
[assembly: AssemblyFileVersion("1.0.3.0")]
[assembly: AssemblyInformationalVersion("1.0.3+3f17dd375f908f2e61c644e22b595b83b249bf33")]
[assembly: AssemblyProduct("AutoRestockIL2CPP")]
[assembly: AssemblyTitle("AutoRestockIL2CPP")]
[assembly: NeutralResourcesLanguage("en-US")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.3.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 AutoRestock
{
	public class AutoRestockMod : MelonMod
	{
		public MelonPreferences_Category melonPrefs;

		public Harmony harmony = new Harmony("com.lasersquid.autorestock");

		public override void OnInitializeMelon()
		{
			CreateMelonPreferences();
			SetMod();
			((MelonBase)this).LoggerInstance.Msg("Mod initialized.");
		}

		private void CreateMelonPreferences()
		{
			melonPrefs = MelonPreferences.CreateCategory("AutoRestock");
			melonPrefs.SetFilePath("UserData/AutoRestock.cfg", true, false);
			melonPrefs.CreateEntry<float>("itemDiscount", 0f, "Restock discount", "Discount applied to restock price (0.2 = 20% off)", false, false, (ValueValidator)null, (string)null);
			melonPrefs.CreateEntry<bool>("payWithCash", true, "Pay for restock with cash", "True to pay with cash, false to pay with bank account", false, false, (ValueValidator)null, (string)null);
			melonPrefs.CreateEntry<bool>("useDebt", false, "Enable debt", "Enable restocking even when zero or negative cash/bank balance", false, false, (ValueValidator)null, (string)null);
			melonPrefs.CreateEntry<bool>("enableCauldrons", true, "Enable auto-restock on cauldrons", "Enable auto-restock on cauldrons", false, false, (ValueValidator)null, (string)null);
			melonPrefs.CreateEntry<bool>("enableMixingStations", true, "Enable auto-restock on mixing stations", "Enable auto-restock on mixing stations", false, false, (ValueValidator)null, (string)null);
			melonPrefs.CreateEntry<bool>("enableChemistryStations", true, "Enable auto-restock on chemistry stations", "Enable auto-restock on chemistry stations", false, false, (ValueValidator)null, (string)null);
			melonPrefs.CreateEntry<bool>("enablePackagingStations", true, "Enable auto-restock on packaging stations", "Enable auto-restock on packaging stations", false, false, (ValueValidator)null, (string)null);
			melonPrefs.CreateEntry<bool>("enableStorage", true, "Enable auto-restock on storage (shelves and safes)", "Enable auto-restock on storage (shelves and safes)", false, false, (ValueValidator)null, (string)null);
			melonPrefs.CreateEntry<bool>("playerRestockStations", true, "Enable auto-restock on stations after player-initiated actions (start cauldron, etc)", "Enable auto-restock on stations after player-initiated actions (start cauldron, etc)", false, false, (ValueValidator)null, (string)null);
			melonPrefs.CreateEntry<bool>("verboseLogs", false, "Print to the log for each auto-restock transaction", "Print to the log for each auto-restock transaction", false, false, (ValueValidator)null, (string)null);
			melonPrefs.CreateEntry<bool>("debugLogs", false, "Print debug logs", "Print debug logs", false, false, (ValueValidator)null, (string)null);
			melonPrefs.SaveToFile(false);
		}

		private List<Type> GetPatchTypes()
		{
			return (from t in Assembly.GetExecutingAssembly().GetTypes()
				where t.Name.EndsWith("Patches")
				select t).ToList();
		}

		private void SetMod()
		{
			foreach (Type patchType in GetPatchTypes())
			{
				MethodInfo method = patchType.GetMethod("SetMod", BindingFlags.Static | BindingFlags.Public | BindingFlags.FlattenHierarchy);
				method.Invoke(null, new object[1] { this });
			}
			Utils.SetMod(this);
		}
	}
	public class UnityObjectComparer : IEqualityComparer<Object>
	{
		public bool Equals(Object a, Object b)
		{
			return a.GetInstanceID() == b.GetInstanceID();
		}

		public int GetHashCode(Object item)
		{
			return item.GetInstanceID();
		}
	}
	public class Sched1PatchesBase
	{
		protected static AutoRestockMod Mod;

		public static void SetMod(AutoRestockMod mod)
		{
			Mod = mod;
		}
	}
	public static class Utils
	{
		private static AutoRestockMod Mod;

		public static void SetMod(AutoRestockMod mod)
		{
			Mod = mod;
		}

		public static void PrintException(Exception e)
		{
			Warn("Exception: " + e.GetType().Name + " - " + e.Message);
			Warn("Source: " + e.Source);
			Warn(e.StackTrace ?? "");
			if (e.InnerException != null)
			{
				Warn("Inner exception: " + e.InnerException.GetType().Name + " - " + e.InnerException.Message);
				Warn("Source: " + e.InnerException.Source);
				Warn(e.InnerException.StackTrace ?? "");
				if (e.InnerException.InnerException != null)
				{
					Warn("Inner inner exception: " + e.InnerException.InnerException.GetType().Name + " - " + e.InnerException.InnerException.Message);
					Warn("Source: " + e.InnerException.InnerException.Source);
					Warn(e.InnerException.InnerException.StackTrace ?? "");
				}
			}
		}

		public static void Log(string message)
		{
			((MelonBase)Mod).LoggerInstance.Msg(message);
		}

		public static void Warn(string message)
		{
			((MelonBase)Mod).LoggerInstance.Warning(message);
		}

		public static void Debug(string message)
		{
			if (Manager.isInitialized && Manager.melonPrefs.GetEntry<bool>("debugLogs").Value)
			{
				((MelonBase)Mod).LoggerInstance.Msg("DEBUG: " + message);
			}
		}

		public static void VerboseLog(string message)
		{
			if (Manager.isInitialized && Manager.melonPrefs.GetEntry<bool>("verboseLogs").Value)
			{
				((MelonBase)Mod).LoggerInstance.Msg(message);
			}
		}

		public static object GetField(Type type, string fieldName, object target)
		{
			return AccessTools.Property(type, fieldName).GetValue(target);
		}

		public static void SetField(Type type, string fieldName, object target, object value)
		{
			AccessTools.Property(type, fieldName).SetValue(target, value);
		}

		public static object GetProperty(Type type, string fieldName, object target)
		{
			return AccessTools.Property(type, fieldName).GetValue(target);
		}

		public static void SetProperty(Type type, string fieldName, object target, object value)
		{
			AccessTools.Property(type, fieldName).SetValue(target, value);
		}

		public static object CallMethod(Type type, string methodName, object target, object[] args)
		{
			return AccessTools.Method(type, methodName, (Type[])null, (Type[])null).Invoke(target, args);
		}

		public static T CastTo<T>(object o) where T : class
		{
			if (!(o is T result))
			{
				return null;
			}
			return result;
		}

		public static bool Is<T>(object o)
		{
			return o is T;
		}

		public static T CastTo<T>(Object o) where T : Il2CppObjectBase
		{
			return ((Il2CppObjectBase)o).TryCast<T>();
		}

		public static bool Is<T>(Object o) where T : Il2CppObjectBase
		{
			return ((Il2CppObjectBase)o).TryCast<T>() != null;
		}

		public static UnityAction ToUnityAction(Action action)
		{
			return DelegateSupport.ConvertDelegate<UnityAction>((Delegate)action);
		}

		public static UnityAction<T> ToUnityAction<T>(Action<T> action)
		{
			return DelegateSupport.ConvertDelegate<UnityAction<T>>((Delegate)action);
		}

		public static bool IsQualityIngredient(string itemID)
		{
			List<string> source = new List<string>(1) { "pseudo" };
			return source.Aggregate(seed: false, (bool accum, string name) => accum || itemID.Contains(name));
		}

		public static ItemDefinition GetItemDef(string itemID)
		{
			return Registry.GetItem(itemID);
		}

		public static StorableItemInstance GetItemInstance(string itemID)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Expected O, but got Unknown
			return new StorableItemInstance(Registry.GetItem(itemID), 1);
		}

		public static QualityItemInstance GetItemInstance(string itemID, EQuality quality)
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: 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_008d: Expected O, but got Unknown
			Dictionary<EQuality, string> dictionary = new Dictionary<EQuality, string>
			{
				{
					(EQuality)4,
					"heavenly"
				},
				{
					(EQuality)3,
					"highquality"
				},
				{
					(EQuality)2,
					""
				},
				{
					(EQuality)1,
					"lowquality"
				},
				{
					(EQuality)0,
					"trash"
				}
			};
			if (IsQualityIngredient(itemID))
			{
				string itemID2 = dictionary[quality] + itemID;
				return new QualityItemInstance(GetItemDef(itemID2), 1, quality);
			}
			Warn("itemid " + itemID + " is not a quality ingredient?");
			return null;
		}

		public static bool IsObjectStorageRack(IItemSlotOwner slotOwner)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			string objName = new Object(((Il2CppObjectBase)slotOwner).Pointer).name;
			List<string> source = new List<string>(5) { "Safe", "Small Storage Rack", "Medium Storage Rack", "Large Storage Rack", "StorageRack" };
			return source.Aggregate(seed: false, (bool accum, string name) => accum || objName.Contains(name));
		}

		public static bool IsObjectBuildableItem(IItemSlotOwner slotOwner)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			string objName = new Object(((Il2CppObjectBase)slotOwner).Pointer).name;
			List<string> source = new List<string>(6) { "PackagingStation", "PackagingStationMk2", "Cauldron", "ChemistryStation", "MixingStation", "MixingStationMk2" };
			return source.Aggregate(seed: false, (bool accum, string name) => accum || objName.Contains(name));
		}
	}
	public static class Manager
	{
		public class Transaction
		{
			public string itemID;

			public int quantity;

			public float discount;

			public float unitPrice;

			public float totalCost;

			public string property;

			public bool useCash;

			public SlotIdentifier slotID;

			public Transaction(string itemID, int quantity, float discount, float unitPrice, float totalCost, bool useCash, SlotIdentifier slotID)
			{
				this.itemID = itemID;
				this.quantity = quantity;
				this.discount = discount;
				this.unitPrice = unitPrice;
				this.totalCost = totalCost;
				this.useCash = useCash;
				this.slotID = slotID;
			}
		}

		public class SlotIdentifier
		{
			public List<float> gridLocation;

			public string type;

			public int slotIndex;

			public string property;

			public SlotIdentifier(string property, Vector2 gridLocation, int slotIndex, string type)
			{
				//IL_0018: Unknown result type (might be due to invalid IL or missing references)
				//IL_0021: Unknown result type (might be due to invalid IL or missing references)
				this.property = property;
				this.gridLocation = new List<float>(new <>z__ReadOnlyArray<float>(new float[2] { gridLocation.x, gridLocation.y }));
				this.slotIndex = slotIndex;
				this.type = type;
			}

			[JsonConstructor]
			public SlotIdentifier(string property, List<float> gridLocation, int slotIndex, string type)
			{
				this.property = property;
				this.gridLocation = gridLocation;
				this.slotIndex = slotIndex;
				this.type = type;
			}
		}

		[CompilerGenerated]
		private sealed class <RestockCoroutine>d__27 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public ItemSlot slot;

			public StorableItemInstance item;

			public NetworkObject lockOwner;

			public Transaction transaction;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <RestockCoroutine>d__27(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0033: Unknown result type (might be due to invalid IL or missing references)
				//IL_003d: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					slot.SetIsRemovalLocked(true);
					<>2__current = (object)new WaitForSeconds(1f);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					Utils.VerboseLog($"Restocking {((ItemInstance)item).Name} (${transaction.unitPrice}) x{transaction.quantity} at {transaction.slotID.property}. Total: ${transaction.totalCost}.");
					if (transaction.quantity > 0)
					{
						((ItemInstance)item).SetQuantity(transaction.quantity - slot.Quantity);
						slot.AddItem((ItemInstance)(object)item, false);
					}
					slot.SetIsRemovalLocked(false);
					if (transaction.totalCost <= 0f)
					{
						Utils.VerboseLog("Total cost of transaction is $0. Get a freebie!");
					}
					else if (melonPrefs.GetEntry<bool>("payWithCash").Value)
					{
						moneyManager.ChangeCashBalance(0f - transaction.totalCost, true, false);
					}
					else
					{
						moneyManager.CreateOnlineTransaction("Restock", (0f - transaction.totalCost) / (float)transaction.quantity, (float)transaction.quantity, ((ItemInstance)item).Definition.Name ?? "");
					}
					AcquireMutex();
					coroutines.Remove(transaction);
					ReleaseMutex();
					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();
			}
		}

		public static Dictionary<ItemSlot, NPC> shelfAccessors;

		public static MelonPreferences_Category melonPrefs;

		private static TimeManager timeManager;

		private static MoneyManager moneyManager;

		private static SaveManager saveManager;

		private static string ledgerString;

		private static string transactionString;

		private static List<Transaction> ledger;

		private static Dictionary<Transaction, object> coroutines;

		private static NPC lockOwner;

		private static EDay ledgerDay;

		private static Mutex exclusiveLock;

		public static bool isInitialized;

		public static SlotIdentifier SerializeSlot(ItemSlot slot)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Expected O, but got Unknown
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			GridItem component;
			string name;
			if (Utils.IsObjectBuildableItem(slot.SlotOwner))
			{
				BuildableItem val = new BuildableItem(((Il2CppObjectBase)slot.SlotOwner).Pointer);
				component = ((Component)val).gameObject.GetComponent<GridItem>();
				name = ((Object)val).name;
			}
			else
			{
				if (!Utils.IsObjectStorageRack(slot.SlotOwner))
				{
					Utils.Warn("Couldn't serialize itemslot!");
					return null;
				}
				StorageEntity val2 = new StorageEntity(((Il2CppObjectBase)slot.SlotOwner).Pointer);
				component = (GridItem)(object)((Component)val2).gameObject.GetComponent<PlaceableStorageEntity>();
				name = ((Object)val2).name;
			}
			string name2 = ((Object)((BuildableItem)component).ParentProperty).name;
			return new SlotIdentifier(name2, component.OriginCoordinate, (int)Utils.GetProperty(typeof(ItemSlot), "SlotIndex", slot), name);
		}

		public static string StringToType(string typeString)
		{
			List<string> list = new List<string>(6) { "Cauldron", "ChemistryStation", "MixingStationMk2", "MixingStation", "PackagingStationMk2", "PackagingStation" };
			string text = list.Find((string s) => typeString.Contains(s));
			if (text != null && text.Length > 0)
			{
				return text;
			}
			List<string> source = new List<string>(2) { "StorageRack", "Safe" };
			if (source.Aggregate(seed: false, (bool accum, string s) => accum || typeString.Contains(s)))
			{
				return "StorageEntity";
			}
			return null;
		}

		public static ItemSlot DeserializeSlot(SlotIdentifier identifier)
		{
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				List<Property> source = ((IEnumerable<Property>)Object.FindObjectsOfType<Property>()).ToList();
				List<GridItem> list = ((IEnumerable<GridItem>)Object.FindObjectsOfType<GridItem>()).ToList();
				Property property = ((IEnumerable<Property>)source).FirstOrDefault((Func<Property, bool>)((Property p) => ((Object)p).name == identifier.property));
				List<GridItem> source2 = list.FindAll((GridItem g) => (Object)(object)((BuildableItem)g).ParentProperty == (Object)(object)property);
				GridItem val = source2.Single((GridItem g) => g.OriginCoordinate == new Vector2(identifier.gridLocation[0], identifier.gridLocation[1]));
				Component componentByName = ((Component)val).gameObject.GetComponentByName(StringToType(identifier.type));
				return new IItemSlotOwner(((Il2CppObjectBase)componentByName).Pointer).ItemSlots[identifier.slotIndex];
			}
			catch (Exception e)
			{
				Utils.PrintException(e);
			}
			return null;
		}

		public static void CompleteTransactions(List<Transaction> transactions)
		{
			try
			{
				foreach (Transaction transaction in transactions)
				{
					ItemSlot val = DeserializeSlot(transaction.slotID);
					if (val == null)
					{
						Utils.Warn("Couldn't deserialize slot!");
						continue;
					}
					StorableItemInstance itemInstance = Utils.GetItemInstance(transaction.itemID);
					TryRestocking(val, itemInstance, transaction.quantity);
				}
			}
			catch (Exception e)
			{
				Utils.PrintException(e);
			}
		}

		public static void Initialize()
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				melonPrefs = MelonPreferences.GetCategory("AutoRestock");
				timeManager = NetworkSingleton<TimeManager>.Instance;
				moneyManager = NetworkSingleton<MoneyManager>.Instance;
				saveManager = Singleton<SaveManager>.Instance;
				ledgerDay = timeManager.CurrentDay;
				shelfAccessors = new Dictionary<ItemSlot, NPC>();
				coroutines = new Dictionary<Transaction, object>();
				lockOwner = ((IEnumerable<NPC>)Object.FindObjectsOfType<NPC>()).FirstOrDefault((Func<NPC, bool>)((NPC npc) => npc.ID == "oscar_holland"));
				exclusiveLock = new Mutex();
				TimeManager obj = timeManager;
				obj.onDayPass += Action.op_Implicit((Action)OnDayPass);
				saveManager.onSaveStart.AddListener(Utils.ToUnityAction(OnSaveStart));
				ledgerString = GetSaveString() + "_ledger";
				transactionString = GetSaveString() + "_inprogress";
				if (!melonPrefs.HasEntry(ledgerString))
				{
					melonPrefs.CreateEntry<string>(ledgerString, "[]", "", true);
				}
				if (!melonPrefs.HasEntry(transactionString))
				{
					melonPrefs.CreateEntry<string>(transactionString, "[]", "", true);
				}
				melonPrefs.LoadFromFile(false);
				ledger = JsonConvert.DeserializeObject<List<Transaction>>(melonPrefs.GetEntry<string>(ledgerString).Value);
				isInitialized = true;
				Utils.Log("AutoRestock manager initialized.");
			}
			catch (Exception e)
			{
				Utils.PrintException(e);
			}
			try
			{
				List<Transaction> list = JsonConvert.DeserializeObject<List<Transaction>>(melonPrefs.GetEntry<string>(transactionString).Value);
				if (list.Count > 0)
				{
					Utils.Log($"Completing {list.Count} pending transaction{((list.Count > 1) ? "s" : "")}.");
					CompleteTransactions(list);
				}
			}
			catch (Exception e2)
			{
				Utils.PrintException(e2);
			}
		}

		public static void Stop()
		{
			if (isInitialized)
			{
				isInitialized = false;
				ledger.Clear();
				StopCoroutines();
				lockOwner = null;
				exclusiveLock.Dispose();
			}
		}

		public static void StopCoroutines()
		{
			if (!isInitialized)
			{
				return;
			}
			foreach (KeyValuePair<Transaction, object> coroutine in coroutines)
			{
				MelonCoroutines.Stop(coroutine.Value);
			}
			coroutines.Clear();
		}

		public static void AcquireMutex()
		{
			if (isInitialized)
			{
				exclusiveLock.WaitOne();
			}
		}

		public static void ReleaseMutex()
		{
			if (isInitialized)
			{
				exclusiveLock.ReleaseMutex();
			}
		}

		public static bool ItemIsRestockable(string itemID)
		{
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			if (isInitialized)
			{
				List<string> list = new List<string>(4) { "Agriculture", "Consumable", "Ingredient", "Packaging" };
				List<string> list2 = new List<string>(1) { "speedgrow" };
				List<string> list3 = new List<string>(3) { "cocaleaf", "cocainebase", "liquidmeth" };
				List<string> list4 = new List<string>(5) { "cocaseed", "granddaddypurpleseed", "greencrackseed", "ogkushseed", "sourdieselseed" };
				ItemDefinition itemDef = Utils.GetItemDef(itemID);
				EItemCategory category = itemDef.Category;
				return (list.Contains(((object)(EItemCategory)(ref category)).ToString()) || list2.Contains(itemDef.ID)) && !list3.Contains(itemDef.ID);
			}
			return false;
		}

		public static void TryRestocking(ItemSlot slot, StorableItemInstance item, int quantity)
		{
			if (isInitialized && InstanceFinder.IsServer)
			{
				string iD = ((ItemInstance)item).ID;
				float num = Mathf.Clamp(melonPrefs.GetEntry<float>("itemDiscount").Value, 0f, 1f);
				float num2 = ((ItemInstance)item).GetMonetaryValue() * 2f / (float)((ItemInstance)item).Quantity;
				float num3 = num2 * (float)quantity * (1f - num);
				bool value = melonPrefs.GetEntry<bool>("payWithCash").Value;
				bool value2 = melonPrefs.GetEntry<bool>("useDebt").Value;
				SlotIdentifier slotIdentifier = SerializeSlot(slot);
				try
				{
					if (((ItemInstance)item).StackLimit == 0)
					{
						Utils.Debug($"Stacklimit ({((ItemInstance)item).StackLimit}) == 0. Not restocking.");
						((ItemInstance)item).RequestClearSlot();
					}
					else if (ItemIsRestockable(((ItemInstance)item).ID))
					{
						float num4 = (value ? moneyManager.cashBalance : moneyManager.onlineBalance);
						if (num4 < num3 && !value2)
						{
							Utils.Log($"Can't afford to restock {quantity}x {iD} (${num3}).");
						}
						else if (num4 >= num3)
						{
							AcquireMutex();
							Transaction transaction = new Transaction(iD, quantity, num, num2, num3, value, slotIdentifier);
							ledger.Add(transaction);
							Utils.Debug($"Starting restock coroutine ({iD} x{quantity} at {slotIdentifier.property}).");
							coroutines[transaction] = MelonCoroutines.Start(RestockCoroutine(slot, item, ((NetworkBehaviour)lockOwner).NetworkObject, transaction));
							ReleaseMutex();
						}
					}
					return;
				}
				catch (Exception e)
				{
					Utils.PrintException(e);
					ReleaseMutex();
					((ItemInstance)item).RequestClearSlot();
					return;
				}
			}
			Utils.Log("Tried to restock item, but Manager was not initialized!");
		}

		public static bool OwnedByNPC(ItemSlot slot)
		{
			//IL_0019: 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_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			if (isInitialized)
			{
				string name = new Object(((Il2CppObjectBase)slot.SlotOwner).Pointer).name;
				if (name.Contains("Cauldron"))
				{
					return (Object)(object)new Cauldron(((Il2CppObjectBase)slot.SlotOwner).Pointer).NPCUserObject != (Object)null;
				}
				if (name.Contains("MixingStation") || name.Contains("MixingStationMk2"))
				{
					return (Object)(object)new MixingStation(((Il2CppObjectBase)slot.SlotOwner).Pointer).NPCUserObject != (Object)null;
				}
				if (name.Contains("PackagingStation") || name.Contains("PackagingStationMk2"))
				{
					return (Object)(object)new PackagingStation(((Il2CppObjectBase)slot.SlotOwner).Pointer).NPCUserObject != (Object)null;
				}
				if (name.Contains("ChemistryStation"))
				{
					return (Object)(object)new ChemistryStation(((Il2CppObjectBase)slot.SlotOwner).Pointer).NPCUserObject != (Object)null;
				}
				if (name.Contains("StorageEntity"))
				{
					return slot.IsLocked || slot.IsAddLocked || slot.IsRemovalLocked;
				}
				return false;
			}
			return false;
		}

		[IteratorStateMachine(typeof(<RestockCoroutine>d__27))]
		private static IEnumerator RestockCoroutine(ItemSlot slot, StorableItemInstance item, NetworkObject lockOwner, Transaction transaction)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <RestockCoroutine>d__27(0)
			{
				slot = slot,
				item = item,
				lockOwner = lockOwner,
				transaction = transaction
			};
		}

		private static void OnDayPass()
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Expected O, but got Unknown
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			if (isInitialized && InstanceFinder.IsServer)
			{
				NetworkSingleton<MessagingManager>.Instance.SendMessage(new Message(GetReceipt(), (ESenderType)1, true, -1), true, "oscar_holland");
				ledger.Clear();
				ledgerDay = timeManager.CurrentDay;
			}
		}

		private static string GetSaveString()
		{
			string[] array = Singleton<LoadManager>.Instance.LoadedGameFolderPath.Split('\\');
			return array[^2] + "_" + array[^1];
		}

		public static void OnSaveStart()
		{
			if (isInitialized && InstanceFinder.IsServer)
			{
				string text = GetSaveString() + "_ledger";
				if (melonPrefs.HasEntry(text))
				{
					melonPrefs.GetEntry<string>(text).EditedValue = LedgerToJson();
				}
				else
				{
					MelonPreferences_Entry val = melonPrefs.CreateEntry<string>(text, "", "", true);
					val.BoxedEditedValue = LedgerToJson();
				}
				string text2 = GetSaveString() + "_inprogress";
				if (melonPrefs.HasEntry(text2))
				{
					melonPrefs.GetEntry<string>(text2).EditedValue = PendingTransactionsToJson();
				}
				else
				{
					MelonPreferences_Entry val2 = melonPrefs.CreateEntry<string>(text2, "", "", true);
					val2.BoxedEditedValue = PendingTransactionsToJson();
				}
				melonPrefs.SaveToFile(false);
			}
		}

		public static List<Transaction> GetPendingTransactions()
		{
			return coroutines.Keys.ToList();
		}

		public static string PendingTransactionsToJson()
		{
			return JsonConvert.SerializeObject((object)GetPendingTransactions());
		}

		public static float LedgerTotal()
		{
			return ledger.Aggregate(0f, (float accum, Transaction transaction) => accum + transaction.totalCost);
		}

		public static string LedgerToJson()
		{
			return JsonConvert.SerializeObject((object)ledger);
		}

		private static string GetReceipt()
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			if (isInitialized)
			{
				string text = $"Restock receipt for {ledgerDay}:\n\n";
				float num = 0f;
				if (ledger.Count > 0)
				{
					Dictionary<string, Dictionary<string, int>> dictionary = new Dictionary<string, Dictionary<string, int>>();
					Dictionary<string, float> dictionary2 = new Dictionary<string, float>();
					foreach (Transaction item in ledger)
					{
						if (!dictionary.ContainsKey(item.slotID.property))
						{
							dictionary[item.slotID.property] = new Dictionary<string, int>();
						}
						if (!dictionary[item.slotID.property].ContainsKey(item.itemID))
						{
							dictionary[item.slotID.property][item.itemID] = 0;
						}
						dictionary[item.slotID.property][item.itemID] += item.quantity;
						dictionary2[item.itemID] = item.unitPrice;
					}
					foreach (string key in dictionary.Keys)
					{
						float num2 = 0f;
						text = text + key + ": \n";
						foreach (KeyValuePair<string, int> item2 in dictionary[key])
						{
							string name = Utils.GetItemDef(item2.Key).Name;
							text += $"  {name} x{item2.Value} = ${dictionary2[item2.Key] * (float)item2.Value}\n";
							num2 += dictionary2[item2.Key] * (float)item2.Value;
						}
						text += "=====================\n";
						text += $"  Property total: ${num2}\n\n";
						num += num2;
					}
				}
				text += "=====================\n";
				text += $"  Grand total: ${num}\n\n";
				return text + "Oscar says thank you for your business! :)";
			}
			return "AutoRestock not initialized!";
		}
	}
	[HarmonyPatch]
	public class PersistencePatches : Sched1PatchesBase
	{
		[HarmonyPatch(typeof(LoadingScreen), "Close")]
		[HarmonyPostfix]
		public static void ClosePostfix(LoadingScreen __instance)
		{
			if (InstanceFinder.IsServer && !Manager.isInitialized)
			{
				Manager.Initialize();
			}
		}

		[HarmonyPatch(typeof(LoadManager), "ExitToMenu")]
		[HarmonyPrefix]
		public static void ExitToMenuPrefix(LoadManager __instance)
		{
			if (InstanceFinder.IsServer && Manager.isInitialized)
			{
				Manager.Stop();
			}
		}
	}
	[HarmonyPatch]
	public class CauldronPatches : Sched1PatchesBase
	{
		[HarmonyPatch(typeof(Cauldron), "RemoveIngredients")]
		[HarmonyPrefix]
		public static bool RemoveIngredientsPrefix(Cauldron __instance)
		{
			if (!InstanceFinder.IsServer || !Manager.isInitialized)
			{
				return true;
			}
			try
			{
				if (!Manager.melonPrefs.GetEntry<bool>("enableCauldrons").Value)
				{
					return true;
				}
				if (__instance.LiquidSlot.ItemInstance.Quantity > 1)
				{
					return true;
				}
				if (Manager.melonPrefs.GetEntry<bool>("playerRestockStations").Value || (Object)(object)__instance.PlayerUserObject == (Object)null)
				{
					StorableItemInstance val = Utils.CastTo<StorableItemInstance>((Object)(object)__instance.LiquidSlot.ItemInstance.GetCopy(1));
					Manager.TryRestocking(__instance.LiquidSlot, val, ((ItemInstance)val).StackLimit);
				}
			}
			catch (Exception e)
			{
				Utils.Warn(MethodBase.GetCurrentMethod().DeclaringType.Name + ":");
				Utils.PrintException(e);
			}
			return true;
		}
	}
	[HarmonyPatch]
	public class MixingStationPatches : Sched1PatchesBase
	{
		[HarmonyPatch(typeof(MixingStation), "SendMixingOperation")]
		[HarmonyPrefix]
		public static bool SendMixingOperationPrefix(MixingStation __instance, MixOperation operation)
		{
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			if (!InstanceFinder.IsServer || !Manager.isInitialized)
			{
				return true;
			}
			try
			{
				if (!Manager.melonPrefs.GetEntry<bool>("enableMixingStations").Value)
				{
					return true;
				}
				if ((float)(__instance.MixerSlot.Quantity - operation.Quantity) >= ((MixingStationConfiguration)Utils.GetProperty(typeof(MixingStation), "stationConfiguration", __instance)).StartThrehold.GetData().Value)
				{
					return true;
				}
				if (Manager.melonPrefs.GetEntry<bool>("playerRestockStations").Value || (Object)(object)__instance.PlayerUserObject == (Object)null)
				{
					StorableItemInstance itemInstance = Utils.GetItemInstance(operation.IngredientID);
					Manager.TryRestocking(__instance.MixerSlot, itemInstance, ((ItemInstance)itemInstance).StackLimit);
				}
			}
			catch (Exception e)
			{
				Utils.Warn(MethodBase.GetCurrentMethod().DeclaringType.Name + ":");
				Utils.PrintException(e);
			}
			return true;
		}
	}
	[HarmonyPatch]
	public class PackagingStationPatches : Sched1PatchesBase
	{
		[HarmonyPatch(typeof(PackagingStation), "PackSingleInstance")]
		[HarmonyPrefix]
		public static bool PackSingleInstancePrefix(PackagingStation __instance)
		{
			if (!InstanceFinder.IsServer || !Manager.isInitialized)
			{
				return true;
			}
			try
			{
				if (!Manager.melonPrefs.GetEntry<bool>("enablePackagingStations").Value)
				{
					return true;
				}
				if (__instance.PackagingSlot.ItemInstance == null || __instance.PackagingSlot.ItemInstance.Quantity > 1)
				{
					return true;
				}
				if (Manager.melonPrefs.GetEntry<bool>("playerRestockStations").Value || (Object)(object)__instance.PlayerUserObject == (Object)null)
				{
					StorableItemInstance val = Utils.CastTo<StorableItemInstance>((Object)(object)__instance.PackagingSlot.ItemInstance.GetCopy(1));
					Manager.TryRestocking(__instance.PackagingSlot, val, ((ItemInstance)val).StackLimit);
				}
			}
			catch (Exception e)
			{
				Utils.Warn(MethodBase.GetCurrentMethod().DeclaringType.Name + ":");
				Utils.PrintException(e);
			}
			return true;
		}
	}
	[HarmonyPatch]
	public class ChemistryStationPatches : Sched1PatchesBase
	{
		private static List<List<T>> Permute<T>(List<T> nums)
		{
			List<List<T>> list = new List<List<T>>();
			return DoPermute(nums, 0, nums.Count - 1, list);
		}

		private static List<List<T>> DoPermute<T>(List<T> nums, int start, int end, List<List<T>> list)
		{
			if (start == end)
			{
				list.Add(new List<T>(nums));
			}
			else
			{
				for (int i = start; i <= end; i++)
				{
					Swap(nums, start, i);
					DoPermute(nums, start + 1, end, list);
					Swap(nums, start, i);
				}
			}
			return list;
		}

		private static void Swap<T>(List<T> list, int index1, int index2)
		{
			T value = list[index1];
			list[index1] = list[index2];
			list[index2] = value;
		}

		[HarmonyPatch(typeof(ChemistryStation), "SendCookOperation")]
		[HarmonyPrefix]
		public static bool SendCookOperationPrefix(ChemistryStation __instance, ChemistryCookOperation op)
		{
			//IL_02af: Unknown result type (might be due to invalid IL or missing references)
			if (!InstanceFinder.IsServer || !Manager.isInitialized)
			{
				return true;
			}
			try
			{
				if (!Manager.melonPrefs.GetEntry<bool>("enableChemistryStations").Value)
				{
					return true;
				}
				if (Manager.melonPrefs.GetEntry<bool>("playerRestockStations").Value || (Object)(object)__instance.PlayerUserObject == (Object)null)
				{
					List<ItemDefinition> list2 = new List<ItemDefinition>();
					Enumerator<IngredientQuantity> enumerator = op.Recipe.Ingredients.GetEnumerator();
					while (enumerator.MoveNext())
					{
						IngredientQuantity current = enumerator.Current;
						bool flag = false;
						foreach (ItemSlot item in (Il2CppArrayBase<ItemSlot>)(object)__instance.IngredientSlots)
						{
							if (item.ItemInstance != null && item.ItemInstance.Definition.Name.Contains(current.Item.Name))
							{
								flag = true;
								break;
							}
						}
						if (!flag)
						{
							list2.Add(current.Item);
						}
					}
					List<List<ItemDefinition>> list3 = new List<List<ItemDefinition>>();
					List<List<ItemDefinition>> list4 = new List<List<ItemDefinition>>();
					if (list2.Count > 0)
					{
						List<ItemSlot> emptySlots = new List<ItemSlot>();
						foreach (ItemSlot item2 in (Il2CppArrayBase<ItemSlot>)(object)__instance.IngredientSlots)
						{
							if (item2.Quantity == 0)
							{
								emptySlots.Add(item2);
							}
						}
						list3 = Permute(list2);
						list4 = list3.Select(delegate(List<ItemDefinition> mapping)
						{
							//IL_0035: Unknown result type (might be due to invalid IL or missing references)
							bool flag2 = true;
							for (int i = 0; i < mapping.Count; i++)
							{
								ItemInstance val3 = (ItemInstance)((!Utils.IsQualityIngredient(mapping[i].ID)) ? ((object)Utils.GetItemInstance(mapping[i].ID)) : ((object)Utils.GetItemInstance(mapping[i].ID, op.ProductQuality)));
								if (!emptySlots[i].DoesItemMatchPlayerFilters(val3))
								{
									flag2 = false;
									break;
								}
							}
							return flag2 ? mapping : null;
						}).ToList();
						list4.RemoveAll((List<ItemDefinition> list) => list == null);
						if (list4.Count == 0)
						{
							Utils.Log("Couldn't restock chemistry station because items do not agree with filters.");
						}
					}
					int num = 0;
					foreach (ItemSlot item3 in (Il2CppArrayBase<ItemSlot>)(object)__instance.IngredientSlots)
					{
						if (item3.ItemInstance == null && list2.Count > 0)
						{
							ItemDefinition val = list4[0][num];
							if (Utils.IsQualityIngredient(val.ID))
							{
								QualityItemInstance itemInstance = Utils.GetItemInstance(val.ID, op.ProductQuality);
								Manager.TryRestocking(item3, (StorableItemInstance)(object)itemInstance, ((ItemInstance)itemInstance).StackLimit);
							}
							else
							{
								StorableItemInstance itemInstance2 = Utils.GetItemInstance(val.ID);
								Manager.TryRestocking(item3, itemInstance2, ((ItemInstance)itemInstance2).StackLimit);
							}
							num++;
							continue;
						}
						int num2 = 0;
						Enumerator<IngredientQuantity> enumerator5 = op.Recipe.Ingredients.GetEnumerator();
						while (enumerator5.MoveNext())
						{
							IngredientQuantity current5 = enumerator5.Current;
							if (item3.ItemInstance.Definition.Name.Contains(current5.Item.Name))
							{
								num2 = current5.Quantity;
								break;
							}
						}
						if (num2 > 0 && item3.ItemInstance.Quantity < num2)
						{
							StorableItemInstance val2 = Utils.CastTo<StorableItemInstance>((Object)(object)item3.ItemInstance.GetCopy(1));
							Manager.TryRestocking(item3, val2, ((ItemInstance)val2).StackLimit);
						}
					}
				}
			}
			catch (Exception e)
			{
				Utils.Warn(MethodBase.GetCurrentMethod().DeclaringType.Name + ":");
				Utils.PrintException(e);
			}
			return true;
		}
	}
	[HarmonyPatch]
	public class StorageEntityPatches : Sched1PatchesBase
	{
		[HarmonyPatch(typeof(MoveItemBehaviour), "TakeItem")]
		[HarmonyPrefix]
		public static void TakeItemPrefix(MoveItemBehaviour __instance)
		{
			if (!InstanceFinder.IsServer || !Manager.isInitialized)
			{
				return;
			}
			try
			{
				if ((int)Utils.CallMethod(typeof(MoveItemBehaviour), "GetAmountToGrab", __instance, Array.Empty<object>()) > 0)
				{
					TransitRoute val = Utils.CastTo<TransitRoute>(Utils.GetField(typeof(MoveItemBehaviour), "assignedRoute", __instance));
					ItemInstance val2 = Utils.CastTo<ItemInstance>(Utils.GetField(typeof(MoveItemBehaviour), "itemToRetrieveTemplate", __instance));
					ItemSlot firstSlotContainingTemplateItem = val.Source.GetFirstSlotContainingTemplateItem(val2, (ESlotType)2);
					if (firstSlotContainingTemplateItem.SlotOwner != null && Utils.IsObjectStorageRack(firstSlotContainingTemplateItem.SlotOwner) && !Manager.shelfAccessors.TryAdd(firstSlotContainingTemplateItem, ((Behaviour)__instance).Npc))
					{
						Utils.Warn("ItemSlot is already in list of shelfAccessors?");
					}
				}
			}
			catch (Exception e)
			{
				Utils.PrintException(e);
			}
		}

		[HarmonyPatch(typeof(MoveItemBehaviour), "TakeItem")]
		[HarmonyPostfix]
		public static void TakeItemPostfix(MoveItemBehaviour __instance)
		{
			if (!InstanceFinder.IsServer || !Manager.isInitialized)
			{
				return;
			}
			try
			{
				TransitRoute val = Utils.CastTo<TransitRoute>(Utils.GetField(typeof(MoveItemBehaviour), "assignedRoute", __instance));
				ItemInstance val2 = Utils.CastTo<ItemInstance>(Utils.GetField(typeof(MoveItemBehaviour), "itemToRetrieveTemplate", __instance));
				ItemSlot firstSlotContainingTemplateItem = val.Source.GetFirstSlotContainingTemplateItem(val2, (ESlotType)2);
				if (firstSlotContainingTemplateItem != null)
				{
					Manager.shelfAccessors.Remove(firstSlotContainingTemplateItem);
				}
			}
			catch (Exception e)
			{
				Utils.PrintException(e);
			}
		}

		[HarmonyPatch(typeof(StorageEntity), "SetStoredInstance")]
		[HarmonyPrefix]
		public static void SetStoredInstancePrefix(StorageEntity __instance, int itemSlotIndex, ItemInstance instance)
		{
			if (!InstanceFinder.IsServer || !Manager.isInitialized)
			{
				return;
			}
			try
			{
				if (Manager.melonPrefs.GetEntry<bool>("enableStorage").Value && instance == null && IsStorageRack(__instance))
				{
					ItemSlot val = __instance.ItemSlots.ToArray()[itemSlotIndex];
					if (val.ItemInstance != null && (!((Object)(object)__instance.CurrentPlayerAccessor != (Object)null) || Manager.shelfAccessors.ContainsKey(val)))
					{
						StorableItemInstance val2 = Utils.CastTo<StorableItemInstance>((Object)(object)val.ItemInstance.GetCopy(1));
						Manager.TryRestocking(val, val2, ((ItemInstance)val2).StackLimit);
					}
				}
			}
			catch (Exception e)
			{
				Utils.Warn(MethodBase.GetCurrentMethod().DeclaringType.Name + ":");
				Utils.PrintException(e);
			}
		}

		private static bool IsStorageRack(StorageEntity item)
		{
			if (item.StorageEntityName == "Safe" || item.StorageEntityName == "Large Storage Rack" || item.StorageEntityName == "Medium Storage Rack" || item.StorageEntityName == "Small Storage Rack")
			{
				return true;
			}
			return false;
		}
	}
}
[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();
	}
}