Decompiled source of InventoryRepair Sunkenland v1.0.3

InventoryRepair_Sunkenland.dll

Decompiled 2 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
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 HarmonyLib;
using ItemManager;
using JetBrains.Annotations;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Localization;
using UnityEngine.Localization.Settings;
using UnityEngine.Localization.Tables;
using UnityEngine.Networking;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("InventoryRepair_Sunkenland")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Azumatt")]
[assembly: AssemblyProduct("InventoryRepair_Sunkenland")]
[assembly: AssemblyCopyright("Copyright ©  2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("3DC357FF-84FD-4BB0-89C7-FA6059583C24")]
[assembly: AssemblyFileVersion("1.0.3")]
[assembly: TargetFramework(".NETFramework,Version=v4.8.1", FrameworkDisplayName = ".NET Framework 4.8.1")]
[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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[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 InventoryRepair_Sunkenland
{
	[BepInPlugin("Azumatt.InventoryRepair_Sunkenland", "InventoryRepair_Sunkenland", "1.0.3")]
	public class InventoryRepair_SunkenlandPlugin : BaseUnityPlugin
	{
		public enum Toggle
		{
			Off,
			On
		}

		private class ConfigurationManagerAttributes
		{
			[UsedImplicitly]
			public int? Order;

			[UsedImplicitly]
			public bool? Browsable;

			[UsedImplicitly]
			public string? Category;

			[UsedImplicitly]
			public Action<ConfigEntryBase>? CustomDrawer;
		}

		internal const string ModName = "InventoryRepair_Sunkenland";

		internal const string ModVersion = "1.0.3";

		internal const string Author = "Azumatt";

		private const string ModGUID = "Azumatt.InventoryRepair_Sunkenland";

		private static string ConfigFileName = "Azumatt.InventoryRepair_Sunkenland.cfg";

		private static string ConfigFileFullPath;

		private readonly Harmony _harmony = new Harmony("Azumatt.InventoryRepair_Sunkenland");

		public static readonly ManualLogSource InventoryRepair_SunkenlandLogger;

		private static ConfigEntry<KeyboardShortcut> hotkey;

		private void Awake()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			hotkey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("1 - General", "Hotkey", new KeyboardShortcut((KeyCode)290, Array.Empty<KeyCode>()), "If pressed, everything in your inventory will be repaired.");
			new CustomItem("RepairMe", "Azu's Cool Shit", "C2_Reparing Hammer")
			{
				Level = 4,
				Rare = true,
				CraftAmount = 1,
				Stack = 1,
				CanBeSold = false,
				Condition = 130f,
				MaxCondition = 130f,
				EquipmentSlotType = (EquipmentSlotType)8,
				Icon = "https://cdn3d.iconscout.com/3d/premium/thumb/repair-6819914-5604678.png"
			};
			_harmony.PatchAll();
			SetupWatcher();
		}

		private void Update()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			if (hotkey.Value.IsKeyDown())
			{
				RepairInventory();
			}
		}

		private void RepairInventory()
		{
			if (!Object.op_Implicit((Object)(object)Global.code))
			{
				return;
			}
			PlayerCharacter player = Global.code.Player;
			if ((Object)(object)player == (Object)null)
			{
				return;
			}
			List<UIEquipmentSlot> list = new List<UIEquipmentSlot>();
			list.AddRange((IEnumerable<UIEquipmentSlot>)(object)new UIEquipmentSlot[4]
			{
				Global.code.uiInventory.miscSlot1,
				Global.code.uiInventory.miscSlot2,
				Global.code.uiInventory.miscSlot3,
				Global.code.uiInventory.miscSlot4
			});
			foreach (UIEquipmentSlot item in list)
			{
				if (((UIItemSlot)item).ThisItem == (Item)null)
				{
					InventoryRepair_SunkenlandLogger.LogDebug((object)("No item found in slot " + ((Object)item).name + ", skipping"));
				}
				else if (!(((Object)((UIItemSlot)item).ThisItem).name != "RepairMe"))
				{
					InventoryRepair_SunkenlandLogger.LogDebug((object)("Found RepairMe item in slot " + ((Object)item).name + ", repairing"));
					RepairStation obj = ((Component)player).gameObject.AddComponent<RepairStation>();
					obj.Repair();
					Object.DestroyImmediate((Object)(object)obj);
				}
			}
		}

		private void OnDestroy()
		{
			((BaseUnityPlugin)this).Config.Save();
		}

		private void SetupWatcher()
		{
			FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(Paths.ConfigPath, ConfigFileName);
			fileSystemWatcher.Changed += ReadConfigValues;
			fileSystemWatcher.Created += ReadConfigValues;
			fileSystemWatcher.Renamed += ReadConfigValues;
			fileSystemWatcher.IncludeSubdirectories = true;
			fileSystemWatcher.SynchronizingObject = ThreadingHelper.SynchronizingObject;
			fileSystemWatcher.EnableRaisingEvents = true;
		}

		private void ReadConfigValues(object sender, FileSystemEventArgs e)
		{
			if (!File.Exists(ConfigFileFullPath))
			{
				return;
			}
			try
			{
				InventoryRepair_SunkenlandLogger.LogDebug((object)"ReadConfigValues called");
				((BaseUnityPlugin)this).Config.Reload();
			}
			catch
			{
				InventoryRepair_SunkenlandLogger.LogError((object)("There was an issue loading your " + ConfigFileName));
				InventoryRepair_SunkenlandLogger.LogError((object)"Please check your config entries for spelling and format!");
			}
		}

		internal ConfigEntry<T> TextEntryConfig<T>(string group, string name, T value, string desc)
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Expected O, but got Unknown
			ConfigurationManagerAttributes configurationManagerAttributes = new ConfigurationManagerAttributes
			{
				CustomDrawer = TextAreaDrawer
			};
			return ((BaseUnityPlugin)this).Config.Bind<T>(group, name, value, new ConfigDescription(desc, (AcceptableValueBase)null, new object[1] { configurationManagerAttributes }));
		}

		internal static void TextAreaDrawer(ConfigEntryBase entry)
		{
			GUILayout.ExpandHeight(true);
			GUILayout.ExpandWidth(true);
			entry.BoxedValue = GUILayout.TextArea((string)entry.BoxedValue, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.ExpandWidth(true),
				GUILayout.ExpandHeight(true)
			});
		}

		static InventoryRepair_SunkenlandPlugin()
		{
			string configPath = Paths.ConfigPath;
			char directorySeparatorChar = Path.DirectorySeparatorChar;
			ConfigFileFullPath = configPath + directorySeparatorChar + ConfigFileName;
			InventoryRepair_SunkenlandLogger = Logger.CreateLogSource("InventoryRepair_Sunkenland");
			hotkey = null;
		}
	}
	public static class KeyboardExtensions
	{
		public static bool IsKeyDown(this KeyboardShortcut shortcut)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			if ((int)((KeyboardShortcut)(ref shortcut)).MainKey != 0 && Input.GetKeyDown(((KeyboardShortcut)(ref shortcut)).MainKey))
			{
				return ((KeyboardShortcut)(ref shortcut)).Modifiers.All((Func<KeyCode, bool>)Input.GetKey);
			}
			return false;
		}

		public static bool IsKeyHeld(this KeyboardShortcut shortcut)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			if ((int)((KeyboardShortcut)(ref shortcut)).MainKey != 0 && Input.GetKey(((KeyboardShortcut)(ref shortcut)).MainKey))
			{
				return ((KeyboardShortcut)(ref shortcut)).Modifiers.All((Func<KeyCode, bool>)Input.GetKey);
			}
			return false;
		}
	}
}
namespace ItemManager
{
	[PublicAPI]
	public enum WorkTable
	{
		Disabled,
		Inventory,
		[InternalName("F1_Stove")]
		Stove,
		[InternalName("A1_Research Table")]
		ResearchTable,
		[InternalName("B2_Avil")]
		Anvil,
		[InternalName("C1_Gun Workshop")]
		GunWorkshop,
		[InternalName("C2_Ammo Workshop")]
		AmmoWorkShop,
		[InternalName("C3_Armor Workshop")]
		ArmorWorkShop,
		Custom
	}
	public class InternalName : Attribute
	{
		public readonly string internalName;

