Decompiled source of Valheimv2 Ultimate ModPack v1.1.0

plugins/AReasonToFish.dll

Decompiled a month ago
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Jotunn;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("AReasonToFish")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("AReasonToFish")]
[assembly: AssemblyCopyright("Copyright ©  2021")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("e3243d22-4307-4008-ba36-9f326008cde5")]
[assembly: AssemblyFileVersion("0.0.1.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.1.0")]
namespace AReasonToFish;

[BepInPlugin("com.jotunn.AReasonToFish", "AReasonToFish", "0.0.1")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
internal class JotunnModStub : BaseUnityPlugin
{
	[HarmonyPatch(typeof(FishingFloat), "FixedUpdate")]
	private static class Fishing_Patch
	{
		private static void Prefix(ref float ___m_moveForce, ref float ___m_pullLineSpeed)
		{
			___m_pullLineSpeed = pullLineSpeedMultiplier.Value;
			___m_moveForce = forceMultiplier.Value;
		}
	}

	public const string PluginGUID = "com.jotunn.AReasonToFish";

	public const string PluginName = "AReasonToFish";

	public const string PluginVersion = "0.0.1";

	private AssetBundle AltProgBundle;

	private readonly Harmony harmony = new Harmony("fish.overhaul");

	private static ConfigEntry<float> pullLineSpeedMultiplier;

	private static ConfigEntry<float> forceMultiplier;

	private static GameObject fishingWeight;

	private static GameObject fishRawTroll;

	private static GameObject fishRawCod;

	private static GameObject fishRawTuna;

	private static GameObject fishRawHerring;

	private static GameObject fishRawTetra;

	private static GameObject fishRawGrouper;

	private static GameObject fishRawMagma;

	private static GameObject fishRawSalmon;

	private static GameObject trollFishStew;

	private static GameObject trollFishSkewer;

	private static GameObject meadBatteredCod;

	private static GameObject codTaco;

	private static GameObject tunaSandwitch;

	private static GameObject tunaSalad;

	private static GameObject pickledHerring;

	private static GameObject herringOnion;

	private static GameObject fishpop;

	private void Awake()
	{
		LoadAssets();
		pullLineSpeedMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Modify pull speed", "pullLineSpeedMultiplier", 1.8f, "Speed multiplier");
		forceMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Modify force", "forceMultiplier", 18f, "Force multiplier");
		harmony.PatchAll();
		PrefabManager.OnVanillaPrefabsAvailable += AddItems;
	}

	private void OnDestroy()
	{
		harmony.UnpatchSelf();
	}

	private void LoadAssets()
	{
		AltProgBundle = AssetUtils.LoadAssetBundleFromResources("areasontofish");
		Logger.LogInfo((object)("Embedded resources: " + string.Join(", ", typeof(JotunnModStub).Assembly.GetManifestResourceNames())));
		fishingWeight = AltProgBundle.LoadAsset<GameObject>("FishingWeight");
		fishRawTroll = AltProgBundle.LoadAsset<GameObject>("FishRawTroll");
		fishRawCod = AltProgBundle.LoadAsset<GameObject>("FishRawCod");
		fishRawTuna = AltProgBundle.LoadAsset<GameObject>("FishRawTuna");
		fishRawHerring = AltProgBundle.LoadAsset<GameObject>("FishRawHerring");
		fishRawTetra = AltProgBundle.LoadAsset<GameObject>("FishRawTetra");
		fishRawGrouper = AltProgBundle.LoadAsset<GameObject>("FishRawGrouper");
		fishRawMagma = AltProgBundle.LoadAsset<GameObject>("FishRawMagma");
		fishRawSalmon = AltProgBundle.LoadAsset<GameObject>("FishRawSalmon");
		trollFishStew = AltProgBundle.LoadAsset<GameObject>("TrollFishStew");
		trollFishSkewer = AltProgBundle.LoadAsset<GameObject>("TrollFishSkewer");
		meadBatteredCod = AltProgBundle.LoadAsset<GameObject>("MeadBatteredCod");
		codTaco = AltProgBundle.LoadAsset<GameObject>("FishTaco");
		tunaSandwitch = AltProgBundle.LoadAsset<GameObject>("FishSandwitch");
		tunaSalad = AltProgBundle.LoadAsset<GameObject>("SaladTuna");
		pickledHerring = AltProgBundle.LoadAsset<GameObject>("PickledHerring");
		herringOnion = AltProgBundle.LoadAsset<GameObject>("HerringsandOnions");
		fishpop = AltProgBundle.LoadAsset<GameObject>("FishPop");
	}

	private void AddItems()
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Expected O, but got Unknown
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_003e: Expected O, but got Unknown
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0050: Expected O, but got Unknown
		//IL_0082: Unknown result type (might be due to invalid IL or missing references)
		//IL_0088: Expected O, but got Unknown
		//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bc: Expected O, but got Unknown
		//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c3: Expected O, but got Unknown
		//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ed: Expected O, but got Unknown
		//IL_0181: Unknown result type (might be due to invalid IL or missing references)
		//IL_0188: Expected O, but got Unknown
		//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cc: Expected O, but got Unknown
		//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e1: Expected O, but got Unknown
		//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f5: Expected O, but got Unknown
		//IL_0289: Unknown result type (might be due to invalid IL or missing references)
		//IL_0290: Expected O, but got Unknown
		//IL_02ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d4: Expected O, but got Unknown
		//IL_02df: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e9: Expected O, but got Unknown
		//IL_02f4: Unknown result type (might be due to invalid IL or missing references)
		//IL_02fe: Expected O, but got Unknown
		//IL_030b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0312: Expected O, but got Unknown
		//IL_03a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_03ad: Expected O, but got Unknown
		//IL_03de: Unknown result type (might be due to invalid IL or missing references)
		//IL_03e8: Expected O, but got Unknown
		//IL_03f5: Unknown result type (might be due to invalid IL or missing references)
		//IL_03fc: Expected O, but got Unknown
		//IL_0409: Unknown result type (might be due to invalid IL or missing references)
		//IL_0410: Expected O, but got Unknown
		//IL_0434: Unknown result type (might be due to invalid IL or missing references)
		//IL_043e: Expected O, but got Unknown
		//IL_044a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0454: Expected O, but got Unknown
		//IL_0466: Unknown result type (might be due to invalid IL or missing references)
		//IL_0470: Expected O, but got Unknown
		//IL_0471: Unknown result type (might be due to invalid IL or missing references)
		//IL_0478: Expected O, but got Unknown
		//IL_04b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_04bc: Expected O, but got Unknown
		//IL_04c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_04d0: Expected O, but got Unknown
		//IL_0505: Unknown result type (might be due to invalid IL or missing references)
		//IL_050c: Expected O, but got Unknown
		//IL_0546: Unknown result type (might be due to invalid IL or missing references)
		//IL_0550: Expected O, but got Unknown
		//IL_055d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0564: Expected O, but got Unknown
		//IL_0599: Unknown result type (might be due to invalid IL or missing references)
		//IL_05a0: Expected O, but got Unknown
		//IL_05ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_05d8: Expected O, but got Unknown
		//IL_05d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_05e0: Expected O, but got Unknown
		//IL_060e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0618: Expected O, but got Unknown
		//IL_0619: Unknown result type (might be due to invalid IL or missing references)
		//IL_0620: Expected O, but got Unknown
		//IL_064f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0656: Expected O, but got Unknown
		//IL_06ea: Unknown result type (might be due to invalid IL or missing references)
		//IL_06f1: Expected O, but got Unknown
		//IL_0720: Unknown result type (might be due to invalid IL or missing references)
		//IL_0727: Expected O, but got Unknown
		//IL_07bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_07c2: Expected O, but got Unknown
		//IL_07fc: Unknown result type (might be due to invalid IL or missing references)
		//IL_0806: Expected O, but got Unknown
		//IL_0811: Unknown result type (might be due to invalid IL or missing references)
		//IL_081b: Expected O, but got Unknown
		//IL_0828: Unknown result type (might be due to invalid IL or missing references)
		//IL_082f: Expected O, but got Unknown
		//IL_08c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_08ca: Expected O, but got Unknown
		//IL_0904: Unknown result type (might be due to invalid IL or missing references)
		//IL_090e: Expected O, but got Unknown
		//IL_0919: Unknown result type (might be due to invalid IL or missing references)
		//IL_0923: Expected O, but got Unknown
		//IL_0939: Unknown result type (might be due to invalid IL or missing references)
		//IL_0940: Expected O, but got Unknown
		//IL_09d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_09db: Expected O, but got Unknown
		//IL_0a15: Unknown result type (might be due to invalid IL or missing references)
		//IL_0a1f: Expected O, but got Unknown
		//IL_0a2a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0a34: Expected O, but got Unknown
		//IL_0a3f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0a49: Expected O, but got Unknown
		//IL_0a56: Unknown result type (might be due to invalid IL or missing references)
		//IL_0a5d: Expected O, but got Unknown
		//IL_0af1: Unknown result type (might be due to invalid IL or missing references)
		//IL_0af8: Expected O, but got Unknown
		//IL_0b32: Unknown result type (might be due to invalid IL or missing references)
		//IL_0b3c: Expected O, but got Unknown
		//IL_0b47: Unknown result type (might be due to invalid IL or missing references)
		//IL_0b51: Expected O, but got Unknown
		//IL_0b67: Unknown result type (might be due to invalid IL or missing references)
		//IL_0b6e: Expected O, but got Unknown
		//IL_0c02: Unknown result type (might be due to invalid IL or missing references)
		//IL_0c09: Expected O, but got Unknown
		//IL_0c43: Unknown result type (might be due to invalid IL or missing references)
		//IL_0c4d: Expected O, but got Unknown
		//IL_0c5a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0c61: Expected O, but got Unknown
		//IL_0c96: Unknown result type (might be due to invalid IL or missing references)
		//IL_0c9d: Expected O, but got Unknown
		//IL_0ccb: Unknown result type (might be due to invalid IL or missing references)
		//IL_0cd5: Expected O, but got Unknown
		//IL_0cd6: Unknown result type (might be due to invalid IL or missing references)
		//IL_0cdd: Expected O, but got Unknown
		//IL_0d0c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0d13: Expected O, but got Unknown
		//IL_0da7: Unknown result type (might be due to invalid IL or missing references)
		//IL_0dae: Expected O, but got Unknown
		//IL_0de8: Unknown result type (might be due to invalid IL or missing references)
		//IL_0df2: Expected O, but got Unknown
		//IL_0dfd: Unknown result type (might be due to invalid IL or missing references)
		//IL_0e07: Expected O, but got Unknown
		//IL_0e12: Unknown result type (might be due to invalid IL or missing references)
		//IL_0e1c: Expected O, but got Unknown
		//IL_0e32: Unknown result type (might be due to invalid IL or missing references)
		//IL_0e39: Expected O, but got Unknown
		//IL_0ecd: Unknown result type (might be due to invalid IL or missing references)
		//IL_0ed4: Expected O, but got Unknown
		//IL_0f0e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0f18: Expected O, but got Unknown
		//IL_0f23: Unknown result type (might be due to invalid IL or missing references)
		//IL_0f2d: Expected O, but got Unknown
		//IL_0f38: Unknown result type (might be due to invalid IL or missing references)
		//IL_0f42: Expected O, but got Unknown
		//IL_0f58: Unknown result type (might be due to invalid IL or missing references)
		//IL_0f5f: Expected O, but got Unknown
		//IL_0ff3: Unknown result type (might be due to invalid IL or missing references)
		//IL_0ffa: Expected O, but got Unknown
		//IL_1034: Unknown result type (might be due to invalid IL or missing references)
		//IL_103e: Expected O, but got Unknown
		//IL_104b: Unknown result type (might be due to invalid IL or missing references)
		//IL_1052: Expected O, but got Unknown
		//IL_1087: Unknown result type (might be due to invalid IL or missing references)
		//IL_108e: Expected O, but got Unknown
		//IL_10bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_10c6: Expected O, but got Unknown
		//IL_10c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_10ce: Expected O, but got Unknown
		//IL_10fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_1104: Expected O, but got Unknown
		//IL_1198: Unknown result type (might be due to invalid IL or missing references)
		//IL_119f: Expected O, but got Unknown
		//IL_11d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_11e3: Expected O, but got Unknown
		//IL_11ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_11f8: Expected O, but got Unknown
		//IL_1203: Unknown result type (might be due to invalid IL or missing references)
		//IL_120d: Expected O, but got Unknown
		//IL_1223: Unknown result type (might be due to invalid IL or missing references)
		//IL_122a: Expected O, but got Unknown
		//IL_12be: Unknown result type (might be due to invalid IL or missing references)
		//IL_12c5: Expected O, but got Unknown
		//IL_12ff: Unknown result type (might be due to invalid IL or missing references)
		//IL_1309: Expected O, but got Unknown
		//IL_1316: Unknown result type (might be due to invalid IL or missing references)
		//IL_131d: Expected O, but got Unknown
		//IL_1352: Unknown result type (might be due to invalid IL or missing references)
		//IL_1359: Expected O, but got Unknown
		//IL_1387: Unknown result type (might be due to invalid IL or missing references)
		//IL_1391: Expected O, but got Unknown
		//IL_1392: Unknown result type (might be due to invalid IL or missing references)
		//IL_1399: Expected O, but got Unknown
		//IL_13c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_13cf: Expected O, but got Unknown
		//IL_1463: Unknown result type (might be due to invalid IL or missing references)
		//IL_146a: Expected O, but got Unknown
		//IL_14a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_14ae: Expected O, but got Unknown
		//IL_14bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_14c2: Expected O, but got Unknown
		//IL_14f7: Unknown result type (might be due to invalid IL or missing references)
		//IL_14fe: Expected O, but got Unknown
		//IL_152c: Unknown result type (might be due to invalid IL or missing references)
		//IL_1536: Expected O, but got Unknown
		//IL_1537: Unknown result type (might be due to invalid IL or missing references)
		//IL_153e: Expected O, but got Unknown
		//IL_156d: Unknown result type (might be due to invalid IL or missing references)
		//IL_1574: Expected O, but got Unknown
		//IL_1608: Unknown result type (might be due to invalid IL or missing references)
		//IL_160f: Expected O, but got Unknown
		//IL_1649: Unknown result type (might be due to invalid IL or missing references)
		//IL_1653: Expected O, but got Unknown
		//IL_1660: Unknown result type (might be due to invalid IL or missing references)
		//IL_1667: Expected O, but got Unknown
		//IL_169c: Unknown result type (might be due to invalid IL or missing references)
		//IL_16a3: Expected O, but got Unknown
		//IL_16d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_16db: Expected O, but got Unknown
		//IL_16dc: Unknown result type (might be due to invalid IL or missing references)
		//IL_16e3: Expected O, but got Unknown
		//IL_1712: Unknown result type (might be due to invalid IL or missing references)
		//IL_1719: Expected O, but got Unknown
		ItemConfig val = new ItemConfig();
		val.Name = "Troll Fish Raw";
		val.Description = "Stanky";
		val.CraftingStation = "piece_cauldron";
		val.AddRequirement(new RequirementConfig("Fish5", 1, 0, false));
		CustomItem val2 = new CustomItem("TrollFishRaw", "FishRawTroll", val);
		val2.Recipe.Recipe.m_qualityResultAmountMultiplier = 3f;
		val2.Recipe.Recipe.m_requireOnlyOneIngredient = true;
		ItemManager.Instance.AddItem(val2);
		CookingConversionConfig val3 = new CookingConversionConfig();
		val3.CookTime = 40f;
		((ConversionConfig)val3).FromItem = "TrollFishRaw";
		((ConversionConfig)val3).ToItem = "TrollFishCooked";
		ItemManager.Instance.AddItemConversion(new CustomItemConversion((ConversionConfig)(object)val3));
		ItemConfig val4 = new ItemConfig();
		val4.Name = "Troll Fish Cooked";
		val4.Description = "Cooked troll fish";
		CustomItem val5 = new CustomItem("TrollFishCooked", "FishCooked", val4);
		val5.ItemDrop.m_itemData.m_shared.m_foodRegen = 2f;
		val5.ItemDrop.m_itemData.m_shared.m_food = 50f;
		val5.ItemDrop.m_itemData.m_shared.m_foodStamina = 20f;
		val5.ItemDrop.m_itemData.m_shared.m_foodBurnTime = 1200f;
		val5.ItemDrop.m_itemData.m_shared.m_weight = 0.5f;
		ItemManager.Instance.AddItem(val5);
		ItemConfig val6 = new ItemConfig();
		val6.Name = "Troll Fish Stew";
		val6.Description = "Troll Fish in a stew";
		val6.CraftingStation = "piece_cauldron";
		val6.MinStationLevel = 2;
		val6.AddRequirement(new RequirementConfig("TrollFishRaw", 1, 0, false));
		val6.AddRequirement(new RequirementConfig("Carrot", 1, 0, false));
		CustomItem val7 = new CustomItem("TrollStew", "TrollFishStew", val6);
		val7.ItemDrop.m_itemData.m_shared.m_foodRegen = 2f;
		val7.ItemDrop.m_itemData.m_shared.m_food = 30f;
		val7.ItemDrop.m_itemData.m_shared.m_foodStamina = 55f;
		val7.ItemDrop.m_itemData.m_shared.m_foodBurnTime = 1500f;
		val7.ItemDrop.m_itemData.m_shared.m_weight = 0.5f;
		ItemManager.Instance.AddItem(val7);
		ItemConfig val8 = new ItemConfig();
		val8.Name = "Troll Fish Skewer";
		val8.Description = "Troll Fish on a stick";
		val8.CraftingStation = "piece_cauldron";
		val8.MinStationLevel = 2;
		val8.AddRequirement(new RequirementConfig("TrollFishRaw", 1, 0, false));
		val8.AddRequirement(new RequirementConfig("Turnip", 1, 0, false));
		val8.AddRequirement(new RequirementConfig("Mushroom", 1, 0, false));
		CustomItem val9 = new CustomItem("TrollSkewer", "TrollFishSkewer", val8);
		val9.ItemDrop.m_itemData.m_shared.m_foodRegen = 3f;
		val9.ItemDrop.m_itemData.m_shared.m_food = 60f;
		val9.ItemDrop.m_itemData.m_shared.m_foodStamina = 25f;
		val9.ItemDrop.m_itemData.m_shared.m_foodBurnTime = 1500f;
		val9.ItemDrop.m_itemData.m_shared.m_weight = 0.5f;
		ItemManager.Instance.AddItem(val9);
		ItemConfig val10 = new ItemConfig();
		val10.Name = "Fishing Weights";
		val10.Description = "Adds wieght the end of a line";
		val10.CraftingStation = "forge";
		val10.AddRequirement(new RequirementConfig("Iron", 1, 0, false));
		CustomItem val11 = new CustomItem("FishingWeights", "FishingWeight", val10);
		ItemManager.Instance.AddItem(val11);
		RecipeConfig val12 = new RecipeConfig();
		val12.Item = "FishingBaitOcean";
		val12.CraftingStation = "piece_cauldron";
		val12.AddRequirement(new RequirementConfig("FishingWeights", 1, 0, false));
		val12.AddRequirement(new RequirementConfig("FishingBait", 20, 0, false));
		val12.Amount = 20;
		ItemManager.Instance.AddRecipe(new CustomRecipe(val12));
		ItemConfig val13 = new ItemConfig();
		val13.Name = "Coral Cod Raw";
		val13.Description = "What a catch";
		val13.CraftingStation = "piece_cauldron";
		val13.MinStationLevel = 2;
		val13.AddRequirement(new RequirementConfig("Fish8", 1, 0, false));
		CustomItem val14 = new CustomItem("CoralCodRaw", "FishRawCod", val13);
		val14.Recipe.Recipe.m_qualityResultAmountMultiplier = 3f;
		val14.Recipe.Recipe.m_requireOnlyOneIngredient = true;
		ItemManager.Instance.AddItem(val14);
		ItemConfig val15 = new ItemConfig();
		val15.Name = "Tuna Raw";
		val15.Description = "Chichen of the sea";
		val15.CraftingStation = "piece_cauldron";
		val15.MinStationLevel = 2;
		val15.AddRequirement(new RequirementConfig("Fish3", 1, 0, false));
		CustomItem val16 = new CustomItem("TunaRaw", "FishRawTuna", val15);
		val16.Recipe.Recipe.m_qualityResultAmountMultiplier = 3f;
		val16.Recipe.Recipe.m_requireOnlyOneIngredient = true;
		ItemManager.Instance.AddItem(val16);
		CookingConversionConfig val17 = new CookingConversionConfig();
		val17.CookTime = 40f;
		((ConversionConfig)val17).FromItem = "CoralCodRaw";
		((ConversionConfig)val17).ToItem = "CoralFishCooked";
		ItemManager.Instance.AddItemConversion(new CustomItemConversion((ConversionConfig)(object)val17));
		CookingConversionConfig val18 = new CookingConversionConfig();
		val18.CookTime = 40f;
		((ConversionConfig)val18).FromItem = "TunaRaw";
		((ConversionConfig)val18).ToItem = "TunaFishCooked";
		ItemManager.Instance.AddItemConversion(new CustomItemConversion((ConversionConfig)(object)val18));
		ItemConfig val19 = new ItemConfig();
		val19.Name = "Coral Cod Cooked";
		val19.Description = "Cooked Cod";
		val19.MinStationLevel = 2;
		CustomItem val20 = new CustomItem("CoralFishCooked", "FishCooked", val19);
		val20.ItemDrop.m_itemData.m_shared.m_foodRegen = 2f;
		val20.ItemDrop.m_itemData.m_shared.m_food = 50f;
		val20.ItemDrop.m_itemData.m_shared.m_foodStamina = 10f;
		val20.ItemDrop.m_itemData.m_shared.m_foodBurnTime = 1200f;
		val20.ItemDrop.m_itemData.m_shared.m_weight = 0.5f;
		ItemManager.Instance.AddItem(val20);
		ItemConfig val21 = new ItemConfig();
		val21.Name = "Tuna Cooked";
		val21.Description = "Cooked Tuna fish";
		val21.MinStationLevel = 2;
		CustomItem val22 = new CustomItem("TunaFishCooked", "FishCooked", val21);
		val22.ItemDrop.m_itemData.m_shared.m_foodRegen = 2f;
		val22.ItemDrop.m_itemData.m_shared.m_food = 55f;
		val22.ItemDrop.m_itemData.m_shared.m_foodStamina = 15f;
		val22.ItemDrop.m_itemData.m_shared.m_foodBurnTime = 1200f;
		val22.ItemDrop.m_itemData.m_shared.m_weight = 0.5f;
		ItemManager.Instance.AddItem(val22);
		ItemConfig val23 = new ItemConfig();
		val23.Name = "Cod Fish Tacos";
		val23.Description = "Fish in a taco";
		val23.CraftingStation = "piece_cauldron";
		val23.MinStationLevel = 3;
		val23.AddRequirement(new RequirementConfig("CoralCodRaw", 1, 0, false));
		val23.AddRequirement(new RequirementConfig("BarleyFlour", 4, 0, false));
		CustomItem val24 = new CustomItem("CodTacos", "FishTaco", val23);
		val24.ItemDrop.m_itemData.m_shared.m_foodRegen = 3f;
		val24.ItemDrop.m_itemData.m_shared.m_food = 70f;
		val24.ItemDrop.m_itemData.m_shared.m_foodStamina = 20f;
		val24.ItemDrop.m_itemData.m_shared.m_foodBurnTime = 1800f;
		val24.ItemDrop.m_itemData.m_shared.m_weight = 0.5f;
		ItemManager.Instance.AddItem(val24);
		ItemConfig val25 = new ItemConfig();
		val25.Name = "Mead Battered Cod";
		val25.Description = "Its like bear battered.. but with mead";
		val25.CraftingStation = "piece_cauldron";
		val25.MinStationLevel = 2;
		val25.AddRequirement(new RequirementConfig("CoralCodRaw", 1, 0, false));
		val25.AddRequirement(new RequirementConfig("MeadTasty", 1, 0, false));
		val25.Amount = 1;
		CustomItem val26 = new CustomItem("MeadBCod", "MeadBatteredCod", val25);
		val26.ItemDrop.m_itemData.m_shared.m_foodRegen = 3f;
		val26.ItemDrop.m_itemData.m_shared.m_food = 65f;
		val26.ItemDrop.m_itemData.m_shared.m_foodStamina = 15f;
		val26.ItemDrop.m_itemData.m_shared.m_foodBurnTime = 1500f;
		val26.ItemDrop.m_itemData.m_shared.m_weight = 0.5f;
		ItemManager.Instance.AddItem(val26);
		ItemConfig val27 = new ItemConfig();
		val27.Name = "Tuna Sandwitch";
		val27.Description = "Not sure what a sandwitch is";
		val27.CraftingStation = "piece_cauldron";
		val27.MinStationLevel = 3;
		val27.AddRequirement(new RequirementConfig("TunaSalad", 1, 0, false));
		val27.AddRequirement(new RequirementConfig("Dandelion", 1, 0, false));
		val27.AddRequirement(new RequirementConfig("Bread", 1, 0, false));
		CustomItem val28 = new CustomItem("TunaSandwitch", "FishSandwitch", val27);
		val28.ItemDrop.m_itemData.m_shared.m_foodRegen = 4f;
		val28.ItemDrop.m_itemData.m_shared.m_food = 75f;
		val28.ItemDrop.m_itemData.m_shared.m_foodStamina = 35f;
		val28.ItemDrop.m_itemData.m_shared.m_foodBurnTime = 1800f;
		val28.ItemDrop.m_itemData.m_shared.m_weight = 0.5f;
		ItemManager.Instance.AddItem(val28);
		ItemConfig val29 = new ItemConfig();
		val29.Name = "Tuna Salad";
		val29.Description = "tuna paste really";
		val29.CraftingStation = "piece_cauldron";
		val29.MinStationLevel = 2;
		val29.AddRequirement(new RequirementConfig("TunaRaw", 1, 0, false));
		val29.AddRequirement(new RequirementConfig("MushroomYellow", 3, 0, false));
		val29.Amount = 1;
		CustomItem val30 = new CustomItem("TunaSalad", "SaladTuna", val29);
		val30.ItemDrop.m_itemData.m_shared.m_foodRegen = 3f;
		val30.ItemDrop.m_itemData.m_shared.m_food = 65f;
		val30.ItemDrop.m_itemData.m_shared.m_foodStamina = 25f;
		val30.ItemDrop.m_itemData.m_shared.m_foodBurnTime = 1500f;
		val30.ItemDrop.m_itemData.m_shared.m_weight = 0.5f;
		ItemManager.Instance.AddItem(val30);
		ItemConfig val31 = new ItemConfig();
		val31.Name = "Herring Raw";
		val31.Description = "Not as big as you thought";
		val31.CraftingStation = "piece_cauldron";
		val31.MinStationLevel = 2;
		val31.AddRequirement(new RequirementConfig("Fish6", 1, 0, false));
		CustomItem val32 = new CustomItem("HerringRaw", "FishRawHerring", val31);
		val32.Recipe.Recipe.m_qualityResultAmountMultiplier = 4f;
		val32.Recipe.Recipe.m_requireOnlyOneIngredient = true;
		ItemManager.Instance.AddItem(val32);
		CookingConversionConfig val33 = new CookingConversionConfig();
		val33.CookTime = 40f;
		((ConversionConfig)val33).FromItem = "HerringRaw";
		((ConversionConfig)val33).ToItem = "HerringCooked";
		ItemManager.Instance.AddItemConversion(new CustomItemConversion((ConversionConfig)(object)val33));
		ItemConfig val34 = new ItemConfig();
		val34.Name = "Herring Cooked";
		val34.Description = "Cooked Herring";
		val34.MinStationLevel = 2;
		CustomItem val35 = new CustomItem("HerringCooked", "FishCooked", val34);
		val35.ItemDrop.m_itemData.m_shared.m_foodRegen = 3f;
		val35.ItemDrop.m_itemData.m_shared.m_food = 50f;
		val35.ItemDrop.m_itemData.m_shared.m_foodStamina = 15f;
		val35.ItemDrop.m_itemData.m_shared.m_foodBurnTime = 1200f;
		val35.ItemDrop.m_itemData.m_shared.m_weight = 0.5f;
		ItemManager.Instance.AddItem(val35);
		ItemConfig val36 = new ItemConfig();
		val36.Name = "Pickled Herring";
		val36.Description = "Smells bad.. and tastes bad";
		val36.CraftingStation = "piece_cauldron";
		val36.MinStationLevel = 2;
		val36.AddRequirement(new RequirementConfig("HerringRaw", 1, 0, false));
		val36.AddRequirement(new RequirementConfig("Thistle", 2, 0, false));
		val36.AddRequirement(new RequirementConfig("Ooze", 2, 0, false));
		val36.Amount = 1;
		CustomItem val37 = new CustomItem("PickledHerrings", "PickledHerring", val36);
		val37.ItemDrop.m_itemData.m_shared.m_foodRegen = 2f;
		val37.ItemDrop.m_itemData.m_shared.m_food = 20f;
		val37.ItemDrop.m_itemData.m_shared.m_foodStamina = 75f;
		val37.ItemDrop.m_itemData.m_shared.m_foodBurnTime = 1800f;
		val37.ItemDrop.m_itemData.m_shared.m_weight = 0.5f;
		ItemManager.Instance.AddItem(val37);
		ItemConfig val38 = new ItemConfig();
		val38.Name = "Herrings and Onions";
		val38.Description = "A classy dish";
		val38.CraftingStation = "piece_cauldron";
		val38.MinStationLevel = 2;
		val38.AddRequirement(new RequirementConfig("HerringRaw", 1, 0, false));
		val38.AddRequirement(new RequirementConfig("Onion", 2, 0, false));
		val38.AddRequirement(new RequirementConfig("Honey", 1, 0, false));
		val38.Amount = 1;
		CustomItem val39 = new CustomItem("HerringOnion", "HerringsandOnions", val38);
		val39.ItemDrop.m_itemData.m_shared.m_foodRegen = 3f;
		val39.ItemDrop.m_itemData.m_shared.m_food = 70f;
		val39.ItemDrop.m_itemData.m_shared.m_foodStamina = 20f;
		val39.ItemDrop.m_itemData.m_shared.m_foodBurnTime = 1500f;
		val39.ItemDrop.m_itemData.m_shared.m_weight = 0.5f;
		ItemManager.Instance.AddItem(val39);
		ItemConfig val40 = new ItemConfig();
		val40.Name = "Tetra Raw";
		val40.Description = "Not as big as you thought";
		val40.CraftingStation = "piece_cauldron";
		val40.MinStationLevel = 2;
		val40.AddRequirement(new RequirementConfig("Fish4_cave", 1, 0, false));
		CustomItem val41 = new CustomItem("TetraRaw", "FishRawTetra", val40);
		val41.Recipe.Recipe.m_qualityResultAmountMultiplier = 4f;
		val41.Recipe.Recipe.m_requireOnlyOneIngredient = true;
		ItemManager.Instance.AddItem(val41);
		CookingConversionConfig val42 = new CookingConversionConfig();
		val42.CookTime = 40f;
		((ConversionConfig)val42).FromItem = "TetraRaw";
		((ConversionConfig)val42).ToItem = "TetraCooked";
		ItemManager.Instance.AddItemConversion(new CustomItemConversion((ConversionConfig)(object)val42));
		ItemConfig val43 = new ItemConfig();
		val43.Name = "Tetra Cooked";
		val43.Description = "Cooked cold Fish";
		val43.MinStationLevel = 2;
		CustomItem val44 = new CustomItem("TetraCooked", "FishCooked", val43);
		val44.ItemDrop.m_itemData.m_shared.m_foodRegen = 2f;
		val44.ItemDrop.m_itemData.m_shared.m_food = 55f;
		val44.ItemDrop.m_itemData.m_shared.m_foodStamina = 15f;
		val44.ItemDrop.m_itemData.m_shared.m_foodBurnTime = 1200f;
		val44.ItemDrop.m_itemData.m_shared.m_weight = 0.5f;
		ItemManager.Instance.AddItem(val44);
		ItemConfig val45 = new ItemConfig();
		val45.Name = "Fish Pop";
		val45.Description = "A tasty treat with a hint of blueberry";
		val45.CraftingStation = "piece_cauldron";
		val45.MinStationLevel = 2;
		val45.AddRequirement(new RequirementConfig("TetraRaw", 1, 0, false));
		val45.AddRequirement(new RequirementConfig("FreezeGland", 1, 0, false));
		val45.AddRequirement(new RequirementConfig("Blueberries", 1, 0, false));
		val45.Amount = 1;
		CustomItem val46 = new CustomItem("Fishpop", "FishPop", val45);
		val46.ItemDrop.m_itemData.m_shared.m_foodRegen = 6f;
		val46.ItemDrop.m_itemData.m_shared.m_food = 30f;
		val46.ItemDrop.m_itemData.m_shared.m_foodStamina = 35f;
		val46.ItemDrop.m_itemData.m_shared.m_foodBurnTime = 1500f;
		val46.ItemDrop.m_itemData.m_shared.m_weight = 0.5f;
		ItemManager.Instance.AddItem(val46);
		ItemConfig val47 = new ItemConfig();
		val47.Name = "Grouper Raw";
		val47.Description = "A grouper of tails";
		val47.CraftingStation = "piece_cauldron";
		val47.MinStationLevel = 2;
		val47.AddRequirement(new RequirementConfig("Fish7", 1, 0, false));
		CustomItem val48 = new CustomItem("GrouperRaw", "FishRawGrouper", val47);
		val48.Recipe.Recipe.m_qualityResultAmountMultiplier = 4f;
		val48.Recipe.Recipe.m_requireOnlyOneIngredient = true;
		ItemManager.Instance.AddItem(val48);
		CookingConversionConfig val49 = new CookingConversionConfig();
		val49.CookTime = 40f;
		((ConversionConfig)val49).FromItem = "GrouperRaw";
		((ConversionConfig)val49).ToItem = "GrouperCooked";
		ItemManager.Instance.AddItemConversion(new CustomItemConversion((ConversionConfig)(object)val49));
		ItemConfig val50 = new ItemConfig();
		val50.Name = "Grouper Cooked";
		val50.Description = "Cooked Grouper";
		val50.MinStationLevel = 2;
		CustomItem val51 = new CustomItem("GrouperCooked", "FishCooked", val50);
		val51.ItemDrop.m_itemData.m_shared.m_foodRegen = 2f;
		val51.ItemDrop.m_itemData.m_shared.m_food = 60f;
		val51.ItemDrop.m_itemData.m_shared.m_foodStamina = 15f;
		val51.ItemDrop.m_itemData.m_shared.m_foodBurnTime = 1200f;
		val51.ItemDrop.m_itemData.m_shared.m_weight = 0.5f;
		ItemManager.Instance.AddItem(val51);
		ItemConfig val52 = new ItemConfig();
		val52.Name = "Magmafish Raw";
		val52.Description = "It might be hot but cook it anyway";
		val52.CraftingStation = "piece_cauldron";
		val52.MinStationLevel = 2;
		val52.AddRequirement(new RequirementConfig("Fish11", 1, 0, false));
		CustomItem val53 = new CustomItem("MagmaRaw", "FishRawMagma", val52);
		val53.Recipe.Recipe.m_qualityResultAmountMultiplier = 4f;
		val53.Recipe.Recipe.m_requireOnlyOneIngredient = true;
		ItemManager.Instance.AddItem(val53);
		CookingConversionConfig val54 = new CookingConversionConfig();
		val54.CookTime = 40f;
		((ConversionConfig)val54).FromItem = "MagmaRaw";
		((ConversionConfig)val54).ToItem = "MagmaCooked";
		ItemManager.Instance.AddItemConversion(new CustomItemConversion((ConversionConfig)(object)val54));
		ItemConfig val55 = new ItemConfig();
		val55.Name = "Magmafish Cooked";
		val55.Description = "Cooked Magmafish";
		val55.MinStationLevel = 2;
		CustomItem val56 = new CustomItem("MagmaCooked", "FishCooked", val55);
		val56.ItemDrop.m_itemData.m_shared.m_foodRegen = 2f;
		val56.ItemDrop.m_itemData.m_shared.m_food = 60f;
		val56.ItemDrop.m_itemData.m_shared.m_foodStamina = 15f;
		val56.ItemDrop.m_itemData.m_shared.m_foodBurnTime = 1200f;
		val56.ItemDrop.m_itemData.m_shared.m_weight = 0.5f;
		ItemManager.Instance.AddItem(val56);
		ItemConfig val57 = new ItemConfig();
		val57.Name = "Northern Salmon Raw";
		val57.Description = "The coolest fish in the world";
		val57.CraftingStation = "piece_cauldron";
		val57.MinStationLevel = 2;
		val57.AddRequirement(new RequirementConfig("Fish10", 1, 0, false));
		CustomItem val58 = new CustomItem("SalmonRaw", "FishRawSalmon", val57);
		val58.Recipe.Recipe.m_qualityResultAmountMultiplier = 4f;
		val58.Recipe.Recipe.m_requireOnlyOneIngredient = true;
		ItemManager.Instance.AddItem(val58);
		CookingConversionConfig val59 = new CookingConversionConfig();
		val59.CookTime = 40f;
		((ConversionConfig)val59).FromItem = "SalmonRaw";
		((ConversionConfig)val59).ToItem = "SalmonCooked";
		ItemManager.Instance.AddItemConversion(new CustomItemConversion((ConversionConfig)(object)val59));
		ItemConfig val60 = new ItemConfig();
		val60.Name = "Northern Salmon Cooked";
		val60.Description = "Cooked Northern Salmon";
		val60.MinStationLevel = 2;
		CustomItem val61 = new CustomItem("SalmonCooked", "FishCooked", val60);
		val61.ItemDrop.m_itemData.m_shared.m_foodRegen = 2f;
		val61.ItemDrop.m_itemData.m_shared.m_food = 60f;
		val61.ItemDrop.m_itemData.m_shared.m_foodStamina = 15f;
		val61.ItemDrop.m_itemData.m_shared.m_foodBurnTime = 1200f;
		val61.ItemDrop.m_itemData.m_shared.m_weight = 0.5f;
		ItemManager.Instance.AddItem(val61);
		PrefabManager.OnVanillaPrefabsAvailable -= AddItems;
	}
}

