Decompiled source of ZehsScrapLib v1.0.0

com.github.zehsteam.ZehsScrapLib.dll

Decompiled 2 years ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Cryptography;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.Audio;
using com.github.zehsteam.ZehsScrapLib.Extras;
using com.github.zehsteam.ZehsScrapLib.Modules;
using com.github.zehsteam.ZehsScrapLib.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("com.github.zehsteam.ZehsScrapLib")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Personal scrap items library.")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("ZehsScrapLib")]
[assembly: AssemblyTitle("com.github.zehsteam.ZehsScrapLib")]
[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.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.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.ZehsScrapLib
{
	internal class ConfigManager
	{
		private ConfigEntry<bool> ExtendedLoggingCfg;

		private ConfigEntry<bool> UseSavedataFixCfg;

		internal bool ExtendedLogging
		{
			get
			{
				return ExtendedLoggingCfg.Value;
			}
			set
			{
				ExtendedLoggingCfg.Value = value;
			}
		}

		internal bool UseSavedataFix
		{
			get
			{
				return UseSavedataFixCfg.Value;
			}
			set
			{
				UseSavedataFixCfg.Value = value;
			}
		}

		public ConfigManager()
		{
			BindConfigs();
		}

		private void BindConfigs()
		{
			//IL_0018: 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_0033: Expected O, but got Unknown
			//IL_0033: Expected O, but got Unknown
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Expected O, but got Unknown
			//IL_005f: Expected O, but got Unknown
			ConfigFile config = ((BaseUnityPlugin)Plugin.Instance).Config;
			ExtendedLoggingCfg = config.Bind<bool>(new ConfigDefinition("General", "extendedLogging"), false, new ConfigDescription("Enable extended logging.", (AcceptableValueBase)null, Array.Empty<object>()));
			UseSavedataFixCfg = config.Bind<bool>(new ConfigDefinition("Items", "useSavedataFix"), false, new ConfigDescription("Allow for ZehScrapLib to store/reorder the item list, which should fix issues where items get reshuffled when loading an old save. This is experimental and may cause save corruptions occasionally.", (AcceptableValueBase)null, Array.Empty<object>()));
		}
	}
	[BepInPlugin("com.github.zehsteam.ZehsScrapLib", "ZehsScrapLib", "1.0.0")]
	public class Plugin : BaseUnityPlugin
	{
		private readonly Harmony harmony = new Harmony("com.github.zehsteam.ZehsScrapLib");

		internal static Plugin Instance;

		internal static ManualLogSource logger;

		internal ConfigManager ConfigManager;

		private void Awake()
		{
			if ((Object)(object)Instance == (Object)null)
			{
				Instance = this;
			}
			logger = Logger.CreateLogSource("com.github.zehsteam.ZehsScrapLib");
			logger.LogInfo((object)"ZehsScrapLib has awoken!");
			harmony.PatchAll(typeof(On));
			ConfigManager = new ConfigManager();
			Items.Init();
			Utilities.Init();
			NetworkPrefabs.Init();
		}
	}
	internal static class ReflectionHelper
	{
		private static FieldInfo GetFieldInfo(Type type, string fieldName)
		{
			FieldInfo field;
			do
			{
				field = type.GetField(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				type = type.BaseType;
			}
			while (field == null && type != null);
			return field;
		}

		public static object GetFieldValue(this object obj, string fieldName)
		{
			if (obj == null)
			{
				throw new ArgumentNullException("obj");
			}
			Type type = obj.GetType();
			FieldInfo fieldInfo = GetFieldInfo(type, fieldName);
			if (fieldInfo == null)
			{
				throw new ArgumentOutOfRangeException("fieldName", $"Couldn't find field {fieldName} in type {type.FullName}");
			}
			return fieldInfo.GetValue(obj);
		}

		public static void SetFieldValue(this object obj, string fieldName, object val)
		{
			if (obj == null)
			{
				throw new ArgumentNullException("obj");
			}
			Type type = obj.GetType();
			FieldInfo fieldInfo = GetFieldInfo(type, fieldName);
			if (fieldInfo == null)
			{
				throw new ArgumentOutOfRangeException("fieldName", $"Couldn't find field {fieldName} in type {type.FullName}");
			}
			fieldInfo.SetValue(obj, val);
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "com.github.zehsteam.ZehsScrapLib";

		public const string PLUGIN_NAME = "ZehsScrapLib";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}
namespace com.github.zehsteam.ZehsScrapLib.Patches
{
	[HarmonyPatch]
	internal class On
	{
		public static Action<GameNetworkManager> GameNetworkManager_Start_Postfix;

		public static Action<StartOfRound> StartOfRound_Start_Prefix;

		public static Action<MenuManager> MenuManager_Start_Postfix;

		public static Action<Terminal> Terminal_Awake_Prefix;

		[HarmonyPatch(typeof(GameNetworkManager), "Start")]
		[HarmonyPostfix]
		private static void GameNetworkManagerPatch_Start_Postfix(ref GameNetworkManager __instance)
		{
			GameNetworkManager_Start_Postfix(__instance);
		}

		[HarmonyPatch(typeof(StartOfRound), "Start")]
		[HarmonyPrefix]
		private static void StartOfRoundPatch_Start_Prefix(ref StartOfRound __instance)
		{
			StartOfRound_Start_Prefix(__instance);
		}

		[HarmonyPatch(typeof(MenuManager), "Start")]
		[HarmonyPostfix]
		private static void MenuManagerPatch_Start_Postfix(ref MenuManager __instance)
		{
			MenuManager_Start_Postfix(__instance);
		}

		[HarmonyPatch(typeof(Terminal), "Awake")]
		[HarmonyPrefix]
		private static void TerminalPatch_Awake_Prefix(ref Terminal __instance)
		{
			Terminal_Awake_Prefix(__instance);
		}
	}
}
namespace com.github.zehsteam.ZehsScrapLib.Modules
{
	public class Items
	{
		public struct ItemSaveOrderData
		{
			public int itemId;

			public string itemName;

			public string assetName;
		}

		public class ScrapItem
		{
			public Item item;

			public Item origItem;

			public int rarity = 0;

			public Levels.LevelTypes spawnLevels;

			public string[] spawnLevelOverrides;

			public string modName = "Unknown";

			public Dictionary<string, int> customLevelRarities = new Dictionary<string, int>();

			public Dictionary<Levels.LevelTypes, int> levelRarities = new Dictionary<Levels.LevelTypes, int>();

			public ScrapItem(Item item, int rarity, Levels.LevelTypes spawnLevels = Levels.LevelTypes.None, string[] spawnLevelOverrides = null)
			{
				origItem = item;
				if (!item.isScrap)
				{
					item = item.Clone<Item>();
					item.isScrap = true;
					if (item.maxValue == 0 && item.minValue == 0)
					{
						item.minValue = 40;
						item.maxValue = 100;
					}
					else if (item.maxValue == 0)
					{
						item.maxValue = item.minValue * 2;
					}
					else if (item.minValue == 0)
					{
						item.minValue = item.maxValue / 2;
					}
					GameObject val = NetworkPrefabs.CloneNetworkPrefab(item.spawnPrefab);
					if ((Object)(object)val.GetComponent<GrabbableObject>() != (Object)null)
					{
						val.GetComponent<GrabbableObject>().itemProperties = item;
					}
					item.spawnPrefab = val;
				}
				this.item = item;
				if (spawnLevelOverrides != null)
				{
					foreach (string levelName in spawnLevelOverrides)
					{
						customLevelRarities.Add(Levels.Compatibility.GetLLLNameOfLevel(levelName), rarity);
					}
				}
				if (spawnLevels == Levels.LevelTypes.None)
				{
					return;
				}
				foreach (Levels.LevelTypes value in Enum.GetValues(typeof(Levels.LevelTypes)))
				{
					if (spawnLevels.HasFlag(value))
					{
						levelRarities.Add(value, rarity);
					}
				}
			}

			public ScrapItem(Item item, Dictionary<Levels.LevelTypes, int>? levelRarities = null, Dictionary<string, int>? customLevelRarities = null)
			{
				origItem = item;
				if (!item.isScrap)
				{
					item = item.Clone<Item>();
					item.isScrap = true;
					if (item.maxValue == 0 && item.minValue == 0)
					{
						item.minValue = 40;
						item.maxValue = 100;
					}
					else if (item.maxValue == 0)
					{
						item.maxValue = item.minValue * 2;
					}
					else if (item.minValue == 0)
					{
						item.minValue = item.maxValue / 2;
					}
					GameObject val = NetworkPrefabs.CloneNetworkPrefab(item.spawnPrefab);
					if ((Object)(object)val.GetComponent<GrabbableObject>() != (Object)null)
					{
						val.GetComponent<GrabbableObject>().itemProperties = item;
					}
					item.spawnPrefab = val;
				}
				this.item = item;
				if (customLevelRarities != null)
				{
					this.customLevelRarities = Levels.Compatibility.LLLifyLevelRarityDictionary(customLevelRarities);
				}
				if (levelRarities != null)
				{
					this.levelRarities = levelRarities;
				}
			}
		}

		public class PlainItem
		{
			public Item item;

			public string modName;

			public PlainItem(Item item)
			{
				this.item = item;
			}
		}

		private static List<SelectableLevel> levelsAlreadyAddedTo = new List<SelectableLevel>();

		public static List<Item> ZehsScrapLibItemList = new List<Item>();

		public static List<ScrapItem> scrapItems = new List<ScrapItem>();

		public static List<PlainItem> plainItems = new List<PlainItem>();

		public static void Init()
		{
			On.StartOfRound_Start_Prefix = (Action<StartOfRound>)Delegate.Combine(On.StartOfRound_Start_Prefix, new Action<StartOfRound>(StartOfRound_Start));
			On.Terminal_Awake_Prefix = (Action<Terminal>)Delegate.Combine(On.Terminal_Awake_Prefix, new Action<Terminal>(Terminal_Awake));
		}

		private static void StartOfRound_Start(StartOfRound self)
		{
			if (!Plugin.Instance.ConfigManager.UseSavedataFix || !((NetworkBehaviour)self).IsHost)
			{
				return;
			}
			Plugin.logger.LogInfo((object)"Fixing Item savedata!!");
			List<ItemSaveOrderData> itemList = new List<ItemSaveOrderData>();
			StartOfRound.Instance.allItemsList.itemsList.ForEach(delegate(Item item)
			{
				itemList.Add(new ItemSaveOrderData
				{
					itemId = item.itemId,
					itemName = item.itemName,
					assetName = ((Object)item).name
				});
			});
			if (ES3.KeyExists("ZehsScrapLibAllItemsList", GameNetworkManager.Instance.currentSaveFileName))
			{
				itemList = ES3.Load<List<ItemSaveOrderData>>("ZehsScrapLibAllItemsList", GameNetworkManager.Instance.currentSaveFileName);
			}
			List<Item> itemsList = StartOfRound.Instance.allItemsList.itemsList;
			List<Item> list = new List<Item>();
			foreach (ItemSaveOrderData item2 in itemList)
			{
				Item val = ((IEnumerable<Item>)itemsList).FirstOrDefault((Func<Item, bool>)((Item x) => x.itemId == item2.itemId && x.itemName == item2.itemName && item2.assetName == ((Object)x).name));
				if ((Object)(object)val != (Object)null)
				{
					list.Add(val);
				}
				else
				{
					list.Add(ScriptableObject.CreateInstance<Item>());
				}
			}
			foreach (Item item3 in itemsList)
			{
				if (!list.Contains(item3))
				{
					list.Add(item3);
				}
			}
			StartOfRound.Instance.allItemsList.itemsList = list;
			ES3.Save<List<ItemSaveOrderData>>("ZehsScrapLibAllItemsList", itemList, GameNetworkManager.Instance.currentSaveFileName);
		}

		private static void RegisterZehsScrapLibScrapItemsForAllLevels()
		{
			SelectableLevel[] levels = StartOfRound.Instance.levels;
			foreach (SelectableLevel val in levels)
			{
				if (levelsAlreadyAddedTo.Contains(val))
				{
					continue;
				}
				foreach (ScrapItem scrapItem in scrapItems)
				{
					AddScrapItemToLevel(scrapItem, val);
				}
				levelsAlreadyAddedTo.Add(val);
			}
		}

		private static void AddScrapItemToLevel(ScrapItem scrapItem, SelectableLevel level)
		{
			//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_020a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0214: Expected O, but got Unknown
			string text = ((Object)level).name;
			bool flag = scrapItem.levelRarities.ContainsKey(Levels.LevelTypes.All) || (scrapItem.customLevelRarities != null && scrapItem.customLevelRarities.ContainsKey(text));
			if (scrapItem.levelRarities.ContainsKey(Levels.LevelTypes.Modded) && !Enum.IsDefined(typeof(Levels.LevelTypes), text))
			{
				flag = true;
			}
			Levels.LevelTypes key = Levels.LevelTypes.None;
			bool flag2 = false;
			if (Enum.IsDefined(typeof(Levels.LevelTypes), text))
			{
				key = (Levels.LevelTypes)Enum.Parse(typeof(Levels.LevelTypes), text);
				flag2 = true;
			}
			else
			{
				text = Levels.Compatibility.GetLLLNameOfLevel(text);
			}
			if (!(flag2 || flag))
			{
				return;
			}
			Levels.LevelTypes key2 = (flag ? Levels.LevelTypes.All : ((Levels.LevelTypes)Enum.Parse(typeof(Levels.LevelTypes), text)));
			if (!flag && !scrapItem.levelRarities.ContainsKey(key2))
			{
				return;
			}
			int rarity = 0;
			if (flag2 && scrapItem.levelRarities.ContainsKey(key))
			{
				rarity = scrapItem.levelRarities[key];
			}
			else if (!flag2 && scrapItem.customLevelRarities != null && scrapItem.customLevelRarities.ContainsKey(text))
			{
				rarity = scrapItem.customLevelRarities[text];
			}
			else if (!flag2 && scrapItem.levelRarities.ContainsKey(Levels.LevelTypes.Modded))
			{
				rarity = scrapItem.levelRarities[Levels.LevelTypes.Modded];
			}
			else if (scrapItem.levelRarities.ContainsKey(Levels.LevelTypes.All))
			{
				rarity = scrapItem.levelRarities[Levels.LevelTypes.All];
			}
			SpawnableItemWithRarity item = new SpawnableItemWithRarity
			{
				spawnableItem = scrapItem.item,
				rarity = rarity
			};
			if (!level.spawnableScrap.Any((SpawnableItemWithRarity x) => (Object)(object)x.spawnableItem == (Object)(object)scrapItem.item))
			{
				level.spawnableScrap.Add(item);
				if (Plugin.Instance.ConfigManager.ExtendedLogging)
				{
					Plugin.logger.LogInfo((object)("To " + text + " added " + ((Object)scrapItem.item).name));
				}
			}
		}

		private static void RegisterScrapAsItem(StartOfRound startOfRound)
		{
			foreach (ScrapItem scrapItem in scrapItems)
			{
				if (startOfRound.allItemsList.itemsList.Contains(scrapItem.item))
				{
					continue;
				}
				if (Plugin.Instance.ConfigManager.ExtendedLogging)
				{
					if (scrapItem.modName != "ZehsScrapLib")
					{
						Plugin.logger.LogInfo((object)(scrapItem.modName + " registered scrap item: " + scrapItem.item.itemName));
					}
					else
					{
						Plugin.logger.LogInfo((object)("Registered scrap item: " + scrapItem.item.itemName));
					}
				}
				ZehsScrapLibItemList.Add(scrapItem.item);
				startOfRound.allItemsList.itemsList.Add(scrapItem.item);
			}
		}

		private static void Terminal_Awake(Terminal self)
		{
			StartOfRound instance = StartOfRound.Instance;
			RegisterZehsScrapLibScrapItemsForAllLevels();
			RegisterScrapAsItem(instance);
			foreach (PlainItem plainItem in plainItems)
			{
				if (instance.allItemsList.itemsList.Contains(plainItem.item))
				{
					continue;
				}
				if (Plugin.Instance.ConfigManager.ExtendedLogging)
				{
					if (plainItem.modName != "ZehsScrapLib")
					{
						Plugin.logger.LogInfo((object)(plainItem.modName + " registered item: " + plainItem.item.itemName));
					}
					else
					{
						Plugin.logger.LogInfo((object)("Registered item: " + plainItem.item.itemName));
					}
				}
				ZehsScrapLibItemList.Add(plainItem.item);
				instance.allItemsList.itemsList.Add(plainItem.item);
			}
		}

		public static void RegisterScrap(Item spawnableItem, int rarity, Levels.LevelTypes levelFlags)
		{
			ScrapItem scrapItem = scrapItems.FirstOrDefault((ScrapItem x) => (Object)(object)x.origItem == (Object)(object)spawnableItem || (Object)(object)x.item == (Object)(object)spawnableItem);
			if (scrapItem != null)
			{
				if (levelFlags != Levels.LevelTypes.None)
				{
					scrapItem.levelRarities.Add(levelFlags, rarity);
				}
			}
			else
			{
				scrapItem = new ScrapItem(spawnableItem, rarity, levelFlags);
				Assembly callingAssembly = Assembly.GetCallingAssembly();
				string name = callingAssembly.GetName().Name;
				scrapItem.modName = name;
				scrapItems.Add(scrapItem);
			}
		}

		public static void RegisterScrap(Item spawnableItem, int rarity, Levels.LevelTypes levelFlags = Levels.LevelTypes.None, string[] levelOverrides = null)
		{
			ScrapItem scrapItem = scrapItems.FirstOrDefault((ScrapItem x) => (Object)(object)x.origItem == (Object)(object)spawnableItem || (Object)(object)x.item == (Object)(object)spawnableItem);
			if (scrapItem != null)
			{
				if (levelFlags != Levels.LevelTypes.None)
				{
					scrapItem.levelRarities.Add(levelFlags, rarity);
				}
				if (levelOverrides != null)
				{
					foreach (string levelName in levelOverrides)
					{
						scrapItem.customLevelRarities.Add(Levels.Compatibility.GetLLLNameOfLevel(levelName), rarity);
					}
				}
			}
			else
			{
				scrapItem = new ScrapItem(spawnableItem, rarity, levelFlags, levelOverrides);
				Assembly callingAssembly = Assembly.GetCallingAssembly();
				string name = callingAssembly.GetName().Name;
				scrapItem.modName = name;
				scrapItems.Add(scrapItem);
			}
		}

		public static void RegisterScrap(Item spawnableItem, Dictionary<Levels.LevelTypes, int>? levelRarities = null, Dictionary<string, int>? customLevelRarities = null)
		{
			ScrapItem scrapItem = scrapItems.FirstOrDefault((ScrapItem x) => (Object)(object)x.origItem == (Object)(object)spawnableItem || (Object)(object)x.item == (Object)(object)spawnableItem);
			if (scrapItem != null)
			{
				if (levelRarities != null)
				{
					foreach (KeyValuePair<Levels.LevelTypes, int> levelRarity in levelRarities)
					{
						scrapItem.levelRarities.Add(levelRarity.Key, levelRarity.Value);
					}
				}
				if (customLevelRarities == null)
				{
					return;
				}
				{
					foreach (KeyValuePair<string, int> customLevelRarity in customLevelRarities)
					{
						scrapItem.customLevelRarities.Add(Levels.Compatibility.GetLLLNameOfLevel(customLevelRarity.Key), customLevelRarity.Value);
					}
					return;
				}
			}
			scrapItem = new ScrapItem(spawnableItem, levelRarities, customLevelRarities);
			Assembly callingAssembly = Assembly.GetCallingAssembly();
			string name = callingAssembly.GetName().Name;
			scrapItem.modName = name;
			scrapItems.Add(scrapItem);
		}

		public static void RegisterItem(Item plainItem)
		{
			PlainItem plainItem2 = new PlainItem(plainItem);
			Assembly callingAssembly = Assembly.GetCallingAssembly();
			string name = callingAssembly.GetName().Name;
			plainItem2.modName = name;
			plainItems.Add(plainItem2);
		}

		public static void RemoveScrapFromLevels(Item scrapItem, Levels.LevelTypes levelFlags = Levels.LevelTypes.None, string[] levelOverrides = null)
		{
			if (!((Object)(object)StartOfRound.Instance != (Object)null))
			{
				return;
			}
			SelectableLevel[] levels = StartOfRound.Instance.levels;
			foreach (SelectableLevel val in levels)
			{
				string name = ((Object)val).name;
				if (!Enum.IsDefined(typeof(Levels.LevelTypes), name))
				{
					name = Levels.Compatibility.GetLLLNameOfLevel(name);
				}
				bool flag = levelFlags.HasFlag(Levels.LevelTypes.All) || (levelOverrides?.Any((string item) => Levels.Compatibility.GetLLLNameOfLevel(item).ToLowerInvariant() == name.ToLowerInvariant()) ?? false);
				if (levelFlags.HasFlag(Levels.LevelTypes.Modded) && !Enum.IsDefined(typeof(Levels.LevelTypes), name))
				{
					flag = true;
				}
				if (!(Enum.IsDefined(typeof(Levels.LevelTypes), name) || flag))
				{
					continue;
				}
				Levels.LevelTypes levelTypes = (flag ? Levels.LevelTypes.All : ((Levels.LevelTypes)Enum.Parse(typeof(Levels.LevelTypes), name)));
				if (!flag && !levelFlags.HasFlag(levelTypes))
				{
					continue;
				}
				ScrapItem actualItem = scrapItems.FirstOrDefault((ScrapItem x) => (Object)(object)x.origItem == (Object)(object)scrapItem || (Object)(object)x.item == (Object)(object)scrapItem);
				SpawnableItemWithRarity val2 = ((IEnumerable<SpawnableItemWithRarity>)val.spawnableScrap).FirstOrDefault((Func<SpawnableItemWithRarity, bool>)((SpawnableItemWithRarity x) => (Object)(object)x.spawnableItem == (Object)(object)actualItem.item));
				if (val2 != null)
				{
					if (Plugin.Instance.ConfigManager.ExtendedLogging)
					{
						Plugin.logger.LogInfo((object)("Removed Item " + ((Object)val2.spawnableItem).name + " from Level " + name));
					}
					val.spawnableScrap.Remove(val2);
				}
			}
		}
	}
	public class Levels
	{
		[Flags]
		public enum LevelTypes
		{
			None = 1,
			ExperimentationLevel = 4,
			AssuranceLevel = 8,
			VowLevel = 0x10,
			OffenseLevel = 0x20,
			MarchLevel = 0x40,
			RendLevel = 0x80,
			DineLevel = 0x100,
			TitanLevel = 0x200,
			Vanilla = 0x3FC,
			Modded = 0x400,
			All = -1
		}

		internal static class Compatibility
		{
			private const string illegalCharacters = ".,?!@#$%^&*()_+-=';:'\"";

			private static string GetNumberlessPlanetName(string planetName)
			{
				if (planetName != null)
				{
					return new string(planetName.SkipWhile((char c) => !char.IsLetter(c)).ToArray());
				}
				return string.Empty;
			}

			private static string StripSpecialCharacters(string input)
			{
				string text = string.Empty;
				for (int i = 0; i < input.Length; i++)
				{
					char c = input[i];
					if ((!".,?!@#$%^&*()_+-=';:'\"".ToCharArray().Contains(c) && char.IsLetterOrDigit(c)) || c.ToString() == " ")
					{
						text += c;
					}
				}
				return text;
			}

			internal static string GetLLLNameOfLevel(string levelName)
			{
				string text = StripSpecialCharacters(GetNumberlessPlanetName(levelName));
				if (!text.EndsWith("Level"))
				{
					text += "Level";
				}
				return text;
			}

			internal static Dictionary<string, int> LLLifyLevelRarityDictionary(Dictionary<string, int> keyValuePairs)
			{
				Dictionary<string, int> dictionary = new Dictionary<string, int>();
				List<string> list = keyValuePairs.Keys.ToList();
				List<int> list2 = keyValuePairs.Values.ToList();
				for (int i = 0; i < keyValuePairs.Count; i++)
				{
					dictionary.Add(GetLLLNameOfLevel(list[i]), list2[i]);
				}
				return dictionary;
			}
		}
	}
	public class NetworkPrefabs
	{
		private static List<GameObject> _networkPrefabs = new List<GameObject>();

		internal static void Init()
		{
			On.GameNetworkManager_Start_Postfix = (Action<GameNetworkManager>)Delegate.Combine(On.GameNetworkManager_Start_Postfix, new Action<GameNetworkManager>(GameNetworkManager_Start));
		}

		public static void RegisterNetworkPrefab(GameObject prefab)
		{
			if (prefab == null)
			{
				throw new ArgumentNullException("prefab", "The given argument for RegisterNetworkPrefab is null!");
			}
			if (!_networkPrefabs.Contains(prefab))
			{
				_networkPrefabs.Add(prefab);
			}
		}

		public static GameObject CreateNetworkPrefab(string name)
		{
			GameObject val = PrefabUtils.CreatePrefab(name);
			val.AddComponent<NetworkObject>();
			byte[] value = MD5.Create().ComputeHash(Encoding.UTF8.GetBytes(Assembly.GetCallingAssembly().GetName().Name + name));
			NetworkObject component = val.GetComponent<NetworkObject>();
			component.SetFieldValue("GlobalObjectIdHash", BitConverter.ToUInt32(value, 0));
			RegisterNetworkPrefab(val);
			return val;
		}

		public static GameObject CloneNetworkPrefab(GameObject prefabToClone, string newName = null)
		{
			GameObject val = PrefabUtils.ClonePrefab(prefabToClone, newName);
			byte[] value = MD5.Create().ComputeHash(Encoding.UTF8.GetBytes(Assembly.GetCallingAssembly().GetName().Name + ((Object)val).name));
			NetworkObject component = val.GetComponent<NetworkObject>();
			component.SetFieldValue("GlobalObjectIdHash", BitConverter.ToUInt32(value, 0));
			RegisterNetworkPrefab(val);
			return val;
		}

		private static void GameNetworkManager_Start(GameNetworkManager self)
		{
			foreach (GameObject networkPrefab in _networkPrefabs)
			{
				if (!NetworkManager.Singleton.NetworkConfig.Prefabs.Contains(networkPrefab))
				{
					NetworkManager.Singleton.AddNetworkPrefab(networkPrefab);
				}
			}
		}
	}
	public class PrefabUtils
	{
		internal static Lazy<GameObject> _prefabParent;

		internal static GameObject prefabParent => _prefabParent.Value;

		static PrefabUtils()
		{
			_prefabParent = new Lazy<GameObject>((Func<GameObject>)delegate
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				//IL_000c: Expected O, but got Unknown
				GameObject val = new GameObject("ZehsScrapLibGeneratedPrefabs");
				((Object)val).hideFlags = (HideFlags)61;
				val.SetActive(false);
				return val;
			});
		}

		public static GameObject ClonePrefab(GameObject prefabToClone, string newName = null)
		{
			GameObject val = Object.Instantiate<GameObject>(prefabToClone, prefabParent.transform);
			((Object)val).hideFlags = (HideFlags)61;
			if (newName != null)
			{
				((Object)val).name = newName;
			}
			else
			{
				((Object)val).name = ((Object)prefabToClone).name;
			}
			return val;
		}

		public static GameObject CreatePrefab(string name)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			GameObject val = new GameObject(name);
			((Object)val).hideFlags = (HideFlags)61;
			val.transform.SetParent(prefabParent.transform);
			return val;
		}
	}
	public class Utilities
	{
		public static List<GameObject> prefabsToFix = new List<GameObject>();

		public static List<GameObject> fixedPrefabs = new List<GameObject>();

		public static void Init()
		{
			On.StartOfRound_Start_Prefix = (Action<StartOfRound>)Delegate.Combine(On.StartOfRound_Start_Prefix, new Action<StartOfRound>(StartOfRound_Start));
			On.MenuManager_Start_Postfix = (Action<MenuManager>)Delegate.Combine(On.MenuManager_Start_Postfix, new Action<MenuManager>(MenuManager_Start));
		}

		private static void StartOfRound_Start(StartOfRound self)
		{
			AudioMixer diageticMixer = SoundManager.Instance.diageticMixer;
			if (Plugin.Instance.ConfigManager.ExtendedLogging)
			{
				Plugin.logger.LogInfo((object)("Diagetic mixer is " + ((Object)diageticMixer).name));
			}
			Plugin.logger.LogInfo((object)$"Found {prefabsToFix.Count} prefabs to fix");
			List<GameObject> list = new List<GameObject>();
			for (int num = prefabsToFix.Count - 1; num >= 0; num--)
			{
				GameObject val = prefabsToFix[num];
				AudioSource[] componentsInChildren = val.GetComponentsInChildren<AudioSource>();
				AudioSource[] array = componentsInChildren;
				foreach (AudioSource val2 in array)
				{
					if ((Object)(object)val2.outputAudioMixerGroup == (Object)null || !(((Object)val2.outputAudioMixerGroup.audioMixer).name == "Diagetic"))
					{
						continue;
					}
					AudioMixerGroup val3 = diageticMixer.FindMatchingGroups(((Object)val2.outputAudioMixerGroup).name)[0];
					if ((Object)(object)val3 != (Object)null)
					{
						val2.outputAudioMixerGroup = val3;
						if (Plugin.Instance.ConfigManager.ExtendedLogging)
						{
							Plugin.logger.LogInfo((object)("Set mixer group for " + ((Object)val2).name + " in " + ((Object)val).name + " to Diagetic:" + ((Object)val3).name));
						}
						list.Add(val);
					}
				}
			}
			foreach (GameObject item in list)
			{
				prefabsToFix.Remove(item);
			}
		}

		private static void MenuManager_Start(MenuManager self)
		{
			if ((Object)(object)((Component)self).GetComponent<AudioSource>() == (Object)null)
			{
				return;
			}
			AudioMixer audioMixer = ((Component)self).GetComponent<AudioSource>().outputAudioMixerGroup.audioMixer;
			List<GameObject> list = new List<GameObject>();
			for (int num = prefabsToFix.Count - 1; num >= 0; num--)
			{
				GameObject val = prefabsToFix[num];
				AudioSource[] componentsInChildren = val.GetComponentsInChildren<AudioSource>();
				AudioSource[] array = componentsInChildren;
				foreach (AudioSource val2 in array)
				{
					if ((Object)(object)val2.outputAudioMixerGroup == (Object)null || !(((Object)val2.outputAudioMixerGroup.audioMixer).name == "NonDiagetic"))
					{
						continue;
					}
					AudioMixerGroup val3 = audioMixer.FindMatchingGroups(((Object)val2.outputAudioMixerGroup).name)[0];
					if ((Object)(object)val3 != (Object)null)
					{
						val2.outputAudioMixerGroup = val3;
						if (Plugin.Instance.ConfigManager.ExtendedLogging)
						{
							Plugin.logger.LogInfo((object)("Set mixer group for " + ((Object)val2).name + " in " + ((Object)val).name + " to NonDiagetic:" + ((Object)val3).name));
						}
						list.Add(val);
					}
				}
			}
			foreach (GameObject item in list)
			{
				prefabsToFix.Remove(item);
			}
		}

		public static void FixMixerGroups(GameObject prefab)
		{
			if (!fixedPrefabs.Contains(prefab))
			{
				fixedPrefabs.Add(prefab);
				prefabsToFix.Add(prefab);
			}
		}
	}
}
namespace com.github.zehsteam.ZehsScrapLib.Extras
{
	public static class ScriptableObjectExtension
	{
		public static T Clone<T>(this T scriptableObject) where T : ScriptableObject
		{
			if ((Object)(object)scriptableObject == (Object)null)
			{
				Debug.LogError((object)$"ScriptableObject was null. Returning default {typeof(T)} object.");
				return (T)(object)ScriptableObject.CreateInstance(typeof(T));
			}
			T val = Object.Instantiate<T>(scriptableObject);
			((Object)(object)val).name = ((Object)(object)scriptableObject).name;
			return val;
		}
	}
}