		public InternalName(string internalName)
		{
			this.internalName = internalName;
		}
	}
	[PublicAPI]
	public class RequiredResourceList
	{
		public readonly List<Requirement> Requirements = new List<Requirement>();

		public bool Free;

		public void Add(string itemName, int amount, int quality = 0)
		{
			Requirements.Add(new Requirement
			{
				itemName = itemName,
				amount = amount,
				quality = quality
			});
		}

		public void Add(string itemName, ConfigEntry<int> amountConfig, int quality = 0)
		{
			Requirements.Add(new Requirement
			{
				itemName = itemName,
				amountConfig = amountConfig,
				quality = quality
			});
		}
	}
	[PublicAPI]
	public class CraftingStationList
	{
		public readonly List<WorkTableConfig> Stations = new List<WorkTableConfig>();

		public void Add(WorkTable table, int level)
		{
			Stations.Add(new WorkTableConfig
			{
				Table = table,
				level = level
			});
		}

		public void Add(string customTable, int level)
		{
			Stations.Add(new WorkTableConfig
			{
				Table = WorkTable.Custom,
				level = level,
				custom = customTable
			});
		}
	}
	[PublicAPI]
	public class WeaponRaycastConfigList
	{
		public readonly List<WeaponRayCastConfig> Requirements = new List<WeaponRayCastConfig>();