plugins/CustomAudio.dll

Decompiled a month ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using TMPro;
using UnityEngine;
using UnityEngine.Networking;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+dbf6b255fa95639255e752ae11063f3acb851646")]
[assembly: AssemblyVersion("1.0.0.0")]
public static class SavWav
{
	private const int HEADER_SIZE = 44;

	public static bool Save(string filename, AudioClip clip)
	{
		if (!filename.ToLower().EndsWith(".wav"))
		{
			filename += ".wav";
		}
		string text = Path.Combine(Application.persistentDataPath, filename);
		Debug.Log((object)text);
		Directory.CreateDirectory(Path.GetDirectoryName(text));
		using (FileStream fileStream = CreateEmpty(text))
		{
			ConvertAndWrite(fileStream, clip);
			WriteHeader(fileStream, clip);
		}
		return true;
	}

	public static AudioClip TrimSilence(AudioClip clip, float min)
	{
		float[] array = new float[clip.samples];
		clip.GetData(array, 0);
		return TrimSilence(new List<float>(array), min, clip.channels, clip.frequency);
	}

	public static AudioClip TrimSilence(List<float> samples, float min, int channels, int hz)
	{
		return TrimSilence(samples, min, channels, hz, _3D: false, stream: false);
	}

	public static AudioClip TrimSilence(List<float> samples, float min, int channels, int hz, bool _3D, bool stream)
	{
		int i;
		for (i = 0; i < samples.Count && !(Mathf.Abs(samples[i]) > min); i++)
		{
		}
		samples.RemoveRange(0, i);
		i = samples.Count - 1;
		while (i > 0 && !(Mathf.Abs(samples[i]) > min))
		{
			i--;
		}
		samples.RemoveRange(i, samples.Count - i);
		AudioClip obj = AudioClip.Create("TempClip", samples.Count, channels, hz, _3D, stream);
		obj.SetData(samples.ToArray(), 0);
		return obj;
	}

	private static FileStream CreateEmpty(string filepath)
	{
		FileStream fileStream = new FileStream(filepath, FileMode.Create);
		byte value = 0;
		for (int i = 0; i < 44; i++)
		{
			fileStream.WriteByte(value);
		}
		return fileStream;
	}

	private static void ConvertAndWrite(FileStream fileStream, AudioClip clip)
	{
		float[] array = new float[clip.samples];
		clip.GetData(array, 0);
		short[] array2 = new short[array.Length];
		byte[] array3 = new byte[array.Length * 2];
		int num = 32767;
		for (int i = 0; i < array.Length; i++)
		{
			array2[i] = (short)(array[i] * (float)num);
			_ = new byte[2];
			BitConverter.GetBytes(array2[i]).CopyTo(array3, i * 2);
		}
		fileStream.Write(array3, 0, array3.Length);
	}

	private static void WriteHeader(FileStream fileStream, AudioClip clip)
	{
		int frequency = clip.frequency;
		int channels = clip.channels;
		int samples = clip.samples;
		fileStream.Seek(0L, SeekOrigin.Begin);
		byte[] bytes = Encoding.UTF8.GetBytes("RIFF");
		fileStream.Write(bytes, 0, 4);
		byte[] bytes2 = BitConverter.GetBytes(fileStream.Length - 8);
		fileStream.Write(bytes2, 0, 4);
		byte[] bytes3 = Encoding.UTF8.GetBytes("WAVE");
		fileStream.Write(bytes3, 0, 4);
		byte[] bytes4 = Encoding.UTF8.GetBytes("fmt ");
		fileStream.Write(bytes4, 0, 4);
		byte[] bytes5 = BitConverter.GetBytes(16);
		fileStream.Write(bytes5, 0, 4);
		byte[] bytes6 = BitConverter.GetBytes((ushort)1);
		fileStream.Write(bytes6, 0, 2);
		byte[] bytes7 = BitConverter.GetBytes(channels);
		fileStream.Write(bytes7, 0, 2);
		byte[] bytes8 = BitConverter.GetBytes(frequency);
		fileStream.Write(bytes8, 0, 4);
		byte[] bytes9 = BitConverter.GetBytes(frequency * channels * 2);
		fileStream.Write(bytes9, 0, 4);
		ushort value = (ushort)(channels * 2);
		fileStream.Write(BitConverter.GetBytes(value), 0, 2);
		byte[] bytes10 = BitConverter.GetBytes((ushort)16);
		fileStream.Write(bytes10, 0, 2);
		byte[] bytes11 = Encoding.UTF8.GetBytes("data");
		fileStream.Write(bytes11, 0, 4);
		byte[] bytes12 = BitConverter.GetBytes(samples * channels * 2);
		fileStream.Write(bytes12, 0, 4);
	}
}
namespace CustomAudio;

[BepInPlugin("aedenthorn.CustomAudio", "Custom Audio", "1.5.8")]
public class BepInExPlugin : BaseUnityPlugin
{
	[HarmonyPatch(typeof(ZSFX), "Awake")]
	private static class ZSFX_Awake_Patch
	{
		private static void Postfix(ZSFX __instance)
		{
			if (!modEnabled.Value)
			{
				return;
			}
			string zSFXName = GetZSFXName(__instance);
			if (dumpInfo.Value)
			{
				Dbgl("Checking SFX: " + zSFXName);
			}
			Dictionary<string, Dictionary<string, AudioClip>> customSFXList = BepInExPlugin.customSFXList;
			if (customSFXList != null && customSFXList.TryGetValue(zSFXName, out var value))
			{
				if (dumpInfo.Value)
				{
					Dbgl("replacing SFX list by name: " + zSFXName);
				}
				__instance.m_audioClips = value.Values.ToArray();
			}
			else
			{
				if (customSFX == null || __instance.m_audioClips == null)
				{
					return;
				}
				for (int i = 0; i < __instance.m_audioClips.Length; i++)
				{
					if (__instance.m_audioClips[i] == null)
					{
						continue;
					}
					if (dumpInfo.Value)
					{
						Dbgl("checking SFX: " + zSFXName + ", clip: " + ((Object)__instance.m_audioClips[i]).name);
					}
					if (customSFX.TryGetValue(((Object)__instance.m_audioClips[i]).name, out var value2))
					{
						if (dumpInfo.Value)
						{
							Dbgl("replacing SFX: " + zSFXName + ", clip: " + ((Object)__instance.m_audioClips[i]).name);
						}
						__instance.m_audioClips[i] = value2;
					}
				}
			}
		}
	}

	[HarmonyPatch(typeof(MusicMan), "Awake")]
	private static class MusicMan_Awake_Patch
	{
		private static void Postfix(MusicMan __instance)
		{
			if (!modEnabled.Value)
			{
				return;
			}
			List<string> list = new List<string>();
			for (int i = 0; i < __instance.m_music.Count; i++)
			{
				list.Add("Music list name: " + __instance.m_music[i].m_name);
				for (int j = 0; j < __instance.m_music[i].m_clips.Length; j++)
				{
					if (!Object.op_Implicit((Object)(object)__instance.m_music[i].m_clips[j]))
					{
						continue;
					}
					list.Add("\ttrack name: " + ((Object)__instance.m_music[i].m_clips[j]).name);
					if (customMusic.ContainsKey(((Object)__instance.m_music[i].m_clips[j]).name))
					{
						if (dumpInfo.Value)
						{
							CustomAudioLogger.LogInfo((object)("replacing music: " + __instance.m_music[i].m_name + ", clip: " + ((Object)__instance.m_music[i].m_clips[j]).name));
						}
						__instance.m_music[i].m_clips[j] = customMusic[((Object)__instance.m_music[i].m_clips[j]).name];
					}
				}
				if (customMusicList.ContainsKey(__instance.m_music[i].m_name))
				{
					if (dumpInfo.Value)
					{
						CustomAudioLogger.LogInfo((object)("replacing music list by name: " + __instance.m_music[i].m_name));
					}
					__instance.m_music[i].m_clips = customMusicList[__instance.m_music[i].m_name].Values.ToArray();
				}
			}
			if (dumpInfo.Value)
			{
				CustomAudioLogger.LogInfo((object)string.Join("\n", list));
			}
		}
	}

	[HarmonyPatch(typeof(AudioMan), "Awake")]
	private static class AudioMan_Awake_Patch
	{
		private static void Postfix(AudioMan __instance, List<BiomeAmbients> ___m_randomAmbients, AudioSource ___m_oceanAmbientSource, AudioSource ___m_windLoopSource)
		{
			if (!modEnabled.Value)
			{
				return;
			}
			List<string> list = new List<string>();
			for (int i = 0; i < ___m_randomAmbients.Count; i++)
			{
				list.Add("Ambient list name: " + ___m_randomAmbients[i].m_name);
				list.Add("\tAmbient tracks: (use " + ___m_randomAmbients[i].m_name + ")");
				for (int j = 0; j < ___m_randomAmbients[i].m_randomAmbientClips.Count; j++)
				{
					list.Add("\t\ttrack name: " + ((Object)___m_randomAmbients[i].m_randomAmbientClips[j]).name);
					if (customAmbient.ContainsKey(((Object)___m_randomAmbients[i].m_randomAmbientClips[j]).name))
					{
						CustomAudioLogger.LogInfo((object)("replacing ambient: " + ___m_randomAmbients[i].m_name + ", clip: " + ((Object)___m_randomAmbients[i].m_randomAmbientClips[j]).name));
						___m_randomAmbients[i].m_randomAmbientClips[j] = customAmbient[((Object)___m_randomAmbients[i].m_randomAmbientClips[j]).name];
					}
				}
				list.Add("\tAmbient day tracks: (use " + ___m_randomAmbients[i].m_name + "_day)");
				for (int k = 0; k < ___m_randomAmbients[i].m_randomAmbientClipsDay.Count; k++)
				{
					if (!((Object)(object)__instance.m_randomAmbients[i].m_randomAmbientClipsDay[k] == (Object)null))
					{
						list.Add("\t\ttrack name: " + ((Object)___m_randomAmbients[i].m_randomAmbientClipsDay[k]).name);
						if (customAmbient.ContainsKey(((Object)___m_randomAmbients[i].m_randomAmbientClipsDay[k]).name))
						{
							CustomAudioLogger.LogInfo((object)("replacing ambient day: " + ___m_randomAmbients[i].m_name + ", clip: " + ((Object)___m_randomAmbients[i].m_randomAmbientClipsDay[k]).name));
							___m_randomAmbients[i].m_randomAmbientClipsDay[k] = customAmbient[((Object)___m_randomAmbients[i].m_randomAmbientClipsDay[k]).name];
						}
					}
				}
				list.Add("\tAmbient night tracks: (use " + ___m_randomAmbients[i].m_name + "_night)");
				for (int l = 0; l < ___m_randomAmbients[i].m_randomAmbientClipsNight.Count; l++)
				{
					if (!((Object)(object)__instance.m_randomAmbients[i].m_randomAmbientClipsNight[l] == (Object)null))
					{
						list.Add("\t\ttrack name: " + ((Object)___m_randomAmbients[i].m_randomAmbientClipsNight[l]).name);
						if (customAmbient.ContainsKey(((Object)___m_randomAmbients[i].m_randomAmbientClipsNight[l]).name))
						{
							CustomAudioLogger.LogInfo((object)("replacing ambient night: " + ___m_randomAmbients[i].m_name + ", clip: " + ((Object)___m_randomAmbients[i].m_randomAmbientClipsNight[l]).name));
							___m_randomAmbients[i].m_randomAmbientClipsNight[l] = customAmbient[((Object)___m_randomAmbients[i].m_randomAmbientClipsNight[l]).name];
						}
					}
				}
				if (customAmbientList.ContainsKey(___m_randomAmbients[i].m_name + "_day"))
				{
					CustomAudioLogger.LogInfo((object)("replacing ambient day list by name: " + ___m_randomAmbients[i].m_name + "_day"));
					___m_randomAmbients[i].m_randomAmbientClipsDay = new List<AudioClip>(customAmbientList[___m_randomAmbients[i].m_name + "_day"].Values.ToList());
				}
				else if (customAmbientList.ContainsKey(___m_randomAmbients[i].m_name + "_night"))
				{
					CustomAudioLogger.LogInfo((object)("replacing ambient night list by name: " + ___m_randomAmbients[i].m_name + "_night"));
					___m_randomAmbients[i].m_randomAmbientClipsNight = new List<AudioClip>(customAmbientList[___m_randomAmbients[i].m_name + "_night"].Values.ToList());
				}
				else if (customAmbientList.ContainsKey(___m_randomAmbients[i].m_name))
				{
					CustomAudioLogger.LogInfo((object)("replacing ambient list by name: " + ___m_randomAmbients[i].m_name));
					___m_randomAmbients[i].m_randomAmbientClips = new List<AudioClip>(customAmbientList[___m_randomAmbients[i].m_name].Values.ToList());
				}
			}
			if (dumpInfo.Value)
			{
				CustomAudioLogger.LogInfo((object)string.Join("\n", list));
			}
			if (customAmbient.ContainsKey("ocean"))
			{
				___m_oceanAmbientSource.clip = customAmbient["ocean"];
			}
			if (customAmbient.ContainsKey("wind"))
			{
				___m_windLoopSource.clip = customAmbient["wind"];
			}
		}
	}

	[HarmonyPatch(typeof(MusicLocation), "Awake")]
	public static class MusicLocation_Awake_Patch
	{
		private static void Postfix(ref AudioSource ___m_audioSource, ref float ___m_baseVolume)
		{
			if (!((Object)(object)___m_audioSource != (Object)null))
			{
				return;
			}
			if (dumpInfo.Value)
			{
				CustomAudioLogger.LogInfo((object)("Loaded m_audioSource: " + ((Object)___m_audioSource).name));
				CustomAudioLogger.LogInfo((object)("       clip name    : " + ((Object)___m_audioSource.clip).name));
				CustomAudioLogger.LogInfo((object)$"       m_baseVolume : {___m_baseVolume}");
			}
			if (customMusic.ContainsKey(((Object)___m_audioSource.clip).name))
			{
				if (dumpInfo.Value)
				{
					CustomAudioLogger.LogInfo((object)("replacing music: " + ((Object)___m_audioSource.clip).name));
				}
				___m_audioSource.clip = customMusic[((Object)___m_audioSource.clip).name];
				___m_baseVolume *= locationVolmult.Value;
			}
		}
	}

	[HarmonyPatch(typeof(MusicMan), "UpdateMusic")]
	private static class UpdateMusic_Patch
	{
		private static NamedMusic lastMusic;

		private static void Prefix(ref NamedMusic ___m_currentMusic, ref NamedMusic ___m_queuedMusic, AudioSource ___m_musicSource)
		{
			if (!modEnabled.Value)
			{
				return;
			}
			if (___m_queuedMusic != null)
			{
				___m_queuedMusic.m_volume = musicVol.Value;
			}
			if ((Object)(object)((___m_musicSource != null) ? ___m_musicSource.clip : null) != (Object)null && lastMusicName != ((Object)___m_musicSource.clip).name)
			{
				if (dumpInfo.Value)
				{
					Dbgl("Switching music from " + lastMusicName + " to " + ((Object)___m_musicSource.clip).name);
				}
				lastMusicName = ((Object)___m_musicSource.clip).name;
			}
			if (___m_queuedMusic == null && !___m_musicSource.isPlaying && PlayerPrefs.GetInt("ContinousMusic", 1) == 1)
			{
				if (lastMusic != null)
				{
					lastMusic.m_lastPlayedTime = 0f;
					___m_queuedMusic = lastMusic;
					lastMusic = null;
				}
				else if (___m_currentMusic != null)
				{
					lastMusic = ___m_currentMusic;
				}
				else
				{
					lastMusic = null;
				}
			}
			else
			{
				lastMusic = null;
			}
			if (___m_musicSource.isPlaying && ___m_queuedMusic != null && ___m_musicSource.loop)
			{
				Dbgl("queued " + ___m_queuedMusic?.m_name + ", setting " + ((Object)___m_musicSource).name + " loop to false");
				___m_musicSource.loop = false;
			}
		}
	}

	[HarmonyPatch(typeof(AudioMan), "QueueAmbientLoop")]
	private static class QueueAmbientLoop_Patch
	{
		private static void Prefix(ref float ___m_queuedAmbientVol, ref float ___m_ambientVol, ref float vol)
		{
			if (modEnabled.Value)
			{
				vol = ambientVol.Value;
				___m_ambientVol = ambientVol.Value;
				___m_queuedAmbientVol = ambientVol.Value;
			}
		}
	}

	[HarmonyPatch(typeof(EnvMan), "Awake")]
	private static class EnvMan_Awake_Patch
	{
		private static void Postfix(EnvMan __instance)
		{
			if (!modEnabled.Value)
			{
				return;
			}
			for (int i = 0; i < __instance.m_environments.Count; i++)
			{
				if (customMusicList.ContainsKey(__instance.m_environments[i].m_name + "Morning"))
				{
					AddMusicList(__instance, i, "Morning");
				}
				if (customMusicList.ContainsKey(__instance.m_environments[i].m_name + "Day"))
				{
					AddMusicList(__instance, i, "Day");
				}
				if (customMusicList.ContainsKey(__instance.m_environments[i].m_name + "Evening"))
				{
					AddMusicList(__instance, i, "Evening");
				}
				if (customMusicList.ContainsKey(__instance.m_environments[i].m_name + "Night"))
				{
					AddMusicList(__instance, i, "Night");
				}
			}
		}
	}