		public bool Free;

		public void Add(string itemName, int amount, int quality = 0)
		{
			Requirements.Add(new WeaponRayCastConfig
			{
				itemName = itemName,
				amount = amount,
				quality = quality
			});
		}

		public void Add(string itemName, ConfigEntry<int> amountConfig, int quality = 0)
		{
			Requirements.Add(new WeaponRayCastConfig
			{
				itemName = itemName,
				amountConfig = amountConfig,
				quality = quality
			});
		}
	}
	[PublicAPI]
	public class CustomItemRequirement
	{
		public readonly RequiredResourceList RequiredItems = new RequiredResourceList();

		public readonly WeaponRaycastConfigList RayCastConfigList = new WeaponRaycastConfigList();

		public readonly RequiredResourceList RequiredUpgradeItems = new RequiredResourceList();

		public readonly CraftingStationList Crafting = new CraftingStationList();

		public int CraftAmount = 1;

		public bool RequireOnlyOneIngredient;

		public float QualityResultAmountMultiplier = 1f;

		public ConfigEntryBase? CustomItemRequirementIsActive;

		public int Level = 1;

		public bool Rare;

		public int Amount = 1;

		public int Stack = 1;

		public bool CanBeSold = true;

		public float Condition = 100f;

		public float MaxCondition = 100f;

		public EquipmentSlotType EquipmentSlotType = (EquipmentSlotType)8;

		public string Icon = "I_Gasoline";
	}
	public struct Requirement
	{
		public string itemName;

		public int amount;

		public ConfigEntry<int>? amountConfig;

		[Description("Set to a non-zero value to apply the requirement only for a specific quality")]
		public int quality;
	}
	public struct WeaponRayCastConfig
	{
		public string itemName;

		public int amount;

		public ConfigEntry<int>? amountConfig;

		[Description("Set to a non-zero value to apply the requirement only for a specific quality")]
		public int quality;
	}
	public struct WorkTableConfig
	{
		public WorkTable Table;

		public int level;

		public string? custom;
	}
	public struct MockItem
	{
		public string? name;

		public string? description;

		public string? mockFrom;
	}
	[Flags]
	public enum Configurability
	{
		Disabled = 0,
		CustomItemRequirement = 1,
		Stats = 2,
		Drop = 4,
		Trader = 8,
		Full = 0xF
	}
	public enum Toggle
	{
		On = 1,
		Off = 0
	}
	[PublicAPI]
	public class CustomItem
	{
		private class ItemConfig
		{
			public ConfigEntry<string>? craft;

			public ConfigEntry<string>? upgrade;

			public ConfigEntry<WorkTable> table;

			public ConfigEntry<int> tableLevel;

			public ConfigEntry<string> customTable;

			public ConfigEntry<int>? maximumTableLevel;

			public ConfigEntry<float> qualityResultAmountMultiplier;
		}

		private class ConfigurationManagerAttributes
		{
			[UsedImplicitly]
			public int? Order;

			[UsedImplicitly]
			public bool? Browsable;

			[UsedImplicitly]
			public string? Category;

			[UsedImplicitly]
			public Action<ConfigEntryBase>? CustomDrawer;

			public Func<bool>? browsability;
		}

		private static readonly List<CustomItem> registeredItems = new List<CustomItem>();

		private static readonly Dictionary<CustomItem, Item> registeredItemsItemComp = new Dictionary<CustomItem, Item>();

		private static readonly Dictionary<Item, CustomItem> ItemMap = new Dictionary<Item, CustomItem>();

		private static Dictionary<CustomItem, Dictionary<string, List<CraftingItemRequirement>>> activeCustomItemRequirements = new Dictionary<CustomItem, Dictionary<string, List<CraftingItemRequirement>>>();

		private static Dictionary<CustomItem, Dictionary<string, ItemConfig>> itemCraftConfigs = new Dictionary<CustomItem, Dictionary<string, ItemConfig>>();

		private static Dictionary<CustomItem, ConfigEntry<string>> ItemConfigs = new Dictionary<CustomItem, ConfigEntry<string>>();

		private readonly Dictionary<ConfigEntryBase, Action> statsConfigs = new Dictionary<ConfigEntryBase, Action>();

		public static Configurability DefaultConfigurability = Configurability.Full;

		public Configurability? Configurable;

		private Configurability configurationVisible = Configurability.Full;

		public readonly GameObject Prefab;

		private MockItem? mockItem;

		public Dictionary<string, CustomItemRequirement> CustomItemRequirements = new Dictionary<string, CustomItemRequirement>();

		private static BaseUnityPlugin? _plugin;

		private static Dictionary<int, string> assignedIDs = new Dictionary<int, string>();

		private Configurability configurability => Configurable ?? DefaultConfigurability;