	[HarmonyPatch(typeof(TeleportWorld), "Awake")]
	private static class TeleportWorld_Awake_Patch
	{
		private static void Postfix(TeleportWorld __instance)
		{
			if (modEnabled.Value && customSFX.ContainsKey("portal"))
			{
				AudioSource componentInChildren = ((Component)__instance).GetComponentInChildren<AudioSource>();
				componentInChildren.clip = customSFX["portal"];
				((Component)componentInChildren).gameObject.SetActive(false);
				((Component)componentInChildren).gameObject.SetActive(true);
			}
		}
	}

	[HarmonyPatch(typeof(Fireplace), "Start")]
	private static class Fireplace_Start_Patch
	{
		private static void Postfix(Fireplace __instance)
		{
			if (!modEnabled.Value)
			{
				return;
			}
			if (((Object)__instance).name.Contains("groundtorch") && customSFX.ContainsKey("groundtorch"))
			{
				Dbgl("Replacing ground torch audio");
				__instance.m_enabledObject.GetComponentInChildren<AudioSource>().clip = customSFX["groundtorch"];
			}
			else if (((Object)__instance).name.Contains("walltorch") && customSFX.ContainsKey("walltorch"))
			{
				Dbgl("Replacing walltorch audio");
				GameObject enabledObjectHigh = __instance.m_enabledObjectHigh;
				if (Object.op_Implicit((Object)(object)((enabledObjectHigh != null) ? enabledObjectHigh.GetComponentInChildren<AudioSource>() : null)))
				{
					__instance.m_enabledObjectHigh.GetComponentInChildren<AudioSource>().clip = customSFX["walltorch"];
					return;
				}
				GameObject enabledObject = __instance.m_enabledObject;
				if (Object.op_Implicit((Object)(object)((enabledObject != null) ? enabledObject.GetComponentInChildren<AudioSource>() : null)))
				{
					__instance.m_enabledObject.GetComponentInChildren<AudioSource>().clip = customSFX["walltorch"];
				}
			}
			else if (((Object)__instance).name.Contains("fire_pit") && customSFX.ContainsKey("fire_pit"))
			{
				Dbgl("Replacing fire_pit audio");
				__instance.m_enabledObjectHigh.GetComponentInChildren<AudioSource>().clip = customSFX["fire_pit"];
			}
			else if (((Object)__instance).name.Contains("bonfire") && customSFX.ContainsKey("bonfire"))
			{
				Dbgl("Replacing bonfire audio");
				__instance.m_enabledObjectHigh.GetComponentInChildren<AudioSource>().clip = customSFX["bonfire"];
			}
			else if (((Object)__instance).name.Contains("hearth") && customSFX.ContainsKey("hearth"))
			{
				Dbgl("Replacing hearth audio");
				__instance.m_enabledObjectHigh.GetComponentInChildren<AudioSource>().clip = customSFX["hearth"];
			}
		}
	}

	[HarmonyPatch(typeof(Terminal), "InputText")]
	private static class InputText_Patch
	{
		private static bool Prefix(Terminal __instance)
		{
			if (!modEnabled.Value)
			{
				return true;
			}
			string text = ((TMP_InputField)__instance.m_input).text;
			if (text.ToLower().Equals(typeof(BepInExPlugin).Namespace.ToLower() + " reset"))
			{
				((BaseUnityPlugin)context).Config.Reload();
				((BaseUnityPlugin)context).Config.Save();
				Traverse.Create((object)__instance).Method("AddString", new object[1] { text }).GetValue();
				Traverse.Create((object)__instance).Method("AddString", new object[1] { ((BaseUnityPlugin)context).Info.Metadata.Name + " config reloaded" }).GetValue();
				return false;
			}
			if (text.ToLower().Equals(typeof(BepInExPlugin).Namespace.ToLower() + " music"))
			{
				Traverse.Create((object)__instance).Method("AddString", new object[1] { text }).GetValue();
				if (Object.op_Implicit((Object)(object)EnvMan.instance))
				{
					string name;
					if (Object.op_Implicit((Object)(object)Player.m_localPlayer) && Player.m_localPlayer.IsSafeInHome())
					{
						name = "home";
					}
					else
					{
						name = EnvMan.instance.GetAmbientMusic();
					}
					Dbgl("Current environment: " + EnvMan.instance.GetCurrentEnvironment().m_name);
					Dbgl("Current music list: " + name + " " + ((IEnumerable<NamedMusic>)MusicMan.instance.m_music).FirstOrDefault((Func<NamedMusic, bool>)((NamedMusic m) => m.m_name == name))?.m_clips.Length);
				}
				Dbgl("Vanilla music list names:\n" + string.Join("\n", MusicMan.instance.m_music.Select((NamedMusic m) => m.m_name)));
				if (Object.op_Implicit((Object)(object)EnvMan.instance))
				{
					List<string> list = new List<string>();
					for (int i = 0; i < EnvMan.instance.m_environments.Count; i++)
					{
						list.Add(EnvMan.instance.m_environments[i].m_name + "Morning");
						list.Add(EnvMan.instance.m_environments[i].m_name + "Day");
						list.Add(EnvMan.instance.m_environments[i].m_name + "Evening");
						list.Add(EnvMan.instance.m_environments[i].m_name + "Night");
					}
					Dbgl("Possible music list names:\n" + string.Join("\n", list));
				}
				Traverse.Create((object)__instance).Method("AddString", new object[1] { ((BaseUnityPlugin)context).Info.Metadata.Name + " dumped music names" }).GetValue();
				return false;
			}
			if (text.ToLower().Equals(typeof(BepInExPlugin).Namespace.ToLower() + " env"))
			{
				Traverse.Create((object)__instance).Method("AddString", new object[1] { text }).GetValue();
				if (!Object.op_Implicit((Object)(object)EnvMan.instance))
				{
					Traverse.Create((object)__instance).Method("AddString", new object[1] { "Must be called in-game" }).GetValue();
				}
				Dbgl("Current environment: " + EnvMan.instance.GetCurrentEnvironment().m_name);
				return false;
			}
			return true;
		}
	}

	public static ConfigEntry<bool> isDebug;

	public static ConfigEntry<bool> modEnabled;

	public static ConfigEntry<bool> dumpInfo;

	public static ConfigEntry<float> musicVol;

	public static ConfigEntry<float> ambientVol;

	public static ConfigEntry<float> locationVolmult;

	internal const string ModName = "Custom Audio";

	public static Dictionary<string, AudioClip> customMusic = new Dictionary<string, AudioClip>();

	public static Dictionary<string, Dictionary<string, AudioClip>> customMusicList = new Dictionary<string, Dictionary<string, AudioClip>>();

	public static Dictionary<string, AudioClip> customAmbient = new Dictionary<string, AudioClip>();

	public static Dictionary<string, Dictionary<string, AudioClip>> customAmbientList = new Dictionary<string, Dictionary<string, AudioClip>>();

	public static Dictionary<string, AudioClip> customSFX = new Dictionary<string, AudioClip>();

	public static Dictionary<string, Dictionary<string, AudioClip>> customSFXList = new Dictionary<string, Dictionary<string, AudioClip>>();

	public static readonly ManualLogSource CustomAudioLogger = Logger.CreateLogSource("Custom Audio");

	private static string lastMusicName = "";

	private static BepInExPlugin context;

	public static void Dbgl(string str = "", bool pref = true)
	{
		if (isDebug.Value)
		{
			CustomAudioLogger.LogInfo((object)((pref ? (typeof(BepInExPlugin).Namespace + " ") : "") + str));
		}
	}

	private void Awake()
	{
		context = this;
		modEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Enable this mod");
		isDebug = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "IsDebug", false, "Show debug log messages in the console");
		dumpInfo = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "DumpInfo", false, "Dump audio info to the console");
		musicVol = ((BaseUnityPlugin)this).Config.Bind<float>("General", "MusicVol", 0.6f, "Music volume, 0.0 - 1.0");
		locationVolmult = ((BaseUnityPlugin)this).Config.Bind<float>("General", "LocationVol", 5f, "Location music volume multiplier");
		ambientVol = ((BaseUnityPlugin)this).Config.Bind<float>("General", "AmbientVol", 0.3f, "Ambient volume");
		if (modEnabled.Value)
		{
			PreloadAudioClips();
			Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), (string)null);
		}
	}

	public void PreloadAudioClips()
	{
		if (dumpInfo.Value)
		{
			CustomAudioLogger.LogInfo((object)"Preloading audio clips.");
		}
		string text = Path.Combine(Paths.PluginPath, "CustomAudio");
		if (Directory.Exists(text))
		{
			customMusic.Clear();
			customAmbient.Clear();
			customSFX.Clear();
			customMusicList.Clear();
			customAmbientList.Clear();
			customSFXList.Clear();
			if (Directory.Exists(Path.Combine(text, "Music")))
			{
				CollectAudioFiles(Path.Combine(text, "Music"), customMusic, customMusicList);
			}
			else
			{
				Directory.CreateDirectory(Path.Combine(text, "Music"));
			}
			if (Directory.Exists(Path.Combine(text, "SFX")))
			{
				CollectAudioFiles(Path.Combine(text, "SFX"), customSFX, customSFXList);
			}
			else
			{
				Directory.CreateDirectory(Path.Combine(text, "SFX"));
			}
			if (Directory.Exists(Path.Combine(text, "Ambient")))
			{
				CollectAudioFiles(Path.Combine(text, "Ambient"), customAmbient, customAmbientList);
			}
			else
			{
				Directory.CreateDirectory(Path.Combine(text, "Ambient"));
			}
		}
		else
		{
			CustomAudioLogger.LogInfo((object)("Directory " + text + " does not exist! Creating."));
			Directory.CreateDirectory(text);
			Directory.CreateDirectory(Path.Combine(text, "Ambient"));
			Directory.CreateDirectory(Path.Combine(text, "Music"));
			Directory.CreateDirectory(Path.Combine(text, "SFX"));
		}
		string[] directories = Directory.GetDirectories(Paths.PluginPath, "*", SearchOption.AllDirectories);
		for (int i = 0; i < directories.Length; i++)
		{
			string text2 = Path.Combine(directories[i], "CustomAudio");
			if (Directory.Exists(text2))
			{
				string path = Path.Combine(text2, "Music");
				if (Directory.Exists(path))
				{
					CollectAudioFiles(path, customMusic, customMusicList);
				}
				string path2 = Path.Combine(text2, "Ambient");
				if (Directory.Exists(path2))
				{
					CollectAudioFiles(path2, customAmbient, customAmbientList);
				}
				string path3 = Path.Combine(text2, "SFX");
				if (Directory.Exists(path3))
				{
					CollectAudioFiles(path3, customSFX, customSFXList);
				}
			}
		}
	}

	public void CollectAudioFiles(string path, Dictionary<string, AudioClip> customDict, Dictionary<string, Dictionary<string, AudioClip>> customDictDict)
	{
		Dbgl("checking folder " + Path.GetFileName(path));
		string[] files = Directory.GetFiles(path);
		foreach (string path2 in files)
		{
			PreloadClipCoroutine(path2, (AudioType)0, customDict);
		}
		files = Directory.GetDirectories(path);
		foreach (string path3 in files)
		{
			string fileName = Path.GetFileName(path3);
			string[] files2 = Directory.GetFiles(path3);
			customDictDict[fileName] = new Dictionary<string, AudioClip>();
			string[] array = files2;
			foreach (string path4 in array)
			{
				PreloadClipCoroutine(path4, (AudioType)0, customDictDict[fileName]);
			}
		}
		files = Directory.GetDirectories(path);
		foreach (string path5 in files)
		{
			string fileName2 = Path.GetFileName(path5);
			string[] files3 = Directory.GetFiles(path5);
			if (files3.Length == 1 && files3[0].ToLower().EndsWith(".txt") && customDictDict.ContainsKey(Path.GetFileNameWithoutExtension(files3[0])))
			{
				if (dumpInfo.Value)
				{
					CustomAudioLogger.LogInfo((object)("\tlinking music folder " + Path.GetFileName(path5) + " to folder " + Path.GetFileNameWithoutExtension(files3[0])));
				}
				customDictDict[fileName2] = customDictDict[Path.GetFileNameWithoutExtension(files3[0])];
			}
		}
	}

	private void PreloadClipCoroutine(string path, AudioType audioType, Dictionary<string, AudioClip> whichDict)
	{
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_006b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0071: Expected O, but got Unknown
		if (path.EndsWith(".txt") || !path.Contains("."))
		{
			return;
		}
		Dbgl("path: " + path);
		path = "file:///" + path.Replace("\\", "/");
		try
		{
			UnityWebRequest audioClip = UnityWebRequestMultimedia.GetAudioClip(path, audioType);
			audioClip.SendWebRequest();
			while (!audioClip.isDone)
			{
			}
			if (audioClip != null)
			{
				DownloadHandlerAudioClip val = (DownloadHandlerAudioClip)audioClip.downloadHandler;
				if (val != null)
				{
					AudioClip audioClip2 = val.audioClip;
					if ((Object)(object)audioClip2 != (Object)null)
					{
						string text = (((Object)audioClip2).name = Path.GetFileNameWithoutExtension(path));
						if (!whichDict.ContainsKey(text))
						{
							whichDict[text] = audioClip2;
						}
						Dbgl("Added audio clip " + text + " to dict");
					}
					else
					{
						Dbgl("audio clip is null. data: " + ((DownloadHandler)val).text);
					}
				}
				else
				{
					Dbgl("DownloadHandler is null. bytes downloaded: " + audioClip.downloadedBytes);
				}
			}
			else
			{
				Dbgl("www is null " + audioClip.url);
			}
		}
		catch
		{
		}
	}

	public static string GetZSFXName(ZSFX zfx)
	{
		string name = ((Object)zfx).name;
		char[] anyOf = new char[2] { '(', ' ' };
		int num = name.IndexOfAny(anyOf);
		if (num != -1)
		{
			return name.Remove(num);
		}
		return name;
	}

	private static void AddMusicList(EnvMan envMan, int index, string which)
	{
		//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
		//IL_0101: Unknown result type (might be due to invalid IL or missing references)
		//IL_010d: Expected O, but got Unknown
		string text = envMan.m_environments[index].m_name + which;
		Dbgl($"Adding music list by name: {text} ({customMusicList[text].Count})");
		switch (which)
		{
		case "Morning":
			envMan.m_environments[index].m_musicMorning = text;
			break;
		case "Day":
			envMan.m_environments[index].m_musicDay = text;
			break;
		case "Evening":
			envMan.m_environments[index].m_musicEvening = text;
			break;
		case "Night":
			envMan.m_environments[index].m_musicNight = text;
			break;
		}
		MusicMan.instance.m_music.Add(new NamedMusic
		{
			m_name = text,
			m_clips = customMusicList[text].Values.ToArray(),
			m_loop = true,
			m_ambientMusic = true,
			m_resume = true
		});
	}
}
public class UnityWebRequestAwaiter : INotifyCompletion
{
	private UnityWebRequestAsyncOperation asyncOp;

	private Action continuation;

	public bool IsCompleted
	{
		get
		{
			BepInExPlugin.Dbgl("Is completed get");
			return ((AsyncOperation)asyncOp).isDone;
		}
	}

	public UnityWebRequestAwaiter(UnityWebRequestAsyncOperation asyncOp)
	{
		this.asyncOp = asyncOp;
		((AsyncOperation)asyncOp).completed += OnRequestCompleted;
		BepInExPlugin.Dbgl("created asyncop");
	}

	public void GetResult()
	{
		BepInExPlugin.Dbgl("Get Result");
	}

	public void OnCompleted(Action continuation)
	{
		this.continuation = continuation;
		BepInExPlugin.Dbgl("on completed");
	}

	private void OnRequestCompleted(AsyncOperation obj)
	{
		continuation();
		BepInExPlugin.Dbgl("on request completed");
	}
}
public static class ExtensionMethods
{
	public static UnityWebRequestAwaiter GetAwaiter(this UnityWebRequestAsyncOperation asyncOp)
	{
		return new UnityWebRequestAwaiter(asyncOp);
	}
}

plugins/SlayerSkills.dll