		[Description("Specifies the resources needed to craft the item.\nUse .Add to add resources with their internal ID and an amount.\nUse one .Add for each resource type the item should need.")]
		public RequiredResourceList RequiredItems => this[""].RequiredItems;

		[Description("Specifies the resources needed to craft the item.\nUse .Add to add resources with their internal ID and an amount.\nUse one .Add for each resource type the item should need.")]
		public WeaponRaycastConfigList RayCastConfigList => this[""].RayCastConfigList;

		[Description("Specifies the resources needed to upgrade the item.\nUse .Add to add resources with their internal ID and an amount. This amount will be multipled by the item quality level.\nUse one .Add for each resource type the upgrade should need.")]
		public RequiredResourceList RequiredUpgradeItems => this[""].RequiredUpgradeItems;

		[Description("Specifies the crafting station needed to craft the item.\nUse .Add to add a crafting station, using the CraftingTable enum and a minimum level for the crafting station.\nUse one .Add for each crafting station.")]
		public CraftingStationList Crafting => this[""].Crafting;

		[Description("Specifies a config entry which toggles whether a recipe is active.")]
		public ConfigEntryBase? CustomItemRequirementIsActive
		{
			get
			{
				return this[""].CustomItemRequirementIsActive;
			}
			set
			{
				this[""].CustomItemRequirementIsActive = value;
			}
		}

		[Description("Specifies the number of items that should be given to the player with a single craft of the item.\nDefaults to 1.")]
		public int Level
		{
			get
			{
				return this[""].Level;
			}
			set
			{
				this[""].Level = value;
			}
		}

		[Description("Specifies the rarity of the item.\nDefaults to false.")]
		public bool Rare
		{
			get
			{
				return this[""].Rare;
			}
			set
			{
				this[""].Rare = value;
			}
		}

		[Description("Specifies the number of items that should be given to the player with a single craft of the item.\nDefaults to 1.")]
		public int CraftAmount
		{
			get
			{
				return this[""].CraftAmount;
			}
			set
			{
				this[""].CraftAmount = value;
			}
		}

		[Description("Specifies the stack size of the item.\nDefaults to 1.")]
		public int Stack
		{
			get
			{
				return this[""].Stack;
			}
			set
			{
				this[""].Stack = value;
			}
		}

		[Description("Specifies if the item can be sold to a trader.\nDefaults to true.")]
		public bool CanBeSold
		{
			get
			{
				return this[""].CanBeSold;
			}
			set
			{
				this[""].CanBeSold = value;
			}
		}

		[Description("Specifies the condition of the item.\nDefaults to 100.")]
		public float Condition
		{
			get
			{
				return this[""].Condition;
			}
			set
			{
				this[""].Condition = value;
			}
		}

		[Description("Specifies the maximum condition of the item.\nDefaults to 100.")]
		public float MaxCondition
		{
			get
			{
				return this[""].MaxCondition;
			}
			set
			{
				this[""].MaxCondition = value;
			}
		}

		[Description("Specifies the equipment slot type of the item.\nDefaults to Misc.")]
		public EquipmentSlotType EquipmentSlotType
		{
			get
			{
				//IL_000b: Unknown result type (might be due to invalid IL or missing references)
				return this[""].EquipmentSlotType;
			}
			set
			{
				//IL_000b: Unknown result type (might be due to invalid IL or missing references)
				//IL_000c: Unknown result type (might be due to invalid IL or missing references)
				this[""].EquipmentSlotType = value;
			}
		}

		[Description("Specifies the icon of the item.\nDefaults to I_Gasoline.")]
		public string Icon
		{
			get
			{
				return this[""].Icon;
			}
			set
			{
				this[""].Icon = value;
			}
		}

		public CustomItemRequirement this[string name]
		{
			get
			{
				if (CustomItemRequirements.TryGetValue(name, out CustomItemRequirement value))
				{
					return value;
				}
				return CustomItemRequirements[name] = new CustomItemRequirement();
			}
		}

		private static BaseUnityPlugin plugin
		{
			get
			{
				//IL_009b: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a5: Expected O, but got Unknown
				if (_plugin == null)
				{
					IEnumerable<TypeInfo> source;
					try
					{
						source = Assembly.GetExecutingAssembly().DefinedTypes.ToList();
					}
					catch (ReflectionTypeLoadException ex)
					{
						source = from t in ex.Types
							where t != null
							select t.GetTypeInfo();
					}
					_plugin = (BaseUnityPlugin)Chainloader.ManagerObject.GetComponent((Type)source.First((TypeInfo t) => t.IsClass && typeof(BaseUnityPlugin).IsAssignableFrom(t)));
				}
				return _plugin;
			}
		}

		public CustomItem(string assetBundleFileName, string prefabName)
			: this(PrefabManager.GetAssetBundleFromResources(assetBundleFileName), prefabName)
		{
		}

		public CustomItem(AssetBundle bundle, string prefabName)
			: this(PrefabManager.RegisterPrefab(bundle, prefabName))
		{
		}

		public CustomItem(string prefabName, string description, string mockFrom)
			: this(PrefabManager.RegisterPrefab(prefabName, description, mockFrom))
		{
		}

		public CustomItem(GameObject prefab, bool skipRegistering = false)
		{
			if (!skipRegistering)
			{
				PrefabManager.RegisterPrefab(prefab);
			}
			Prefab = prefab;
			registeredItems.Add(this);
			ItemMap[Prefab.GetComponent<Item>()] = this;
		}

		private CustomItem(Dictionary<string, MockItem> mockedItem)
		{
			mockItem = mockedItem.Values.First();
			registeredItems.Add(this);
		}

		public void ToggleConfigurationVisibility(Configurability visible)
		{
			configurationVisible = visible;
			if (ItemConfigs.TryGetValue(this, out ConfigEntry<string> value))
			{
				Toggle((ConfigEntryBase)(object)value, Configurability.Drop);
			}
			if (itemCraftConfigs.TryGetValue(this, out Dictionary<string, ItemConfig> value2))
			{
				foreach (ItemConfig value4 in value2.Values)
				{
					ToggleObj(value4, Configurability.CustomItemRequirement);
				}
			}
			foreach (KeyValuePair<ConfigEntryBase, Action> statsConfig in statsConfigs)
			{
				Toggle(statsConfig.Key, Configurability.Stats);
				if ((visible & Configurability.Stats) != 0)
				{
					statsConfig.Value();
				}
			}
			void Toggle(ConfigEntryBase cfg, Configurability check)
			{
				object[] tags = cfg.Description.Tags;
				for (int j = 0; j < tags.Length; j++)
				{
					if (tags[j] is ConfigurationManagerAttributes configurationManagerAttributes)
					{
						configurationManagerAttributes.Browsable = (visible & check) != 0 && (configurationManagerAttributes.browsability == null || configurationManagerAttributes.browsability());
					}
				}
			}
			void ToggleObj(object obj, Configurability check)
			{
				FieldInfo[] fields = obj.GetType().GetFields();
				for (int i = 0; i < fields.Length; i++)
				{
					object? value3 = fields[i].GetValue(obj);
					ConfigEntryBase val = (ConfigEntryBase)((value3 is ConfigEntryBase) ? value3 : null);
					if (val != null)
					{
						Toggle(val, check);
					}
				}
			}
		}

		private static string getInternalName<T>(T value) where T : struct
		{
			return ((InternalName)typeof(T).GetMember(value.ToString())[0].GetCustomAttributes(typeof(InternalName)).First()).internalName;
		}