Decompiled a month ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
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 BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using HarmonyLib;
using TMPro;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("SlayerSkills")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("SlayerSkills")]
[assembly: AssemblyCopyright("Copyright ©  2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("9f8a1b6e-6d0e-4dab-bbd8-9ed433836544")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
internal sealed class ConfigurationManagerAttributes
{
	public delegate void CustomHotkeyDrawerFunc(ConfigEntryBase setting, ref bool isCurrentlyAcceptingInput);

	public bool? ShowRangeAsPercent;

	public Action<ConfigEntryBase> CustomDrawer;

	public CustomHotkeyDrawerFunc CustomHotkeyDrawer;

	public bool? Browsable;

	public string Category;

	public object DefaultValue;

	public bool? HideDefaultButton;

	public bool? HideSettingName;

	public string Description;

	public string DispName;

	public int? Order;

	public bool? ReadOnly;

	public bool? IsAdvanced;

	public Func<object, string> ObjToStr;

	public Func<string, object> StrToObj;
}
namespace neobotics.ValheimMods;

internal class DebugUtils
{
	public static void ObjectInspector(object o)
	{
		if (o == null)
		{
			Debug.Log((object)"Object is null");
			return;
		}
		BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
		Type type = o.GetType();
		Debug.Log((object)(o.ToString() + " Type " + type.Name));
		PropertyInfo[] properties = type.GetProperties(bindingAttr);
		foreach (PropertyInfo propertyInfo in properties)
		{
			Debug.Log((object)$"{type.Name}.{propertyInfo.Name} = {propertyInfo.GetValue(o)}");
		}
		FieldInfo[] fields = type.GetFields(bindingAttr);
		foreach (FieldInfo field in fields)
		{
			FieldPrinter(o, type, field);
		}
	}

	public static void MethodInspector(object o)
	{
		if (o == null)
		{
			Debug.Log((object)"Object is null");
			return;
		}
		BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
		Type type = o.GetType();
		Debug.Log((object)(o.ToString() + " Type " + type.Name));
		MethodInfo[] methods = type.GetMethods(bindingAttr);
		foreach (MethodInfo methodInfo in methods)
		{
			methodInfo.GetParameters();
			string arg = string.Join(", ", (from x in methodInfo.GetParameters()
				select x.ParameterType?.ToString() + " " + x.Name).ToArray());
			Debug.Log((object)$"{methodInfo.ReturnType} {methodInfo.Name} ({arg})");
		}
	}

	private static void ItemDataInspector(ItemData item)
	{
		ObjectInspector(item);
		ObjectInspector(item.m_shared);
	}

	private static void FieldPrinter(object o, Type t, FieldInfo field)
	{
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Expected O, but got Unknown
		//IL_0077: Unknown result type (might be due to invalid IL or missing references)
		//IL_007d: Expected O, but got Unknown
		//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f3: Expected O, but got Unknown
		try
		{
			if (field.FieldType == typeof(ItemData))
			{
				ItemData val = (ItemData)field.GetValue(o);
				if (val != null)
				{
					ItemDataInspector(val);
				}
				else
				{
					Debug.Log((object)$"{t.Name}.{field.Name} = {field.GetValue(o)} [null]");
				}
			}
			else if (field.FieldType == typeof(Transform))
			{
				Transform val2 = (Transform)field.GetValue(o);
				if ((Object)(object)val2 != (Object)null)
				{
					Debug.Log((object)("\tTransform.parent = " + ((Object)val2.parent).name));
				}
				else
				{
					Debug.Log((object)$"{t.Name}.{field.Name} = {field.GetValue(o)} [null]");
				}
			}
			else if (field.FieldType == typeof(EffectList))
			{
				EffectList val3 = (EffectList)field.GetValue(o);
				if (val3 != null)
				{
					Debug.Log((object)$"{t.Name}.{field.Name} = {field.GetValue(o)}:");
					EffectData[] effectPrefabs = val3.m_effectPrefabs;
					foreach (EffectData val4 in effectPrefabs)
					{
						Debug.Log((object)("\tEffectData.m_prefab = " + ((Object)val4.m_prefab).name));
					}
				}
				else
				{
					Debug.Log((object)$"{t.Name}.{field.Name} = {field.GetValue(o)} [null]");
				}
			}
			else
			{
				Debug.Log((object)$"{t.Name}.{field.Name} = {field.GetValue(o)}");
			}
		}
		catch (Exception)
		{
			Debug.Log((object)("Exception accessing " + t?.Name + "." + field?.Name));
		}
	}

	public static void GameObjectInspector(GameObject go)
	{
		Debug.Log((object)("\n\nInspecting GameObject " + ((Object)go).name));
		ObjectInspector(go);
		Component[] componentsInChildren = go.GetComponentsInChildren<Component>();
		foreach (Component val in componentsInChildren)
		{
			try
			{
				string obj = ((val != null) ? ((Object)val).name : null);
				object obj2;
				if (val == null)
				{
					obj2 = null;
				}
				else
				{
					Transform transform = val.transform;
					if (transform == null)
					{
						obj2 = null;
					}
					else
					{
						Transform parent = transform.parent;
						obj2 = ((parent != null) ? ((Object)parent).name : null);
					}
				}
				Debug.Log((object)("\n\nInspecting Component " + obj + " with parent " + (string?)obj2));
				ObjectInspector(val);
			}
			catch (Exception)
			{
			}
		}
	}

	public static void PrintList<T>(List<T> l)
	{
		foreach (T item in l)
		{
			Debug.Log((object)item.ToString());
		}
	}

	public static void ComponentInspector(Component c)
	{
		Debug.Log((object)("\n\nInspecting Component " + ((Object)c).name));
		ObjectInspector(c);
	}

	public static void EffectsInspector(EffectList e)
	{
		EffectData[] effectPrefabs = e.m_effectPrefabs;
		Debug.Log((object)$"Effect list has effects {e.HasEffects()} count {effectPrefabs.Length}");
		EffectData[] array = effectPrefabs;
		foreach (EffectData val in array)
		{
			Debug.Log((object)$"Effect Data {val} prefab name {((Object)val.m_prefab).name} prefab GameObject name {((Object)val.m_prefab.gameObject).name}");
		}
	}

	public static void PrintInventory()
	{
		foreach (ItemData allItem in ((Humanoid)Player.m_localPlayer).GetInventory().GetAllItems())
		{
			Debug.Log((object)allItem.m_shared.m_name);
		}
	}

	public static void PrintAllObjects()
	{
		ZNetScene.instance.m_prefabs.ForEach(delegate(GameObject x)
		{
			Debug.Log((object)("GameObject " + ((Object)x).name));
		});
	}

	public static void PrintAllCharacters()
	{
		Character.GetAllCharacters().ForEach(delegate(Character x)
		{
			Debug.Log((object)("Character " + ((Object)x).name));
		});
	}

	public static void PrintAllLayers()
	{
		string[] array = (from index in Enumerable.Range(0, 31)
			select LayerMask.LayerToName(index) into l
			where !string.IsNullOrEmpty(l)
			select l).ToArray();
		foreach (string text in array)
		{
			Debug.Log((object)("Layer " + text + " " + Convert.ToString(LayerMask.NameToLayer(text), 2).PadLeft(32, '0')));
		}
	}
}
public class DelegatedConfigEntry<T> : DelegatedConfigEntryBase
{
	private ConfigEntry<T> _entry;

	private EventHandler rootHandler;

	private Action<object, EventArgs> clientDelegate;

	private Logging Log;

	public ConfigEntry<T> ConfigEntry
	{
		get
		{
			return _entry;
		}
		set
		{
			_entry = value;
			if (_entry != null && rootHandler != null)
			{
				_entry.SettingChanged += rootHandler;
			}
			Name = ((ConfigEntryBase)_entry).Definition.Key;
			Section = ((ConfigEntryBase)_entry).Definition.Section;
			ServerValue = ((ConfigEntryBase)_entry).GetSerializedValue();
			Log.Trace("Set " + Section + " " + Name + " to serialized value " + ServerValue);
		}
	}

	public T Value
	{
		get
		{
			return _entry.Value;
		}
		set
		{
			_entry.Value = value;
		}
	}

	public DelegatedConfigEntry(bool useServerDelegate = false)
		: this((Action<object, EventArgs>)null, useServerDelegate)
	{
	}

	public DelegatedConfigEntry(Action<object, EventArgs> delegateHandler, bool useServerDelegate = false)
	{
		Log = Logging.GetLogger();
		Log.Trace("DelegatedConfigEntry");
		if (delegateHandler != null)
		{
			clientDelegate = delegateHandler;
		}
		if (useServerDelegate)
		{
			Log.Trace("Configuring server delegate");
			rootHandler = delegate(object s, EventArgs e)
			{
				ServerDelegate(s, e);
			};
			ServerConfiguration.ServerDelegatedEntries.Add(this);
		}
		else if (clientDelegate != null)
		{
			rootHandler = delegate(object s, EventArgs e)
			{
				clientDelegate(s, e);
			};
		}
	}

	private void ServerDelegate(object sender, EventArgs args)
	{
		//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ea: Expected O, but got Unknown
		Logging.GetLogger().Trace("ServerDelegate");
		_entry.SettingChanged -= rootHandler;
		ZNet instance = ZNet.instance;
		bool? flag = ((instance != null) ? new bool?(instance.IsServer()) : null);
		if (flag.HasValue)
		{
			if (flag == false && ServerConfiguration.Instance.ReceivedServerValues)
			{
				if (ServerValue != null)
				{
					((ConfigEntryBase)_entry).SetSerializedValue(ServerValue);
					Log.Debug("Setting " + Name + " to server value " + ServerValue);
				}
			}
			else if (flag == true)
			{
				ServerValue = ((ConfigEntryBase)_entry).GetSerializedValue();
				ServerConfiguration.Instance.SendConfigToAllClients(sender, (SettingChangedEventArgs)args);
			}
		}
		if (clientDelegate != null)
		{
			clientDelegate(sender, args);
		}
		_entry.SettingChanged += rootHandler;
	}

	public void EnableHandler(bool setActive)
	{
		if (setActive)
		{
			_entry.SettingChanged += rootHandler;
		}
		else
		{
			_entry.SettingChanged -= rootHandler;
		}
	}

	public bool IsKeyPressed()
	{
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_003a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0060: Unknown result type (might be due to invalid IL or missing references)
		if (ConfigEntry is ConfigEntry<KeyboardShortcut> val)
		{
			KeyboardShortcut value = val.Value;
			foreach (KeyCode modifier in ((KeyboardShortcut)(ref value)).Modifiers)
			{
				if (!Input.GetKey(modifier))
				{
					return false;
				}
			}
			if (!Input.GetKeyDown(((KeyboardShortcut)(ref value)).MainKey))
			{
				return false;
			}
			return true;
		}
		Log.Error("Keyboard read attempted on non-KeyboardShortcut config.");
		return false;
	}

	public bool IsKeyDown()
	{
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_003a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0060: Unknown result type (might be due to invalid IL or missing references)
		if (ConfigEntry is ConfigEntry<KeyboardShortcut> val)
		{
			KeyboardShortcut value = val.Value;
			foreach (KeyCode modifier in ((KeyboardShortcut)(ref value)).Modifiers)
			{
				if (!Input.GetKey(modifier))
				{
					return false;
				}
			}
			if (!Input.GetKey(((KeyboardShortcut)(ref value)).MainKey))
			{
				return false;
			}
			return true;
		}
		Log.Error("Keyboard read attempted on non-KeyboardShortcut config.");
		return false;
	}

	public bool IsKeyReleased()
	{
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_003a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0060: Unknown result type (might be due to invalid IL or missing references)
		if (ConfigEntry is ConfigEntry<KeyboardShortcut> val)
		{
			KeyboardShortcut value = val.Value;
			foreach (KeyCode modifier in ((KeyboardShortcut)(ref value)).Modifiers)
			{
				if (!Input.GetKeyUp(modifier))
				{
					return false;
				}
			}
			if (!Input.GetKeyUp(((KeyboardShortcut)(ref value)).MainKey))
			{
				return false;
			}
			return true;
		}
		Log.Error("Keyboard read attempted on non-KeyboardShortcut config.");
		return false;
	}
}
public class DelegatedConfigEntryBase
{
	public string Name;

	public string Section;

	public string ServerValue;
}
internal class HarmonyHelper
{
	public enum PatchType
	{
		Prefix,
		Postfix,
		Transpiler,
		Finalizer
	}

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

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

	public static void GetDetectionSet(Dictionary<string, string> harmonyIds)
	{
		Logging logger = Logging.GetLogger();
		foreach (KeyValuePair<string, string> harmonyId in harmonyIds)
		{
			if (Harmony.HasAnyPatches(harmonyId.Key))
			{
				logger.Debug("Detected " + harmonyId.Value + " from Harmony");
				if (!detectionSet.ContainsKey(harmonyId.Key))
				{
					detectionSet.Add(harmonyId.Key, harmonyId.Value);
				}
			}
			else if (Chainloader.PluginInfos.ContainsKey(harmonyId.Key))
			{
				logger.Debug("Detected " + harmonyId.Value + " from BepInEx");
				if (!detectionSet.ContainsKey(harmonyId.Key))
				{
					detectionSet.Add(harmonyId.Key, harmonyId.Value);
				}
			}
		}
	}

	public static void AddExclusion(string key)
	{
		if (detectionSet.ContainsKey(key))
		{
			unpatchMods.Add(key, detectionSet[key]);
		}
	}

	public static void UnpatchMods(Harmony harmony)
	{
		Logging logger = Logging.GetLogger();
		foreach (KeyValuePair<string, string> unpatchMod in unpatchMods)
		{
			logger.Warning("Not compatible with " + unpatchMod.Value);
			harmony.UnpatchAll(unpatchMod.Key);
			detectionSet.Remove(unpatchMod.Key);
			logger.Warning("Disabled " + unpatchMod.Value);
		}
	}

	public static bool IsModDetected(string key)
	{
		return detectionSet.ContainsKey(key);
	}

	public static bool IsModNameDetected(string value)
	{
		return detectionSet.ContainsValue(value);
	}

	public static bool TryGetDetectedModName(string key, out string mod)
	{
		return detectionSet.TryGetValue(key, out mod);
	}

	public static bool TryGetDetectedModKey(string value, out string key)
	{
		key = null;
		foreach (string key2 in detectionSet.Keys)
		{
			if (detectionSet[key2] == value)
			{
				key = key2;
				return true;
			}
		}
		return false;
	}

	public static string AddAnonymousPatch(string baseMethodName, PatchType patchType, string modName, string patchMethodName = null)
	{
		string text = null;
		int num = 0;
		Logging logger = Logging.GetLogger();
		foreach (MethodBase item in Harmony.GetAllPatchedMethods().ToList())
		{
			MethodBaseExtensions.HasMethodBody(item);
			Patches patchInfo = Harmony.GetPatchInfo(item);
			ReadOnlyCollection<Patch> readOnlyCollection = patchInfo.Prefixes;
			switch (patchType)
			{
			case PatchType.Postfix:
				readOnlyCollection = patchInfo.Postfixes;
				break;
			case PatchType.Prefix:
				readOnlyCollection = patchInfo.Prefixes;
				break;
			case PatchType.Transpiler:
				readOnlyCollection = patchInfo.Transpilers;
				break;
			case PatchType.Finalizer:
				readOnlyCollection = patchInfo.Finalizers;
				break;
			}
			foreach (Patch item2 in readOnlyCollection)
			{
				if (!item2.owner.StartsWith("harmony-auto") || !(item.Name == baseMethodName))
				{
					continue;
				}
				if (patchMethodName != null)
				{
					if (item2.PatchMethod.Name == patchMethodName)
					{
						num++;
						text = item2.owner;
					}
				}
				else
				{
					num++;
					text = item2.owner;
				}
			}
			if (num == 1)
			{
				detectionSet.Add(text, modName);
				logger.Info($"Added unique anonymous {baseMethodName} {patchType}: {text} as {modName}");
			}
			else if (num > 1)
			{
				text = null;
				logger.Warning($"Found multiple anonymous {baseMethodName} {patchType} entries. Can't identify correct patch to remove or modify.");
			}
		}
		if (num == 0)
		{
			logger.Info("No patch found for " + modName);
		}
		return text;
	}
}
public class Logging
{
	public enum LogLevels
	{
		Critical,
		Error,
		Warning,
		Info,
		Debug,
		Trace
	}

	private static Logging _logger;

	public LogLevels LogLevel { get; set; }

	public string ModName { get; set; }

	private Logging(LogLevels level, string name)
	{
		LogLevel = level;
		ModName = name;
	}

	public static Logging GetLogger(LogLevels level, string name)
	{
		if (_logger == null)
		{
			_logger = new Logging(level, name);
		}
		return _logger;
	}

	public static Logging GetLogger()
	{
		if (_logger == null)
		{
			throw new NullReferenceException("Logger not initialized");
		}
		return _logger;
	}

	public void Trace(string msg)
	{
		if (LogLevel >= LogLevels.Trace)
		{
			Debug.Log((object)Message(msg));
		}
	}

	public void Debug(string msg)
	{
		if (LogLevel >= LogLevels.Debug)
		{
			Debug.Log((object)Message(msg));
		}
	}

	public void Info(string msg)
	{
		if (LogLevel >= LogLevels.Info)
		{
			Debug.Log((object)Message(msg));
		}
	}

	public void Warning(string msg)
	{
		if (LogLevel >= LogLevels.Warning)
		{
			Debug.LogWarning((object)Message(msg));
		}
	}

	public void Error(string msg)
	{
		if (LogLevel >= LogLevels.Error)
		{
			Debug.LogWarning((object)Message(msg));
		}
	}

	public void Error(Exception e)
	{
		Error(e, stackTrace: false);
	}

	public void Error(Exception e, bool stackTrace)
	{
		if (LogLevel >= LogLevels.Error)
		{
			Warning(Message(e.Message));
			if (stackTrace)
			{
				Warning(e.StackTrace);
			}
		}
	}

	public void Critical(Exception e)
	{
		if (LogLevel >= LogLevels.Critical)
		{
			Debug(Message(e.Message));
			Error(e.StackTrace);
		}
	}

	private string Message(string msg)
	{
		return ModName + ": " + msg;
	}

	public static void ChangeLogging(object s, EventArgs e)
	{
		SettingChangedEventArgs val = (SettingChangedEventArgs)(object)((e is SettingChangedEventArgs) ? e : null);
		GetLogger().Debug($"ChangeLog {val.ChangedSetting.Definition.Key} to {val.ChangedSetting.BoxedValue}");
		GetLogger().LogLevel = Cfg.debugLevel.Value;
	}
}
public class ServerConfiguration
{
	[HarmonyPatch(typeof(ZNet), "StopAll")]
	private static class ZNet_Shutdown_Patch
	{
		[HarmonyPrefix]
		private static void ZNet_StopAll_Prefix(ZNet __instance)
		{
			Log.Debug("ZNet_StopAll_Patch_Prefix");
			if (Instance != null)
			{
				Instance.ReceivedServerValues = false;
			}
		}
	}

	[HarmonyPatch(typeof(ZNet), "OnNewConnection")]
	private static class ZNet_OnNewConnection_Patch
	{
		private static void Postfix(ZNet __instance, ZNetPeer peer)
		{
			Log.Debug("ZNet OnNewConnection postfix");
			if (!__instance.IsServer())
			{
				try
				{
					peer.m_rpc.Register<ZPackage>("ClientConfigReceiver." + GetPluginGuid(), (Action<ZRpc, ZPackage>)Instance.RPC_ClientConfigReceiver);
					Log.Debug("Player registered RPC_ClientConfigReceiver");
					return;
				}
				catch (Exception)
				{
					Log.Warning("Failed to register RPC");
					return;
				}
			}
			try
			{
				Instance.SendConfigToClient(peer);
			}
			catch (Exception)
			{
				Log.Warning("Error sending server configuration to client");
			}
		}
	}

	public static List<DelegatedConfigEntryBase> ServerDelegatedEntries = new List<DelegatedConfigEntryBase>();

	private static ConfigFile LocalConfig;

	private static BaseUnityPlugin Mod;

	private static string ConfigFileName;

	private static ServerConfiguration _instance;

	private static Logging Log;

	public bool IsSetup;

	public bool ReceivedServerValues;

	public FileSystemWatcher ConfigWatcher;

	private const string NOT_CONFIGURED = "ServerConfiguration not initialized. Setup first.";

	public static ServerConfiguration Instance
	{
		get
		{
			if (_instance == null)
			{
				_instance = new ServerConfiguration();
			}
			return _instance;
		}
	}

	private ServerConfiguration()
	{
	}

	public void Setup(ConfigFile config, BaseUnityPlugin modInstance)
	{
		LocalConfig = config;
		Log = Logging.GetLogger();
		Log.Trace("ServerConfiguration Setup");
		Mod = modInstance;
		ConfigFileName = Path.GetFileName(LocalConfig.ConfigFilePath);
		IsSetup = true;
	}

	public void CreateConfigWatcher()
	{
		ConfigWatcher = Utils.CreateFileWatcher(LocalConfig.ConfigFilePath, LoadConfig);
	}

	private void LoadConfig(object sender, FileSystemEventArgs e)
	{
		if (!File.Exists(LocalConfig.ConfigFilePath))
		{
			return;
		}
		try
		{
			Log.Debug($"Loading configuration {e.ChangeType}");
			LocalConfig.Reload();
		}
		catch
		{
			Log.Error("Error loading configuration file " + ConfigFileName);
		}
	}

	public static string GetPluginGuid()
	{
		return Mod.Info.Metadata.GUID;
	}

	public void RPC_ClientConfigReceiver(ZRpc zrpc, ZPackage package)
	{
		if (!Instance.IsSetup)
		{
			Log.Error("ServerConfiguration not initialized. Setup first.");
			return;
		}
		Log.Debug("ClientConfigReceiver");
		string section;
		string name;
		while (package.GetPos() < package.Size())
		{
			section = package.ReadString();
			name = package.ReadString();
			string text = package.ReadString();
			Log.Trace("Reading " + section + " " + name + " value " + text + " from ZPackage");
			DelegatedConfigEntryBase delegatedConfigEntryBase = ServerDelegatedEntries.Find((DelegatedConfigEntryBase e) => e.Name == name && e.Section == section);
			if (delegatedConfigEntryBase != null)
			{
				Log.Trace("Found DCEB on client and setting to server value " + text);
				delegatedConfigEntryBase.ServerValue = text;
			}
			ConfigEntryBase val = LocalConfig[section, name];
			if (val != null)
			{
				Log.Trace("Found local CEB and setting underlying config value " + text);
				val.SetSerializedValue(text);
			}
		}
		ReceivedServerValues = true;
	}

	internal void WriteConfigEntries(ZPackage zpkg)
	{
		foreach (DelegatedConfigEntryBase serverDelegatedEntry in ServerDelegatedEntries)
		{
			Log.Trace("Writing " + serverDelegatedEntry.Section + " " + serverDelegatedEntry.Name + " value " + serverDelegatedEntry.ServerValue + " to ZPackage");
			zpkg.Write(serverDelegatedEntry.Section);
			zpkg.Write(serverDelegatedEntry.Name);
			zpkg.Write(serverDelegatedEntry.ServerValue);
		}
	}

	internal void SendConfigToClient(ZNetPeer peer)
	{
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0031: Expected O, but got Unknown
		if (!Instance.IsSetup)
		{
			Log.Error("ServerConfiguration not initialized. Setup first.");
			return;
		}
		Log.Debug("SendConfigToClient");
		ZPackage val = new ZPackage();
		WriteConfigEntries(val);
		peer.m_rpc.Invoke("ClientConfigReceiver." + GetPluginGuid(), new object[1] { val });
		Log.Trace("Invoked ClientConfigReceiver on peer");
	}

	public void SendConfigToAllClients(object o, SettingChangedEventArgs e)
	{
		//IL_004d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0053: Expected O, but got Unknown
		if (!IsSetup)
		{
			Log.Error("ServerConfiguration not initialized. Setup first.");
		}
		else if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer() && ZNet.instance.GetPeerConnections() > 0)
		{
			Log.Debug("SendConfigToAllClients");
			ZPackage zpkg = new ZPackage();
			WriteConfigEntries(zpkg);
			((MonoBehaviour)Mod).StartCoroutine(_instance.Co_BroadcastConfig(zpkg));
		}
	}

	private IEnumerator Co_BroadcastConfig(ZPackage zpkg)
	{
		Log.Debug("Co_BroadcastConfig");
		List<ZNetPeer> connectedPeers = ZNet.instance.GetConnectedPeers();
		foreach (ZNetPeer item in connectedPeers)
		{
			if (item != ZNet.instance.GetServerPeer())
			{
				item.m_rpc.Invoke("ClientConfigReceiver." + GetPluginGuid(), new object[1] { zpkg });
				Log.Trace("Invoked ClientConfigReceiver on peer");
			}
			yield return null;
		}
	}
}
internal class Utils
{
	public static TEnum Guardrails<TEnum>(string value, TEnum enumDefault) where TEnum : struct
	{
		if (Enum.TryParse<TEnum>(value, ignoreCase: true, out var result))
		{
			return result;
		}
		return enumDefault;
	}

	public static int Guardrails(int value, int lbound, int ubound)
	{
		if (value < lbound)
		{
			return lbound;
		}
		if (value > ubound)
		{
			return ubound;
		}
		return value;
	}

	public static string truncate(string value, int maxChars)
	{
		if (value == null)
		{
			return null;
		}
		if (value.Length <= maxChars)
		{
			return value;
		}
		return value.Substring(0, maxChars);
	}

	public static void GetCharactersInRangeXZ(Vector3 point, float radius, List<Character> characters)
	{
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		float num = radius * radius;
		foreach (Character s_character in Character.s_characters)
		{
			if (DistanceSqrXZ(((Component)s_character).transform.position, point) < num)
			{
				characters.Add(s_character);
			}
		}
	}

	public static float DistanceSqr(Vector3 v0, Vector3 v1)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0013: 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_0021: Unknown result type (might be due to invalid IL or missing references)
		float num = v1.x - v0.x;
		float num2 = v1.y - v0.y;
		float num3 = v1.z - v0.z;
		return num * num + num2 * num2 + num3 * num3;
	}

	public static float DistanceSqrXZ(Vector3 v0, Vector3 v1)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		float num = v1.x - v0.x;
		float num2 = v1.z - v0.z;
		return num * num + num2 * num2;
	}

	public static float DistanceXZ(Vector3 v0, Vector3 v1)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		float num = v1.x - v0.x;
		float num2 = v1.z - v0.z;
		return Mathf.Sqrt(num * num + num2 * num2);
	}

	public static float Guardrails(float value, float lbound, float ubound)
	{
		if (value < lbound)
		{
			return lbound;
		}
		if (value > ubound)
		{
			return ubound;
		}
		return value;
	}

	public static string UnClonifiedName(string name)
	{
		if (name == null)
		{
			return null;
		}
		int num = name.IndexOf("(Clone)");
		if (num < 1)
		{
			return name;
		}
		return name.Substring(0, num);
	}

	public static void SetTranslator(int id, string idText)
	{
		typeof(Localization).GetMethod("AddWord", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(Localization.instance, new object[2]
		{
			"skill_" + id,
			idText
		});
	}

	public static string GetTranslated(int id)
	{
		Logging.GetLogger().Debug(string.Format("Got translation for id {0} to {1}", id, Localization.instance.Localize("skill_" + id)));
		return Localization.instance.Localize("$skill_" + id);
	}

	public static string GetAssemblyPathedFile(string fileName)
	{
		return new FileInfo(Assembly.GetExecutingAssembly().Location).DirectoryName.Replace('\\', '/') + "/" + fileName;
	}

	public static Sprite GetPrefabIcon(string prefabName)
	{
		Sprite result = null;
		GameObject prefab = GetPrefab(prefabName);
		ItemDrop val = default(ItemDrop);
		if ((Object)(object)prefab != (Object)null && prefab.TryGetComponent<ItemDrop>(ref val))
		{
			result = val.m_itemData.GetIcon();
		}
		return result;
	}

	public static Player GetPlayerByZDOID(ZDOID zid)
	{
		//IL_0016: 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_001e: Unknown result type (might be due to invalid IL or missing references)
		foreach (Player allPlayer in Player.GetAllPlayers())
		{
			ZDOID zDOID = ((Character)allPlayer).GetZDOID();
			if (((ZDOID)(ref zDOID)).Equals(zid))
			{
				return allPlayer;
			}
		}
		return null;
	}

	public static Character GetCharacterByZDOID(string cid)
	{
		//IL_0016: 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)
		foreach (Character allCharacter in Character.GetAllCharacters())
		{
			ZDOID zDOID = allCharacter.GetZDOID();
			if (((object)(ZDOID)(ref zDOID)).ToString().Equals(cid))
			{
				return allCharacter;
			}
		}
		return null;
	}

	public static Character GetCharacterByZDOID(ZDOID cid)
	{
		//IL_0016: 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_001e: Unknown result type (might be due to invalid IL or missing references)
		foreach (Character allCharacter in Character.GetAllCharacters())
		{
			ZDOID zDOID = allCharacter.GetZDOID();
			if (((ZDOID)(ref zDOID)).Equals(cid))
			{
				return allCharacter;
			}
		}
		return null;
	}

	public static ZNetPeer GetPeerByRPC(ZRpc rpc)
	{
		foreach (ZNetPeer peer in ZNet.instance.GetPeers())
		{
			if (peer.m_rpc == rpc)
			{
				return peer;
			}
		}
		return null;
	}

	public static List<GameObject> GetGameObjectsOfType(Type t)
	{
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		List<GameObject> list = new List<GameObject>();
		Object[] array = Object.FindObjectsOfType(t);
		foreach (Object val in array)
		{
			list.Add(((Component)val).gameObject);
		}
		return list;
	}

	public static GameObject GetClosestGameObjectOfType(Type t, Vector3 point, float radius)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		return GetGameObjectsOfTypeInRangeByDistance(t, point, radius)?[0];
	}

	public static List<GameObject> GetGameObjectsOfTypeInRangeByDistance(Type t, Vector3 point, float radius)
	{
		//IL_0007: 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_0039: Unknown result type (might be due to invalid IL or missing references)
		List<KeyValuePair<GameObject, float>> list = new List<KeyValuePair<GameObject, float>>();
		List<GameObject> gameObjectsOfTypeInRange = GetGameObjectsOfTypeInRange(t, point, radius);
		if (gameObjectsOfTypeInRange.Count > 0)
		{
			foreach (GameObject item in gameObjectsOfTypeInRange)
			{
				list.Add(new KeyValuePair<GameObject, float>(item, Vector3.Distance(item.transform.position, point)));
			}
			list.Sort((KeyValuePair<GameObject, float> pair1, KeyValuePair<GameObject, float> pair2) => pair1.Value.CompareTo(pair2.Value));
			return list.ConvertAll((KeyValuePair<GameObject, float> x) => x.Key);
		}
		return null;
	}

	public static List<GameObject> GetGameObjectsOfTypeInRange(Type t, Vector3 point, float radius)
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		return (from x in GetGameObjectsOfType(t)
			where Vector3.Distance(x.transform.position, point) < radius
			select x).ToList();
	}

	public static float GetPointDepth(Vector3 p)
	{
		//IL_000a: Unknown result type (might be due to invalid IL or missing references)
		return ZoneSystem.instance.m_waterLevel - GetSolidHeight(p);
	}

	public static List<string> GetDelimitedStringAsList(string delimitedString, char delimiter)
	{
		List<string> list = new List<string>();
		string[] array = delimitedString.Split(new char[1] { delimiter }, StringSplitOptions.RemoveEmptyEntries);
		foreach (string text in array)
		{
			list.Add(text.Trim());
		}
		return list;
	}

	public static float GetSolidHeight(Vector3 p)
	{
		//IL_0021: 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_004b: Unknown result type (might be due to invalid IL or missing references)
		int solidRayMask = ZoneSystem.instance.m_solidRayMask;
		float result = 0f;
		p.y += 1000f;
		RaycastHit val = default(RaycastHit);
		if (Physics.Raycast(p, Vector3.down, ref val, 2000f, solidRayMask) && !Object.op_Implicit((Object)(object)((RaycastHit)(ref val)).collider.attachedRigidbody))
		{
			result = ((RaycastHit)(ref val)).point.y;
		}
		return result;
	}

	public static Transform FindChild(Transform aParent, string aName)
	{
		//IL_000f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0015: Expected O, but got Unknown
		foreach (Transform item in aParent)
		{
			Transform val = item;
			if (((Object)val).name == aName)
			{
				return val;
			}
			Transform val2 = FindChild(val, aName);
			if ((Object)(object)val2 != (Object)null)
			{
				return val2;
			}
		}
		return null;
	}

	public static Transform FindParent(Transform go)
	{
		while ((Object)(object)go.parent != (Object)null)
		{
			go = go.parent;
		}
		return go;
	}

	public static GameObject GetPrefab(int prefabHash)
	{
		return GetPrefabByHash(prefabHash);
	}

	public static GameObject GetPrefabByHash(int prefabHash)
	{
		GameObject val = ObjectDB.instance.GetItemPrefab(prefabHash);
		Logging logger = Logging.GetLogger();
		if ((Object)(object)val != (Object)null)
		{
			logger.Debug("Found prefab in ObjectDB");
		}
		else
		{
			ZNetScene instance = ZNetScene.instance;
			val = ((instance != null) ? instance.GetPrefab(prefabHash) : null);
			if ((Object)(object)val != (Object)null)
			{
				logger.Debug("Found prefab in Scene");
			}
		}
		return val;
	}

	public static GameObject GetPrefab(string prefabName)
	{
		GameObject val = ObjectDB.instance.GetItemPrefab(prefabName);
		Logging logger = Logging.GetLogger();
		if ((Object)(object)val != (Object)null)
		{
			logger.Debug("Found " + prefabName + " in ObjectDB");
		}
		else
		{
			ZNetScene instance = ZNetScene.instance;
			val = ((instance != null) ? instance.GetPrefab(prefabName) : null);
			if ((Object)(object)val != (Object)null)
			{
				logger.Debug("Found " + prefabName + " in Scene");
			}
		}
		return val;
	}

	public static string SerializeFromDictionary<K, V>(string delimp, string delimc, IDictionary<K, V> dict)
	{
		if (dict == null)
		{
			return null;
		}
		IEnumerable<string> values = dict.Select(delegate(KeyValuePair<K, V> kvp)
		{
			KeyValuePair<K, V> keyValuePair = kvp;
			string? obj = keyValuePair.Key?.ToString();
			string text = delimc;
			keyValuePair = kvp;
			return obj + text + keyValuePair.Value;
		});
		return string.Join(delimp, values);
	}

	public static void DeserializeToDictionary<K, V>(string serializedString, string delimp, string delimc, ref IDictionary<K, V> dict)
	{
		if (dict == null)
		{
			return;
		}
		dict.Clear();
		string[] separator = new string[1] { delimp };
		string[] separator2 = new string[1] { delimc };
		string[] array = serializedString.Split(separator, StringSplitOptions.RemoveEmptyEntries);
		for (int i = 0; i < array.Length; i++)
		{
			string[] array2 = array[i].Split(separator2, StringSplitOptions.RemoveEmptyEntries);
			if (array2.Length == 2)
			{
				dict.Add(TypedValue<K>(array2[0]), TypedValue<V>(array2[1]));
			}
		}
	}

	public static FileSystemWatcher CreateFileWatcher(string fullPath, FileSystemEventHandler handler)
	{
		string fileName = Path.GetFileName(fullPath);
		FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(fullPath.Substring(0, fullPath.Length - fileName.Length), fileName);
		fileSystemWatcher.NotifyFilter = NotifyFilters.Attributes | NotifyFilters.Size | NotifyFilters.LastWrite | NotifyFilters.CreationTime;
		fileSystemWatcher.Changed += handler;
		fileSystemWatcher.Created += handler;
		fileSystemWatcher.IncludeSubdirectories = false;
		fileSystemWatcher.SynchronizingObject = ThreadingHelper.SynchronizingObject;
		fileSystemWatcher.EnableRaisingEvents = true;
		return fileSystemWatcher;
	}

	public static T TypedValue<T>(object a)
	{
		return (T)Convert.ChangeType(a, typeof(T));
	}

	public static float TimeAdjustedRamp(float maxValue, float duration, float elapsedTime, float pctFromStartRise, float pctFromEndFall)
	{
		float num = elapsedTime / duration;
		if (num <= pctFromStartRise)
		{
			return maxValue * (num / pctFromStartRise);
		}
		if (num >= 1f - pctFromEndFall)
		{
			return maxValue * ((1f - num) / pctFromEndFall);
		}
		return maxValue;
	}

	public static bool CopyComponentToGameObject(Component original, ref GameObject destination)
	{
		//IL_0073: Unknown result type (might be due to invalid IL or missing references)
		//IL_0079: Expected O, but got Unknown
		Logging logger = Logging.GetLogger();
		Type type = ((object)original).GetType();
		logger.Debug($"Original Type is {type}");
		GameObject obj = destination;
		logger.Debug("Destination GameObject " + ((obj != null) ? ((Object)obj).name : null));
		Component val = destination.GetComponent(type);
		if ((Object)(object)val == (Object)null)
		{
			val = destination.AddComponent(type);
		}
		if ((Object)(object)val == (Object)null)
		{
			logger.Debug("Destination component is null");
			return false;
		}
		Component val2 = (Component)Activator.CreateInstance(type);
		if ((Object)(object)val2 == (Object)null)
		{
			logger.Debug("Destination component is null");
			return false;
		}
		if ((Object)(object)val2 == (Object)null)
		{
			logger.Debug("Boxed component is null");
			return false;
		}
		FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
		foreach (FieldInfo fieldInfo in fields)
		{
			fieldInfo.SetValue(val2, fieldInfo.GetValue(original));
		}
		val = val2;
		return true;
	}

	public static bool CopyObject(object original, object target)
	{
		Logging logger = Logging.GetLogger();
		Type type = original.GetType();
		Type type2 = target.GetType();
		if (type == null)
		{
			logger.Warning("Copy Object: Source object is null");
			Activator.CreateInstance(type);
			return false;
		}
		if (type2 == null)
		{
			logger.Warning("Copy Object: Destination object is null");
			return false;
		}
		if (type2 != type)
		{
			logger.Warning("Copy Object: Source and destination components are different types");
			return false;
		}
		FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
		foreach (FieldInfo fieldInfo in fields)
		{
			fieldInfo.SetValue(target, fieldInfo.GetValue(original));
		}
		return true;
	}
}
internal class Cfg
{
	public static DelegatedConfigEntry<Logging.LogLevels> debugLevel = null;