		private void registerRecipes(RM instance, GameObject container)
		{
			//IL_0284: Unknown result type (might be due to invalid IL or missing references)
			//IL_0289: Unknown result type (might be due to invalid IL or missing references)
			//IL_03da: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0547: Unknown result type (might be due to invalid IL or missing references)
			RM instance2 = instance;
			Blueprint val3 = default(Blueprint);
			Craftable val4 = default(Craftable);
			foreach (CustomItem customItem in registeredItems)
			{
				activeCustomItemRequirements[customItem] = new Dictionary<string, List<CraftingItemRequirement>>();
				itemCraftConfigs.TryGetValue(this, out Dictionary<string, ItemConfig> _);
				if (string.IsNullOrWhiteSpace(customItem.mockItem?.mockFrom))
				{
					continue;
				}
				Item val = null;
				foreach (Transform item in instance2.allItems.items.Where((Transform allItemsItem) => ((Object)allItemsItem).name == customItem.mockItem?.mockFrom))
				{
					val = ((Component)item).GetComponent<Item>();
				}
				if (val == (Item)null)
				{
					break;
				}
				Debug.Log((object)("Creating mock from " + customItem.mockItem?.mockFrom));
				Transform val2 = Object.Instantiate<Transform>(((Component)val).transform, container.transform, true);
				if (!Object.op_Implicit((Object)(object)val2))
				{
					break;
				}
				Item newItemComponent = ((Component)val2).GetComponent<Item>();
				if (!Object.op_Implicit((Object)(object)newItemComponent))
				{
					break;
				}
				((Object)val2).name = customItem.mockItem?.name ?? "MockItem";
				((Object)newItemComponent).name = customItem.mockItem?.name ?? "MockItem";
				newItemComponent.level = customItem.Level;
				newItemComponent.rare = customItem.Rare;
				newItemComponent.craftAmount = customItem.CraftAmount;
				newItemComponent.stackAmount = customItem.Stack;
				newItemComponent.canBeSold = customItem.CanBeSold;
				newItemComponent.Condition = customItem.Condition;
				newItemComponent.MaxCondition = customItem.MaxCondition;
				newItemComponent.equipmentSlotType = customItem.EquipmentSlotType;
				((MonoBehaviour)plugin).StartCoroutine(LoadSpriteFromURL(customItem.Icon, delegate(Sprite sprite)
				{
					if ((Object)(object)sprite != (Object)null)
					{
						newItemComponent.icon = sprite.texture;
					}
				}));
				Debug.Log((object)("[" + Assembly.GetExecutingAssembly().GetName().Name + "] Created mock item with name: " + ((Object)newItemComponent).name + " " + $"and level: {newItemComponent.level} " + $"and rare: {newItemComponent.rare} " + $"and craftAmount: {newItemComponent.craftAmount} " + $"and stackAmount: {newItemComponent.stackAmount} " + $"and canBeSold: {newItemComponent.canBeSold} " + $"and condition: {newItemComponent.Condition} " + $"and MaxCondition: {newItemComponent.MaxCondition} " + $"and equipmentSlotType: {newItemComponent.equipmentSlotType} " + $"and icon: {newItemComponent.icon} {customItem.Icon}"));
				instance2.allItems.items.Max((Transform i) => ((Component)i).GetComponent<Item>()?.ItemID ?? 0);
				newItemComponent.ItemID = GetItemID(customItem.mockItem?.name);
				Debug.Log((object)$"Generated ItemID for '{GetModName()}:{customItem.mockItem?.name}' is {newItemComponent.ItemID}");
				newItemComponent.localizedItemName = LocalizationRuntimeManager.CreateLocalizedString(TableReference.op_Implicit(((LocalizedDatabase<StringTable, StringTableEntry>)(object)LocalizationSettings.StringDatabase).DefaultTable), ((Object)val2).name + "_" + newItemComponent.ItemID, customItem.mockItem?.name);
				((LocalizedReference)newItemComponent.localizedItemName).FallbackState = (FallbackBehavior)2;
				newItemComponent.localizedItemDescription = LocalizationRuntimeManager.CreateLocalizedString(TableReference.op_Implicit(((LocalizedDatabase<StringTable, StringTableEntry>)(object)LocalizationSettings.StringDatabase).DefaultTable), ((Object)val2).name + "_" + newItemComponent.ItemID + "_description", customItem.mockItem?.description);
				((LocalizedReference)newItemComponent.localizedItemDescription).FallbackState = (FallbackBehavior)2;
				newItemComponent.GetCurrentLocaleAndRefresh();
				instance2.allItems.AddItemDifferentName(val2);
				if (!instance2.ItemDictionary.ContainsKey(newItemComponent.ItemID))
				{
					instance2.ItemDictionary.Add(newItemComponent.ItemID, newItemComponent);
				}
				Craftable component = ((Component)val2).GetComponent<Craftable>();
				if (Object.op_Implicit((Object)(object)component))
				{
					component.itemRequirements = ((IEnumerable<Requirement>)customItem.RequiredItems.Requirements).Select((Func<Requirement, CraftingItemRequirement>)((Requirement r) => new CraftingItemRequirement
					{
						item = ((IEnumerable<Transform>)instance2.allItems.items).FirstOrDefault((Func<Transform, bool>)((Transform x) => ((Object)x).name == r.itemName)),
						amount = r.amount
					})).ToArray();
					instance2._allCraftables.Add(component);
					component.NeedBlueprint = false;
				}
				if (Object.op_Implicit((Object)(object)val2) && ((Component)val2).TryGetComponent<Blueprint>(ref val3))
				{
					if (Object.op_Implicit((Object)(object)val3) && val3.UnlockItems.Length != 0)
					{
						Item[] unlockItems = val3.UnlockItems;
						for (int j = 0; j < unlockItems.Length; j++)
						{
							if (((Component)unlockItems[j]).TryGetComponent<Craftable>(ref val4))
							{
								val4.NeedBlueprint = true;
							}
						}
					}
					if (Object.op_Implicit((Object)(object)val3) && val3.UnlockBuildings.Length != 0)
					{
						BuildingPiece[] unlockBuildings = val3.UnlockBuildings;
						foreach (BuildingPiece val5 in unlockBuildings)
						{
							if (!((Object)(object)val5 == (Object)null))
							{
								((Component)val5).GetComponent<Craftable>().NeedBlueprint = true;
							}
						}
					}
				}
				if (!registeredItemsItemComp.ContainsKey(customItem))
				{
					registeredItemsItemComp.Add(customItem, newItemComponent);
				}
				newItemComponent.localizedItemName.RefreshString();
				newItemComponent.localizedItemDescription.RefreshString();
				Debug.Log((object)($"[{Assembly.GetExecutingAssembly().GetName().Name}] {customItem.mockItem?.name} created! with ID: {newItemComponent.ItemID} " + "and name: " + ((Object)newItemComponent).name + " and display name: " + newItemComponent.GetDisplayName() + " and description " + newItemComponent.GetDisplayDescription() + " and localized name: " + LocalizationRuntimeManager.GetString(newItemComponent.localizedItemName) + " and localized description: " + LocalizationRuntimeManager.GetString(newItemComponent.localizedItemDescription)));
			}
		}

		public static string GetModName()
		{
			Assembly callingAssembly = Assembly.GetCallingAssembly();
			AssemblyTitleAttribute customAttribute = callingAssembly.GetCustomAttribute<AssemblyTitleAttribute>();
			if (customAttribute != null)
			{
				return customAttribute.Title;
			}
			return callingAssembly.GetName().Name ?? "UnknownMod";
		}

		public static int GetItemID(string itemName)
		{
			string text = GetModName() + ":" + itemName;
			int num = FNV1aHash(text);
			if (assignedIDs.TryGetValue(num, out string value) && value != text)
			{
				Console.WriteLine("Collision detected for " + text + ". Existing entry: " + value);
				return GenerateFallbackID();
			}
			assignedIDs[num] = text;
			return num;
		}

		private static int GenerateFallbackID()
		{
			int i;
			for (i = assignedIDs.Count + 1000; assignedIDs.ContainsKey(i); i++)
			{
			}
			return i;
		}

		private static int FNV1aHash(string input)
		{
			int num = -2128831035;
			byte[] bytes = Encoding.UTF8.GetBytes(input);
			foreach (byte b in bytes)
			{
				num ^= b;
				num *= 16777619;
			}
			return num;
		}

		internal static IEnumerator LoadSpriteFromURL(string? imageURL, Action<Sprite> callback)
		{
			if (imageURL == null)
			{
				callback(null);
				yield break;
			}
			UnityWebRequest www = UnityWebRequestTexture.GetTexture(imageURL);
			yield return www.SendWebRequest();
			Result result = www.result;
			if (result - 2 <= 1)
			{
				Debug.LogError((object)("Error while fetching image: " + www.error));
				callback(null);
			}
			else
			{
				Texture2D content = DownloadHandlerTexture.GetContent(www);
				Sprite obj = Sprite.Create(content, new Rect(0f, 0f, (float)((Texture)content).width, (float)((Texture)content).height), new Vector2(0.5f, 0.5f));
				callback(obj);
			}
		}

		[HarmonyPriority(700)]
		public static void Patch_RMLoadResources(RM __instance)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			GameObject val;
			if ((Object)(object)GameObject.Find("SunkenlandItemManagerContainer") == (Object)null)
			{
				val = new GameObject("SunkenlandItemManagerContainer");
				Object.DontDestroyOnLoad((Object)(object)val);
			}
			else
			{
				val = GameObject.Find("SunkenlandItemManagerContainer");
			}
			foreach (CustomItem registeredItem in registeredItems)
			{
				registeredItem.registerRecipes(__instance, val);
			}
		}