	public static DelegatedConfigEntry<int> trophyCap = null;

	public static DelegatedConfigEntry<int> damageCap = null;

	public static DelegatedConfigEntry<int> trophyDistance = null;

	public static DelegatedConfigEntry<bool> damagePhysical = null;

	public static DelegatedConfigEntry<bool> damageElemental = null;

	public static DelegatedConfigEntry<bool> damageOther = null;

	public static DelegatedConfigEntry<SlayerSkills.Points> assignPoints = null;

	public static DelegatedConfigEntry<bool> lowerSkillsOnDeath = null;

	public static DelegatedConfigEntry<bool> allowCheats = null;

	public static DelegatedConfigEntry<bool> useCreatureLevel = null;

	public static DelegatedConfigEntry<int> bossPoints = null;

	public static DelegatedConfigEntry<bool> tamesSlay = null;

	public static DelegatedConfigEntry<bool> tamesBuff = null;

	public static DelegatedConfigEntry<Color> skillColor = null;

	private static KeyCode[] keyModifiers = (KeyCode[])(object)new KeyCode[2]
	{
		(KeyCode)308,
		(KeyCode)304
	};

	public static KeyboardShortcut keyConfigItemDefault = new KeyboardShortcut((KeyCode)115, keyModifiers);

	public static void BepInExConfig(BaseUnityPlugin _instance)
	{
		//IL_007c: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d1: Expected O, but got Unknown
		//IL_010a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0114: Expected O, but got Unknown
		//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b7: Expected O, but got Unknown
		//IL_02df: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e9: Expected O, but got Unknown
		debugLevel = new DelegatedConfigEntry<Logging.LogLevels>(SlayerSkills.ChangeLogging);
		debugLevel.ConfigEntry = _instance.Config.Bind<Logging.LogLevels>("Utility", "LogLevel", Logging.LogLevels.Info, "Controls the level of information contained in the log");
		SlayerSkills.Log.LogLevel = debugLevel.Value;
		skillColor = new DelegatedConfigEntry<Color>(SlayerSkills.ChangeColor);
		skillColor.ConfigEntry = _instance.Config.Bind<Color>("Utility", "SkillTextColor", Color.cyan, "Sets the color for the Slayer Skill text in the Trophy panel.");
		trophyCap = new DelegatedConfigEntry<int>(useServerDelegate: true);
		trophyCap.ConfigEntry = _instance.Config.Bind<int>("Slayer Skills", "SkillCap", 100, new ConfigDescription("Sets the maximum Slayer level attainable. Every slayer point earned increases the percentage of the damage buff against a specific creature type.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 200), Array.Empty<object>()));
		trophyDistance = new DelegatedConfigEntry<int>(useServerDelegate: true);
		trophyDistance.ConfigEntry = _instance.Config.Bind<int>("Slayer Skills", "TrophyDistance", 30, new ConfigDescription("Sets the maximum distance, in meters, that a player (in multiplayer) can be from the trophy drop to qualify for the trophy point.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(5, 50), Array.Empty<object>()));
		lowerSkillsOnDeath = new DelegatedConfigEntry<bool>(useServerDelegate: true);
		lowerSkillsOnDeath.ConfigEntry = _instance.Config.Bind<bool>("Slayer Skills", "LowerSkillsOnDeath", true, "If enabled, will lower slayer skills upon death (same % as standard skills)");
		allowCheats = new DelegatedConfigEntry<bool>(useServerDelegate: true);
		allowCheats.ConfigEntry = _instance.Config.Bind<bool>("Slayer Skills", "AllowCheats", false, "If enabled, allows raising and resetting Slayer skills using 'raiseskill' and 'resetskill' commands from the console by using the trophy name for the creature. Use an underscore (_) instead of a space on the command line, e.g. 'raiseskill Deer_Trophy 3'. Note the trophy name is case sensitive!");
		damageCap = new DelegatedConfigEntry<int>(useServerDelegate: true);
		damageCap.ConfigEntry = _instance.Config.Bind<int>("Slayer Damage", "DamagePercent", 100, new ConfigDescription("Sets the maximum damage buff percent of your normal damage. The applied buff percentage is determined by your current Slayer level.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
		damagePhysical = new DelegatedConfigEntry<bool>(useServerDelegate: true);
		damagePhysical.ConfigEntry = _instance.Config.Bind<bool>("Slayer Damage", "BuffPhysical", true, "If enabled, applies slayer bonus to physical damage (slash, blunt, pierce)");
		damageElemental = new DelegatedConfigEntry<bool>(useServerDelegate: true);
		damageElemental.ConfigEntry = _instance.Config.Bind<bool>("Slayer Damage", "BuffElemental", false, "If enabled, applies slayer bonus to elemental damage (lightning, fire, frost)");
		damageOther = new DelegatedConfigEntry<bool>(useServerDelegate: true);
		damageOther.ConfigEntry = _instance.Config.Bind<bool>("Slayer Damage", "BuffOther", false, "If enabled, applies slayer bonus to other damage (poison, spirit)");
		assignPoints = new DelegatedConfigEntry<SlayerSkills.Points>(useServerDelegate: true);
		assignPoints.ConfigEntry = _instance.Config.Bind<SlayerSkills.Points>("Slayer Points", "MultiplayerPoints", SlayerSkills.Points.Random, "Controls how slayer skills are awarded in multiplayer. Random grants skill points to one player in group. All grants a skill point to every player in group. Distribute grants a fraction of a skill point evenly to every player in group.");
		useCreatureLevel = new DelegatedConfigEntry<bool>(useServerDelegate: true);
		useCreatureLevel.ConfigEntry = _instance.Config.Bind<bool>("Slayer Points", "UseCreatureLevel", false, "If enabled, adjusts the Slayer points awarded on trophy drop based on the level (number of 'Stars') of the creature slain");
		bossPoints = new DelegatedConfigEntry<int>(useServerDelegate: true);
		bossPoints.ConfigEntry = _instance.Config.Bind<int>("Slayer Points", "BossAdjustment", 3, new ConfigDescription("Adjusts Slayer points awarded to account for bosses. Equivalent to treating a boss as an 'X-Star' creature. Applies even if UseCreatureLevel is false (and adds if true).", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 10), Array.Empty<object>()));
		tamesSlay = new DelegatedConfigEntry<bool>(useServerDelegate: true);
		tamesSlay.ConfigEntry = _instance.Config.Bind<bool>("Tamed Creatures", "TamesCanSlay", true, "If enabled, trophy drops from creatures slain by your tamed creatires count toward your Slayer skill");
		tamesBuff = new DelegatedConfigEntry<bool>(useServerDelegate: true);
		tamesBuff.ConfigEntry = _instance.Config.Bind<bool>("Tamed Creatures", "TamesGetBuff", false, "If enabled, your tamed creatures also recieve your Slayer buff");
	}
}
internal class CreatureInfo
{
	public string Name { get; }

	public bool Tamed { get; }

	public bool Tapped { get; }

	public bool Boss { get; }

	public int Level { get; }

	public bool DropsEnabled { get; }

	public CreatureInfo(string name, bool tamed, bool tapped, bool boss, int level, bool dropsEnabled)
	{
		Name = name;
		Tamed = tamed;
		Tapped = tapped;
		Boss = boss;
		Level = level;
		DropsEnabled = dropsEnabled;
	}
}
internal class CustomDataWrapper
{
	private Dictionary<string, string> playerData;

	private CustomDataWrapper instance;

	private Dictionary<string, string> Data { get; set; }

	public CustomDataWrapper(Dictionary<string, string> sourceData, string keyPrefix)
	{
		CustomDataWrapper customDataWrapper = this;
		playerData = sourceData;
		Data = new Dictionary<string, string>();
		sourceData.Keys.ToList().ForEach(delegate(string key)
		{
			if (key.StartsWith(keyPrefix))
			{
				customDataWrapper.Data.Add(key, sourceData[key]);
			}
		});
	}

	public void Add(string key, string value)
	{
		Data.Add(key, value);
		playerData.Add(key, value);
	}

	public bool Remove(string key)
	{
		return Data.Remove(key) & playerData.Remove(key);
	}

	public void Set(string key, string value)
	{
		if (Data.ContainsKey(key))
		{
			Data[key] = value;
		}
		else
		{
			Data.Add(key, value);
		}
		if (playerData.ContainsKey(key))
		{
			playerData[key] = value;
		}
		else
		{
			playerData.Add(key, value);
		}
	}

	public string Get(string key)
	{
		if (Data.ContainsKey(key))
		{
			return Data[key];
		}
		return null;
	}

	public bool ContainsKey(string key)
	{
		return Data.ContainsKey(key);
	}

	public void PreSaveSync()
	{
		foreach (KeyValuePair<string, string> datum in Data)
		{
			if (!playerData.ContainsKey(datum.Key))
			{
				playerData.Add(datum.Key, datum.Value);
			}
		}
	}
}
[BepInPlugin("neobotics.valheim_mod.slayerskills", "SlayerSkills", "1.0.13")]
[BepInProcess("valheim.exe")]
[BepInProcess("valheim_server.exe")]
public class SlayerSkills : BaseUnityPlugin
{
	public enum Points
	{
		Random,
		All,
		Distribute,
		KillingBlow
	}

	[HarmonyPatch(typeof(Localization), "SetLanguage")]
	private static class Localization_SetLanguage_Patch
	{
		[HarmonyPostfix]
		private static void Localization_SetLanguage_Postfix(Localization __instance)
		{
			BuildCreatureTrophyMap();
		}
	}

	[HarmonyPatch(typeof(Game), "Start")]
	private static class Game_Start_Patch
	{
		[HarmonyPostfix]
		private static void Game_Start_Patch_Postfix(Game __instance)
		{
			Log.Debug(" Game_Start_Patch_Postfix");
			ZRoutedRpc.instance.Register<string, float>("RaiseSlayerStat", (Action<long, string, float>)RPC_RaiseSlayerStat);
		}
	}

	[HarmonyPatch(typeof(ZNetScene), "Awake")]
	private static class ZNetScene_Awake_Patch
	{
		[HarmonyPostfix]
		private static void ZNetScene_Awake_Postfix(ZNetScene __instance)
		{
			Log.Debug("ZNetScene_Awake_Patch_Postfix");
			BuildCreatureTrophyMap();
		}
	}

	[HarmonyPatch(typeof(InventoryGui), "UpdateTrophyList")]
	private static class InventoryGui_UpdateTrophyList_Patch
	{
		[HarmonyPostfix]
		private static void InventoryGui_UpdateTrophyList_Postfix(InventoryGui __instance, List<GameObject> ___m_trophyList)
		{
			Log.Debug("InventoryGui_UpdateTrophyList_Patch_Postfix");
			if (___m_trophyList == null)
			{
				return;
			}
			foreach (GameObject ___m_trophy in ___m_trophyList)
			{
				Transform transform = ___m_trophy.transform;
				Transform obj = ((transform is RectTransform) ? transform : null);
				TMP_Text component = ((Component)obj.Find("description")).GetComponent<TMP_Text>();
				TMP_Text component2 = ((Component)obj.Find("name")).GetComponent<TMP_Text>();
				if (nameToTokenMap.TryGetValue(component2.text, out var value))
				{
					if (trophyCollection.TryGetValue(value, out var value2))
					{
						string text = ((value2 < (float)Cfg.trophyCap.Value) ? $"{FlooredLevel(value2)}/{Cfg.trophyCap.Value}" : "Slayer");
						component.richText = true;
						component.text = "<color=" + colorString + ">" + text + "</color>\n" + component.text;
					}
					else
					{
						Log.Debug("Can't find mapped token " + value + " in trophy collection");
					}
				}
				else
				{
					Log.Debug("Can't find localized name " + component2.text + " slayerSkill");
				}
			}
		}
	}

	[HarmonyPatch(typeof(CharacterDrop), "OnDeath")]
	private static class CharacterDrop_OnDeath_Patch
	{
		[HarmonyPrefix]
		private static void CharacterDrop_OnDeath_Prefix(CharacterDrop __instance, Character ___m_character)
		{
			Log.Debug("CharacterDrop_OnDeath_Patch_Prefix");
			bool tapped = false;
			ZNetView val = default(ZNetView);
			if (((Component)___m_character).TryGetComponent<ZNetView>(ref val))
			{
				ZDO zDO = val.GetZDO();
				if (zDO.IsValid() && zDO.GetBool(UNIQUE_ID, false))
				{
					tapped = true;
				}
			}
			if ((Object)(object)___m_character != (Object)null)
			{
				_tempCreatureInfo = new CreatureInfo(___m_character.m_name, ___m_character.IsTamed(), tapped, ___m_character.IsBoss(), ___m_character.GetLevel(), __instance.m_dropsEnabled);
			}
		}

		[HarmonyPostfix]
		private static void CharacterDrop_OnDeath_Postfix(CharacterDrop __instance, ref CreatureInfo __state)
		{
			Log.Debug("CharacterDrop_OnDeath_Patch_Postfix");
			_tempCreatureInfo = null;
		}
	}

	[HarmonyPatch(typeof(CharacterDrop), "DropItems")]
	private static class CharacterDrop_DropItems_Patch
	{
		[HarmonyPostfix]
		private static void CharacterDrop_DropItems_Postfix(List<KeyValuePair<GameObject, int>> drops, Vector3 centerPos, float dropArea, bool ___m_dropsEnabled)
		{
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Invalid comparison between Unknown and I4
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			Log.Debug("CharacterDrop_DropItems_Patch_Postfix");
			if (_tempCreatureInfo == null || _tempCreatureInfo.Tamed || !_tempCreatureInfo.DropsEnabled)
			{
				return;
			}
			if (_tempCreatureInfo.Tapped)
			{
				Log.Debug("Creature was tapped by a player");
				{
					ItemDrop val = default(ItemDrop);
					foreach (KeyValuePair<GameObject, int> drop in drops)
					{
						if ((Object)(object)drop.Key != (Object)null && drop.Key.TryGetComponent<ItemDrop>(ref val) && (int)val.m_itemData.m_shared.m_itemType == 13)
						{
							int num = ((!Cfg.useCreatureLevel.Value) ? 1 : _tempCreatureInfo.Level);
							if (_tempCreatureInfo.Boss)
							{
								num += Cfg.bossPoints.Value;
							}
							InitiateRaiseStat(val.m_itemData.m_shared.m_name, num, centerPos);
						}
					}
					return;
				}
			}
			Log.Debug("Character " + _tempCreatureInfo.Name + " was not hit by player");
		}
	}

	[HarmonyPatch(typeof(Ragdoll), "SaveLootList")]
	private static class Ragdoll_SaveLootList_Patch
	{
		[HarmonyPostfix]
		private static void Ragdoll_SaveLootList_Postfix(Ragdoll __instance, CharacterDrop characterDrop, ZNetView ___m_nview)
		{
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Invalid comparison between Unknown and I4
			Log.Debug("Ragdoll_SaveLootList_Patch_Postfix");
			Character character = characterDrop.m_character;
			ZNetView val = default(ZNetView);
			if (!((Object)(object)character != (Object)null) || character.IsTamed() || !((Component)character).TryGetComponent<ZNetView>(ref val))
			{
				return;
			}
			ZDO zDO = val.GetZDO();
			if (zDO.IsValid() && zDO.GetBool(UNIQUE_ID, false))
			{
				ZDO zDO2 = ___m_nview.GetZDO();
				Log.Debug("Creature was tapped by a player");
				int @int = zDO2.GetInt("drops", 0);
				ItemDrop val2 = default(ItemDrop);
				for (int i = 0; i < @int; i++)
				{
					int int2 = zDO2.GetInt("drop_hash" + i, 0);
					GameObject prefab = ZNetScene.instance.GetPrefab(int2);
					if ((Object)(object)prefab != (Object)null && prefab.TryGetComponent<ItemDrop>(ref val2) && (int)val2.m_itemData.m_shared.m_itemType == 13)
					{
						int num = ((!Cfg.useCreatureLevel.Value) ? 1 : character.GetLevel());
						if (character.IsBoss())
						{
							num += Cfg.bossPoints.Value;
						}
						string text = $"{val2.m_itemData.m_shared.m_name}:{num}";
						Log.Debug("Setting ragdoll with " + text);
						if (zDO2.IsValid())
						{
							zDO2.Set(StringExtensionMethods.GetStableHashCode(UNIQUE_ID), text);
						}
					}
				}
			}
			else
			{
				Log.Debug("Character " + ((character != null) ? ((Object)character).name : null) + " was not hit by player");
			}
		}
	}

	[HarmonyPatch(typeof(Ragdoll), "SpawnLoot")]
	private static class Ragdoll_SpawnLoot_Patch
	{
		[HarmonyPostfix]
		private static void Ragdoll_SpawnLoot_Postfix(Ragdoll __instance, Vector3 center, ZNetView ___m_nview)
		{
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			Log.Debug("Ragdoll_SpawnLoot_Patch_Postfix");
			string text = null;
			ZDO zDO = ___m_nview.GetZDO();
			if (zDO.IsValid())
			{
				text = zDO.GetString(StringExtensionMethods.GetStableHashCode(UNIQUE_ID), "");
			}
			if (!Utility.IsNullOrWhiteSpace(text))
			{
				string[] array = text.Split(new char[1] { ':' });
				string itemName = array[0];
				float amount = float.Parse(array[1]);
				Log.Debug("Ragdoll is spawning trophy");
				InitiateRaiseStat(itemName, amount, center);
			}
		}
	}

	[HarmonyPatch(typeof(Character), "Damage")]
	private static class Character_Damage_Patch
	{
		[HarmonyPrefix]
		private static void Character_Damage_Prefix(Character __instance, ref HitData hit, ZNetView ___m_nview)
		{
			Log.Debug("Character_Damage_Patch_Prefix");
			Collider hitCollider = hit.m_hitCollider;
			Character attacker = hit.GetAttacker();
			Player localPlayer = Player.m_localPlayer;
			if (!((Object)(object)attacker != (Object)null) || !((Object)(object)localPlayer != (Object)null) || __instance.IsPlayer())
			{
				return;
			}
			ZDO zDO = ((Component)attacker).GetComponent<ZNetView>().GetZDO();
			bool @bool = zDO.GetBool("tamed", false);
			bool flag = @bool && zDO.GetOwner() == localPlayer.GetPlayerID();
			if ((Object)(object)attacker == (Object)(object)localPlayer || (flag && Cfg.tamesBuff.Value))
			{
				object name;
				if (hitCollider == null)
				{
					name = null;
				}
				else
				{
					Transform transform = ((Component)hitCollider).transform;
					if (transform == null)
					{
						name = null;
					}
					else
					{
						Transform root = transform.root;
						name = ((root != null) ? ((Object)root).name : null);
					}
				}
				string text = Utils.UnClonifiedName((string)name);
				if (Utility.IsNullOrWhiteSpace(text))
				{
					Logging log = Log;
					object obj;
					if (hitCollider == null)
					{
						obj = null;
					}
					else
					{
						Transform transform2 = ((Component)hitCollider).transform;
						if (transform2 == null)
						{
							obj = null;
						}
						else
						{
							Transform root2 = transform2.root;
							obj = ((root2 != null) ? ((Object)root2).name : null);
						}
					}
					log.Info("Can't determine original name " + (string?)obj);
					return;
				}
				Log.Debug(((attacker != null) ? attacker.GetHoverName() : null) + " hit " + text);
				if (creatureTrophyMap.TryGetValue(text, out var value))
				{
					if (trophyCollection.TryGetValue(value, out var value2))
					{
						ApplySlayerBonus(ref hit, Mathf.Min(value2, (float)Cfg.trophyCap.Value));
					}
					else
					{
						Log.Debug("Can't find " + value + " in slayer collection");
					}
				}
				else
				{
					Log.Debug("Can't find hit original " + text + " slayerSkill");
				}
			}
			if (attacker.IsPlayer() || (@bool && Cfg.tamesSlay.Value))
			{
				Log.Debug("Player tapping original");
				ZDO zDO2 = ___m_nview.GetZDO();
				zDO2.Set(UNIQUE_ID, true);
				zDO2.SetOwner(attacker.GetOwner());
			}
		}
	}

	[HarmonyPatch(typeof(Player), "Save")]
	public static class Player_Save_Patch
	{
		[HarmonyPrefix]
		public static void Player_Save_Patch_Prefix(Player __instance, ZPackage pkg)
		{
			Log.Debug("Player_Save_Patch_Prefix");
			if (customData != null)
			{
				string text = Utils.SerializeFromDictionary(",", ":", trophyCollection);
				customData.Set(COLLECTION_ID, text);
				Log.Debug("Serializing and adding trophy collection " + text);
				customData.PreSaveSync();
			}
		}
	}

	[HarmonyPatch(typeof(Player), "OnSpawned")]
	public static class Player_OnSpawned_Patch
	{
		[HarmonyPostfix]
		public static void Player_OnSpawned_Patch_Postfix(Player __instance)
		{
			Log.Debug("Player_OnSpawned_Patch_Postfix");
			if (ZNet.m_world == null)
			{
				return;
			}
			customData = new CustomDataWrapper(__instance.m_customData, UNIQUE_ID);
			string text = customData.Get(COLLECTION_ID);
			if (text != null)
			{
				Utils.DeserializeToDictionary(text, ",", ":", ref trophyCollection);
				Log.Debug("Deserialized trophy string " + text);
			}
			if (trophyCollection.Count <= 0 || trophyCollection.Keys.First().StartsWith("$"))
			{
				return;
			}
			Log.Info("Remapping trophy collection to newer version");
			Dictionary<string, float> dictionary = new Dictionary<string, float>();
			Dictionary<string, string> dictionary2 = new Dictionary<string, string>
			{
				{ "Greydwarf Brute", "Greydwarf brute" },
				{ "Greydwarf Shamen", "Greydwarf shamen" },
				{ "Draugr Elite", "Drauger elite" }
			};
			List<string> list = new List<string>();
			foreach (string key2 in dictionary2.Keys)
			{
				if (trophyCollection.TryGetValue(key2, out var value))
				{
					string key = dictionary2[key2];
					if (trophyCollection.ContainsKey(key))
					{
						trophyCollection[key] += value;
					}
					else
					{
						trophyCollection.Add(key, value);
					}
					list.Add(key2);
				}
			}
			foreach (string item in list)
			{
				trophyCollection.Remove(item);
			}
			foreach (string key3 in trophyCollection.Keys)
			{
				Log.Debug("Remapping " + key3);
				if (nameToTokenMap.TryGetValue(key3, out var value2))
				{
					Log.Debug("Found " + key3 + " with new key " + value2 + " from name-to-token map");
					dictionary.Add(value2, trophyCollection[key3]);
				}
				else
				{
					Log.Debug("Couldn't find " + key3 + " in name-to-token map");
				}
			}
			trophyCollection = dictionary;
			text = Utils.SerializeFromDictionary(",", ":", trophyCollection);
			Log.Debug("New trophy string " + text);
		}
	}

	[HarmonyPatch(typeof(Skills), "LowerAllSkills")]
	private static class Skills_LowerAllSkills_Patch
	{
		[HarmonyPostfix]
		private static void Skills_LowerAllSkills_Postfix(Skills __instance, float factor)
		{
			Log.Debug("Skills_LowerAllSkills_Patch_Postfix");
			if (!Cfg.lowerSkillsOnDeath.Value)
			{
				return;
			}
			foreach (string item in new List<string>(trophyCollection.Keys))
			{
				if (trophyCollection[item] < (float)Cfg.trophyCap.Value)
				{
					float num = trophyCollection[item] * factor;
					trophyCollection[item] -= num;
				}
			}
		}
	}

	[HarmonyPatch(typeof(Skills), "CheatRaiseSkill")]
	private static class Skills_CheatRaiseSkill_Patch
	{
		private static bool Prefix(string name, float value)
		{
			Logging.GetLogger().Debug("Skills CheatRaiseSkill Prefix");
			if (Cfg.allowCheats.Value)
			{
				if (name.ToLower() == "all")
				{
					foreach (string item in new List<string>(trophyCollection.Keys))
					{
						float num = trophyCollection[item] + value;
						num = Mathf.Clamp(num, 0f, (float)Cfg.trophyCap.Value);
						trophyCollection[item] = num;
					}
					Console.instance.Print($"All Slayer skills increased by {value} unless capped.");
					return true;
				}
				name = name.Replace('_', ' ');
				if (nameToTokenMap.TryGetValue(name, out var value2) && trophyCollection.TryGetValue(value2, out var value3))
				{
					value3 += value;
					value3 = Mathf.Clamp(value3, 0f, (float)Cfg.trophyCap.Value);
					trophyCollection[value2] = value3;
					Console.instance.Print($"Slayer skill {name} = {value3}");
					return false;
				}
			}
			else
			{
				Log.Debug("SlayerSkills cheats are not enabled");
			}
			return true;
		}
	}

	[HarmonyPatch(typeof(Skills), "CheatResetSkill")]
	private static class Skills_CheatResetSkill_Patch
	{
		private static bool Prefix(string name)
		{
			Logging.GetLogger().Debug("Skills CheatResetSkill Prefix");
			if (Cfg.allowCheats.Value)
			{
				if (name.ToLower() == "all")
				{
					foreach (string item in new List<string>(trophyCollection.Keys))
					{
						trophyCollection[item] = 0f;
					}
					Console.instance.Print("All Slayer skills reset");
					return true;
				}
				name = name.Replace('_', ' ');
				if (nameToTokenMap.TryGetValue(name, out var value) && trophyCollection.ContainsKey(value))
				{
					trophyCollection[value] = 0f;
					Console.instance.Print("Slayer skill " + name + " reset");
					return false;
				}
			}
			else
			{
				Log.Debug("SlayerSkills cheats are not enabled");
			}
			return true;
		}
	}

	private static SlayerSkills _modInstance;

	private const string MOD_VERSION = "1.0.13";

	private static string Mod = "SlayerSkills";

	private static string LcMod = Mod.ToLower();

	public static Logging Log;

	public static string UNIQUE_ID = Mod + "_1847_";

	public static string COLLECTION_ID = UNIQUE_ID + "_C";

	private static CustomDataWrapper customData = null;

	private static IDictionary<string, float> trophyCollection = new Dictionary<string, float>();

	private static IDictionary<string, string> creatureTrophyMap = new Dictionary<string, string>();

	private static IDictionary<string, string> nameToTokenMap = new Dictionary<string, string>();

	private static CreatureInfo _tempCreatureInfo = null;

	private static string colorString = "#00FFFF";

	private static Harmony harmony = null;

	public static SlayerSkills GetInstance()
	{
		return _modInstance;
	}

	private void Awake()
	{
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_0020: Expected O, but got Unknown
		_modInstance = this;
		harmony = new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID);
		harmony.PatchAll(Assembly.GetExecutingAssembly());
		ConfigureMod();
		Log.Info("Awake");
	}

	private void ConfigureMod()
	{
		Log = Logging.GetLogger(Logging.LogLevels.Info, Mod);
		ServerConfiguration.Instance.Setup(((BaseUnityPlugin)this).Config, (BaseUnityPlugin)(object)_modInstance);
		Cfg.BepInExConfig((BaseUnityPlugin)(object)_modInstance);
		ServerConfiguration.Instance.CreateConfigWatcher();
	}

	public static void ChangeLogging(object s, EventArgs e)
	{
		SettingChangedEventArgs val = (SettingChangedEventArgs)(object)((e is SettingChangedEventArgs) ? e : null);
		Log.Debug($"ChangeLog {val.ChangedSetting.Definition.Key} to {val.ChangedSetting.BoxedValue}");
		Log.LogLevel = Cfg.debugLevel.Value;
	}

	public static void ChangeColor(object s, EventArgs e)
	{
		//IL_0040: Unknown result type (might be due to invalid IL or missing references)
		SettingChangedEventArgs val = (SettingChangedEventArgs)(object)((e is SettingChangedEventArgs) ? e : null);
		Log.Debug($"ChangeColor {val.ChangedSetting.Definition.Key} to {val.ChangedSetting.BoxedValue}");
		colorString = "#" + ColorUtility.ToHtmlStringRGB(Cfg.skillColor.Value);
	}

	private void OnDestroy()
	{
		harmony.UnpatchSelf();
	}

	private static int GetVersionID(string versionString)
	{
		string[] array = versionString.Split(new char[1] { '.' });
		return int.Parse(array[0]) * 10000 + int.Parse(array[1]) * 1000 + int.Parse(array[2]);
	}

	private static bool OkToKey(Player player)
	{
		if (!Chat.instance.HasFocus() && !Console.IsVisible() && (Object)(object)TextViewer.instance != (Object)null && !TextViewer.instance.IsVisible() && !GameCamera.InFreeFly() && !Minimap.IsOpen() && !TextInput.IsVisible() && !StoreGui.IsVisible() && !((Character)player).InCutscene() && !((Character)player).InBed() && !((Character)player).IsTeleporting() && !((Character)player).IsDead())
		{
			return !((Character)player).InPlaceMode();
		}
		return false;
	}

	private static void KeypressEntryPoint()
	{
		_ = Player.m_localPlayer;
		Log.Debug("KeypressEntryPoint");
	}

	private static string GetTrophyDisplayName(string trophyName)
	{
		string text = Localization.instance.Localize(trophyName);
		string text2 = (text.EndsWith(" trophy") ? text.Substring(0, text.Length - 7) : text);
		Log.Debug("Trophy name " + trophyName + " Localized name " + text + " Display name " + text2);
		return text2;
	}

	private static string GetTrophyDisplayNameCaseInsensitive(string trophyName)
	{
		string text = Localization.instance.Localize(trophyName);
		if (!text.EndsWith(" trophy"))
		{
			return text;
		}
		return text.Substring(0, text.Length - 7);
	}

	private static void ApplySlayerBonus(ref HitData hitData, float skillLevel)
	{
		skillLevel = Mathf.Clamp(skillLevel, 0f, (float)Cfg.trophyCap.Value);
		float num = skillLevel / (float)Cfg.trophyCap.Value;
		float num2 = (float)Cfg.damageCap.Value / 100f * num;
		Log.Debug($"Before slayer Level {skillLevel} multiplier {num2} blunt {hitData.m_damage.m_blunt} slash {hitData.m_damage.m_slash} pierce {hitData.m_damage.m_pierce} fire {hitData.m_damage.m_fire} frost {hitData.m_damage.m_frost} lightning {hitData.m_damage.m_lightning} poison {hitData.m_damage.m_poison} spirit {hitData.m_damage.m_spirit}");
		if (Cfg.damagePhysical.Value)
		{
			hitData.m_damage.m_blunt += hitData.m_damage.m_blunt * num2;
			hitData.m_damage.m_slash += hitData.m_damage.m_slash * num2;
			hitData.m_damage.m_pierce += hitData.m_damage.m_pierce * num2;
		}
		if (Cfg.damageElemental.Value)
		{
			hitData.m_damage.m_fire += hitData.m_damage.m_fire * num2;
			hitData.m_damage.m_frost += hitData.m_damage.m_frost * num2;
			hitData.m_damage.m_lightning += hitData.m_damage.m_lightning * num2;
		}
		if (Cfg.damageOther.Value)
		{
			hitData.m_damage.m_spirit += hitData.m_damage.m_spirit * num2;
			hitData.m_damage.m_poison += hitData.m_damage.m_poison * num2;
		}
		Log.Debug($"After slayer Level {skillLevel} multiplier {num2} blunt {hitData.m_damage.m_blunt} slash {hitData.m_damage.m_slash} pierce {hitData.m_damage.m_pierce} fire {hitData.m_damage.m_fire} frost {hitData.m_damage.m_frost} lightning {hitData.m_damage.m_lightning} poison {hitData.m_damage.m_poison} spirit {hitData.m_damage.m_spirit}");
	}

	public static void BuildCreatureTrophyMap()
	{
		//IL_0099: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a0: Invalid comparison between Unknown and I4
		CharacterDrop val = default(CharacterDrop);
		ItemDrop val2 = default(ItemDrop);
		foreach (GameObject prefab in ZNetScene.instance.m_prefabs)
		{
			Character component = (Character)(object)prefab.GetComponent<Humanoid>();
			if ((Object)(object)component == (Object)null)
			{
				component = prefab.GetComponent<Character>();
			}
			if (!((Object)(object)component != (Object)null) || !prefab.TryGetComponent<CharacterDrop>(ref val))
			{
				continue;
			}
			foreach (Drop drop in val.m_drops)
			{
				if ((Object)(object)drop.m_prefab != (Object)null && drop.m_prefab.TryGetComponent<ItemDrop>(ref val2) && (int)val2.m_itemData.m_shared.m_itemType == 13)
				{
					string name = val2.m_itemData.m_shared.m_name;
					string trophyDisplayName = GetTrophyDisplayName(name);
					if (!creatureTrophyMap.ContainsKey(((Object)component).name))
					{
						Log.Debug("Adding " + ((Object)component).name + " " + name + " to original trophy map");
						creatureTrophyMap.Add(((Object)component).name, name);
					}
					if (!nameToTokenMap.ContainsKey(trophyDisplayName))
					{
						Log.Debug("Adding " + trophyDisplayName + " " + name + " to name-to-token map");
						nameToTokenMap.Add(trophyDisplayName, name);
					}
				}
			}
		}
	}

	private static int FlooredLevel(float level)
	{
		return Mathf.FloorToInt(level);
	}

	private static void RaiseStat(string itemName, float amt)
	{
		//IL_0180: Unknown result type (might be due to invalid IL or missing references)
		//IL_0187: Unknown result type (might be due to invalid IL or missing references)
		Log.Debug("RaiseStat");
		bool flag = false;
		string text = GetTrophyDisplayName(itemName);
		if (text.ToLower().EndsWith(" trophy"))
		{
			text = text.Substring(0, text.Length - 7);
		}
		Log.Debug(itemName + " translates to trophy name " + text);
		if (!trophyCollection.ContainsKey(itemName))
		{
			trophyCollection.Add(itemName, amt);
			int num = FlooredLevel(amt);
			if (num >= 1)
			{
				((Character)Player.m_localPlayer).Message((MessageType)2, $"{text} Slayer Level {num}", 0, (Sprite)null);
				flag = true;
			}
			Log.Debug("Adding " + text + " to slayer collection");
		}
		else
		{
			int num2 = FlooredLevel(trophyCollection[itemName]);
			if (num2 < Cfg.trophyCap.Value)
			{
				trophyCollection[itemName] += amt;
				if (trophyCollection[itemName] > (float)Cfg.trophyCap.Value)
				{
					trophyCollection[itemName] = Cfg.trophyCap.Value;
				}
				int num3 = FlooredLevel(trophyCollection[itemName]);
				if (num3 > num2)
				{
					((Character)Player.m_localPlayer).Message((MessageType)1, $"{text} Slayer Level {num3}", 0, (Sprite)null);
					flag = true;
				}
			}
			else
			{
				Log.Debug("Trophy cap reached");
			}
		}
		if (flag)
		{
			Player localPlayer = Player.m_localPlayer;
			Transform head = ((Character)localPlayer).m_head;
			localPlayer.m_skillLevelupEffects.Create(head.position, head.rotation, head, 1f, -1);
		}
	}

	private static void RPC_RaiseSlayerStat(long id, string itemName, float amt)
	{
		Log.Debug("RPC_RaiseSlayerStat");
		RaiseStat(itemName, amt);
	}

	private static List<Player> GetPlayersInRange(Vector3 point, float range, List<Player> allPlayers)
	{
		//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)
		List<Player> list = new List<Player>();
		foreach (Player allPlayer in allPlayers)
		{
			if (Vector3.Distance(((Component)allPlayer).transform.position, point) < range)
			{
				list.Add(allPlayer);
			}
		}
		return list;
	}

	private static void InitiateRaiseStat(string itemName, float amount, Vector3 center)
	{
		//IL_0033: Unknown result type (might be due to invalid IL or missing references)
		//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
		//IL_019a: Unknown result type (might be due to invalid IL or missing references)
		//IL_019f: Unknown result type (might be due to invalid IL or missing references)
		Log.Debug("IntitiateRaiseStat");
		List<Player> allPlayers = Player.GetAllPlayers();
		int num = allPlayers.Count();
		if (num > 1 && Cfg.assignPoints.Value != Points.KillingBlow)
		{
			List<Player> playersInRange = GetPlayersInRange(center, Cfg.trophyDistance.Value, allPlayers);
			Log.Debug($"Players in range {playersInRange.Count}");
			if (playersInRange.Count < num)
			{
				Log.Info($"{num - playersInRange.Count} player(s) not in range of the dropped trophy.");
			}
			if (playersInRange.Count <= 0)
			{
				return;
			}
			if (Cfg.assignPoints.Value != 0)
			{
				if (Cfg.assignPoints.Value == Points.Distribute)
				{
					amount /= (float)playersInRange.Count;
				}
				{
					ZNetView val = default(ZNetView);
					foreach (Player item in playersInRange)
					{
						if (((Component)item).TryGetComponent<ZNetView>(ref val) && val.IsValid() && val.GetZDO().m_uid != ZDOID.None)
						{
							Log.Debug($"Invoking RPC on {val.GetZDO().GetOwner()} player {item.GetPlayerName()}");
							ZRoutedRpc.instance.InvokeRoutedRPC(val.GetZDO().GetOwner(), "RaiseSlayerStat", new object[2] { itemName, amount });
						}
					}
					return;
				}
			}
			int index = Random.Range(0, playersInRange.Count);
			ZNetView val2 = default(ZNetView);
			if (((Component)playersInRange[index]).TryGetComponent<ZNetView>(ref val2) && val2.IsValid() && val2.GetZDO().m_uid != ZDOID.None)
			{
				Log.Debug($"Invoking RPC on {val2.GetZDO().GetOwner()} random player {playersInRange[index].GetPlayerName()}");
				ZRoutedRpc.instance.InvokeRoutedRPC(val2.GetZDO().GetOwner(), "RaiseSlayerStat", new object[2] { itemName, amount });
			}
		}
		else
		{
			RaiseStat(itemName, amount);
		}
	}
}