		[HarmonyPriority(700)]
		public static void Patch_AddItemToFPSPlayer(FPSPlayer __instance)
		{
			GameObject val = GameObject.Find("Weapon Pivot V Bob");
			if (!((Object)(object)val != (Object)null))
			{
				return;
			}
			Debug.Log((object)$"[{Assembly.GetExecutingAssembly().GetName().Name}] Found weaponHolder: {((Object)val).name} with {val.transform.childCount} children");
			foreach (KeyValuePair<CustomItem, Item> item in registeredItemsItemComp)
			{
				Transform itemWithName = RM.code.allItems.GetItemWithName(item.Key.mockItem?.mockFrom);
				if ((Object)(object)itemWithName == (Object)null)
				{
					continue;
				}
				Debug.Log((object)("[" + Assembly.GetExecutingAssembly().GetName().Name + "] Found weaponClonedFrom: " + ((Object)itemWithName).name));
				Transform val2 = null;
				val2 = val.transform.Find(((Component)itemWithName).GetComponent<Item>().GetDisplayName()) ?? val.transform.Find(((Object)itemWithName).name);
				if (!((Object)(object)val2 == (Object)null))
				{
					Debug.Log((object)("[" + Assembly.GetExecutingAssembly().GetName().Name + "] Found WeaponBehavior: " + ((Object)val2).name));
					Transform obj = Object.Instantiate<Transform>(val2, val.transform);
					((Object)obj).name = item.Key.mockItem?.name;
					WeaponBehavior component = ((Component)obj).GetComponent<WeaponBehavior>();
					component.WeaponItem = item.Value;
					component.weaponNumber = val.transform.childCount + 1;
					if (!IListExtensions.Contains<WeaponBehavior>((IList<WeaponBehavior>)PlayerWeapons.code.weaponOrder, component))
					{
						List<WeaponBehavior> list = new List<WeaponBehavior>(PlayerWeapons.code.weaponOrder);
						list.Add(component);
						PlayerWeapons.code.weaponOrder = list.ToArray();
					}
					if (!IListExtensions.Contains<WeaponBehavior>((IList<WeaponBehavior>)PlayerWeapons.code.weaponBehaviors, component))
					{
						List<WeaponBehavior> list2 = new List<WeaponBehavior>(PlayerWeapons.code.weaponBehaviors);
						list2.Add(component);
						PlayerWeapons.code.weaponBehaviors = list2.ToArray();
					}
				}
			}
		}
	}
	[PublicAPI]
	public static class PrefabManager
	{
		private struct BundleId
		{
			[UsedImplicitly]
			public string assetBundleFileName;
		}

		private static readonly Dictionary<BundleId, AssetBundle> bundleCache;

		private static readonly List<GameObject> prefabs;

		static PrefabManager()
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Expected O, but got Unknown
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Expected O, but got Unknown
			bundleCache = new Dictionary<BundleId, AssetBundle>();
			prefabs = new List<GameObject>();
			Harmony val = new Harmony("org.bepinex.helpers.ItemManager");
			val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(RM), "LoadResources", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(CustomItem), "Patch_RMLoadResources", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(FPSPlayer), "Start", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(CustomItem), "Patch_AddItemToFPSPlayer", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		}

		internal static AssetBundle GetAssetBundleFromResources(string assetBundleFileName)
		{
			string assetBundleFileName2 = assetBundleFileName;
			BundleId bundleId = default(BundleId);
			bundleId.assetBundleFileName = assetBundleFileName2;
			BundleId key = bundleId;
			if (!bundleCache.TryGetValue(key, out AssetBundle value))
			{
				Assembly executingAssembly = Assembly.GetExecutingAssembly();
				string name = executingAssembly.GetManifestResourceNames().Single((string str) => str.EndsWith(assetBundleFileName2));
				using Stream stream = executingAssembly.GetManifestResourceStream(name);
				value = AssetBundle.LoadFromStream(stream);
			}
			if ((Object)(object)value == (Object)null)
			{
				throw new Exception("[" + Assembly.GetExecutingAssembly().GetName().Name + "] Failed to load asset bundle " + assetBundleFileName2 + ", please make sure you have set this as an embedded resource in your project and that the name matches the filename.");
			}
			return value;
		}

		public static GameObject RegisterPrefab(string assetBundleFileName, string prefabName)
		{
			return RegisterPrefab(GetAssetBundleFromResources(assetBundleFileName), prefabName);
		}

		public static GameObject RegisterPrefab(AssetBundle assets, string prefabName)
		{
			return RegisterPrefab(assets.LoadAsset<GameObject>(prefabName));
		}

		public static Dictionary<string, MockItem> RegisterPrefab(string prefabName, string description, string mockFrom)
		{
			return new Dictionary<string, MockItem> { 
			{
				prefabName,
				new MockItem
				{
					name = prefabName,
					description = description,
					mockFrom = mockFrom
				}
			} };
		}

		public static GameObject RegisterPrefab(GameObject prefab)
		{
			prefabs.Add(prefab);
			return prefab;
		}
	}
	public class LocalizationRuntimeManager : MonoBehaviour
	{
		private static Dictionary<string, StringTable> runtimeTables = new Dictionary<string, StringTable>();

		public static LocalizedString CreateLocalizedString(string tableName, string key, string value)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: 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_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			((DetailedLocalizationTable<StringTableEntry>)(object)((LocalizedDatabase<StringTable, StringTableEntry>)(object)LocalizationSettings.StringDatabase).GetTable(((LocalizedDatabase<StringTable, StringTableEntry>)(object)LocalizationSettings.StringDatabase).DefaultTable, (Locale)null)).AddEntry(key, value);
			return new LocalizedString
			{
				TableReference = ((LocalizedDatabase<StringTable, StringTableEntry>)(object)LocalizationSettings.StringDatabase).DefaultTable,
				TableEntryReference = TableEntryReference.op_Implicit(key),
				LocaleOverride = LocalizationSettings.SelectedLocale
			};
		}

		public static string GetString(LocalizedString localizedString)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: 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)
			if (runtimeTables.TryGetValue(TableReference.op_Implicit(((LocalizedReference)localizedString).TableReference), out StringTable value))
			{
				StringTableEntry entry = ((DetailedLocalizationTable<StringTableEntry>)(object)value).GetEntry(TableEntryReference.op_Implicit(((LocalizedReference)localizedString).TableEntryReference));
				if (entry != null)
				{
					return ((TableEntry)entry).LocalizedValue;
				}
				Debug.LogError((object)$"[{Assembly.GetExecutingAssembly().GetName().Name}] No entry found with key: {((LocalizedReference)localizedString).TableEntryReference} in table: {((LocalizedReference)localizedString).TableReference}");
			}
			return null;
		}
	}
}