Decompiled source of Svimma v1.0.0

plugins/Svimma/Svimma.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using Ezomic.Core;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")]
[assembly: AssemblyCompany("Thijssen Software")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("Copyright (c) 2026 Robbin Thijssen")]
[assembly: AssemblyDescription("Keep and use weapons, pickaxes and fishing rods while swimming.")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+7d770a75cae966f353b8884d27f2e5546e867f89")]
[assembly: AssemblyProduct("Svimma")]
[assembly: AssemblyTitle("Svimma")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Svimma
{
	internal static class DevConsole
	{
		[HarmonyPatch(typeof(Terminal), "InitTerminal")]
		internal static class Hook
		{
			[CompilerGenerated]
			private static class <>O
			{
				public static ConsoleEvent <0>__OnCommand;
			}

			private static void Postfix()
			{
				//IL_003d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0028: Unknown result type (might be due to invalid IL or missing references)
				//IL_002d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0033: Expected O, but got Unknown
				if (!_registered)
				{
					_registered = true;
					object obj = <>O.<0>__OnCommand;
					if (obj == null)
					{
						ConsoleEvent val = OnCommand;
						<>O.<0>__OnCommand = val;
						obj = (object)val;
					}
					new ConsoleCommand("svimma", "[equip <item> | swing | cost] - what you are doing in the water, and the three things Svimma changes there. With no word it reports", (ConsoleEvent)obj, false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
				}
			}
		}

		private static bool _registered;

		private static void OnCommand(ConsoleEventArgs args)
		{
			Terminal context = args.Context;
			if ((Object)(object)context == (Object)null)
			{
				return;
			}
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				context.AddString("svimma: no player");
				return;
			}
			string text = ((args.Length > 1) ? args[1].ToLowerInvariant() : "");
			if (text == null || text.Length != 0)
			{
				switch (text)
				{
				case "equip":
					context.AddString(Equip(localPlayer, (args.Length > 2) ? args[2] : ""));
					break;
				case "swing":
					context.AddString(Swing(localPlayer));
					break;
				case "cost":
					context.AddString(Cost());
					break;
				default:
					context.AddString("svimma: unknown '" + args[1] + "'. Try svimma, svimma equip <item>, svimma swing, svimma cost.");
					break;
				}
			}
			else
			{
				context.AddString(State(localPlayer));
			}
		}

		private static string State(Player player)
		{
			StringBuilder stringBuilder = new StringBuilder("svimma");
			stringBuilder.Append(" enabled=").Append(Word(SvimmaConfig.Enabled.Value));
			stringBuilder.Append(" swimming=").Append(Word(((Character)player).IsSwimming()));
			stringBuilder.Append(" deep=").Append(Word(Gate.Deep((Character)(object)player)));
			stringBuilder.Append(" right=").Append(Kinds.Name(Gate.Right((Humanoid)(object)player)));
			stringBuilder.Append(" left=").Append(Kinds.Name(Gate.Left((Humanoid)(object)player)));
			stringBuilder.Append(" blocking=").Append(Word(((Character)player).IsBlocking()));
			stringBuilder.Append(" stamina=").Append(player.GetStamina().ToString("0.0", CultureInfo.InvariantCulture));
			return stringBuilder.ToString();
		}

		private static string Equip(Player player, string prefab)
		{
			if (prefab.Length == 0)
			{
				return "svimma equip: which item? (a prefab name, like SwordBronze)";
			}
			foreach (ItemData allItem in ((Humanoid)player).GetInventory().GetAllItems())
			{
				if (allItem != null && !((Object)(object)allItem.m_dropPrefab == (Object)null) && string.Equals(((Object)allItem.m_dropPrefab).name, prefab, StringComparison.OrdinalIgnoreCase))
				{
					if (allItem.m_equipped)
					{
						return "svimma equip=already item=" + ((Object)allItem.m_dropPrefab).name;
					}
					bool flag = ((Humanoid)player).EquipItem(allItem, true);
					return "svimma equip=" + (flag ? "ok" : "refused") + " item=" + ((Object)allItem.m_dropPrefab).name;
				}
			}
			return "svimma equip=missing item=" + prefab + " (give it first)";
		}

		private static string Swing(Player player)
		{
			Gate.LastPaid = -1f;
			Gate.LastVanilla = -1f;
			bool flag = ((Character)player).StartAttack((Character)null, false);
			return "svimma swing=" + (flag ? "started" : "refused") + " stamina=" + player.GetStamina().ToString("0.0", CultureInfo.InvariantCulture);
		}

		private static string Cost()
		{
			if (Gate.LastPaid < 0f)
			{
				return "svimma cost=none (no deep swing has been priced since the last svimma swing)";
			}
			float num = ((Gate.LastVanilla > 0f) ? (Gate.LastPaid / Gate.LastVanilla) : 0f);
			return "svimma cost=" + Gate.LastPaid.ToString("0.00", CultureInfo.InvariantCulture) + " vanilla=" + Gate.LastVanilla.ToString("0.00", CultureInfo.InvariantCulture) + " ratio=" + num.ToString("0.00", CultureInfo.InvariantCulture);
		}

		private static string Word(bool value)
		{
			if (!value)
			{
				return "no";
			}
			return "yes";
		}
	}
	internal static class Gate
	{
		internal static ItemData Equipping;

		internal static float LastPaid = -1f;

		internal static float LastVanilla = -1f;

		private static FieldRef<Humanoid, ItemData> _hiddenLeft;

		private static FieldRef<Humanoid, ItemData> _hiddenRight;

		private static FieldRef<Humanoid, ItemData> _left;

		private static FieldRef<Humanoid, ItemData> _right;

		private static bool _handsBound;

		internal static ItemData Right(Humanoid humanoid)
		{
			if (!BindHands())
			{
				return null;
			}
			return _right.Invoke(humanoid);
		}

		internal static ItemData Left(Humanoid humanoid)
		{
			if (!BindHands())
			{
				return null;
			}
			return _left.Invoke(humanoid);
		}

		internal static bool Deep(Character character)
		{
			if ((Object)(object)character != (Object)null && character.IsSwimming())
			{
				return !character.IsOnGround();
			}
			return false;
		}

		internal static bool Active(Character character)
		{
			if (SvimmaConfig.Enabled.Value && (Object)(object)Player.m_localPlayer != (Object)null)
			{
				return (Object)(object)character == (Object)(object)Player.m_localPlayer;
			}
			return false;
		}

		internal static bool HidesHands(Character character)
		{
			if (!character.IsSwimming())
			{
				return false;
			}
			if (!Active(character))
			{
				return true;
			}
			Humanoid val = (Humanoid)(object)((character is Humanoid) ? character : null);
			if ((Object)(object)val == (Object)null || !BindHands())
			{
				return true;
			}
			bool flag = Kinds.Allowed(_right.Invoke(val)) && Kinds.Allowed(_left.Invoke(val));
			if (flag && SvimmaConfig.Verbose.Value && Deep(character))
			{
				SvimmaPlugin.Log.LogInfo((object)("Deep water: hands stay out (" + Kinds.Name(_right.Invoke(val)) + ", " + Kinds.Name(_left.Invoke(val)) + ")."));
			}
			return !flag;
		}

		internal static bool BlocksEquip(Character character)
		{
			if (!character.IsSwimming())
			{
				return false;
			}
			if (!Active(character))
			{
				return true;
			}
			if (Equipping == null)
			{
				return true;
			}
			bool flag = Kinds.Allowed(Equipping);
			if (SvimmaConfig.Verbose.Value && Deep(character))
			{
				SvimmaPlugin.Log.LogInfo((object)("Deep water: equip " + Kinds.Name(Equipping) + (flag ? " allowed." : " refused.")));
			}
			return !flag;
		}

		internal static bool BlocksShowHands(Character character)
		{
			if (!character.IsSwimming())
			{
				return false;
			}
			if (!Active(character))
			{
				return true;
			}
			Humanoid val = (Humanoid)(object)((character is Humanoid) ? character : null);
			if ((Object)(object)val == (Object)null)
			{
				return true;
			}
			if (!BindHands())
			{
				return true;
			}
			if (Kinds.Allowed(_hiddenLeft.Invoke(val)))
			{
				return !Kinds.Allowed(_hiddenRight.Invoke(val));
			}
			return true;
		}

		private static bool BindHands()
		{
			if (_handsBound)
			{
				return _right != null;
			}
			_handsBound = true;
			try
			{
				_hiddenLeft = AccessTools.FieldRefAccess<Humanoid, ItemData>("m_hiddenLeftItem");
				_hiddenRight = AccessTools.FieldRefAccess<Humanoid, ItemData>("m_hiddenRightItem");
				_left = AccessTools.FieldRefAccess<Humanoid, ItemData>("m_leftItem");
				_right = AccessTools.FieldRefAccess<Humanoid, ItemData>("m_rightItem");
			}
			catch (Exception ex)
			{
				_hiddenLeft = null;
				_hiddenRight = null;
				_left = null;
				_right = null;
				SvimmaPlugin.Log.LogWarning((object)("Could not read the hand items, so swimming puts them away as vanilla does: " + ex.Message));
			}
			return _right != null;
		}
	}
	internal static class Kinds
	{
		internal static bool Allowed(ItemData item)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Invalid comparison between Unknown and I4
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Invalid comparison between Unknown and I4
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Invalid comparison between Unknown and I4
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Invalid comparison between Unknown and I4
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: 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)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Expected I4, but got Unknown
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Invalid comparison between Unknown and I4
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Invalid comparison between Unknown and I4
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Invalid comparison between Unknown and I4
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Invalid comparison between Unknown and I4
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Invalid comparison between Unknown and I4
			if (item == null)
			{
				return true;
			}
			SharedData shared = item.m_shared;
			if ((Object)(object)shared.m_buildPieces != (Object)null)
			{
				return SvimmaConfig.AllowBuildingTools.Value;
			}
			ItemType itemType = shared.m_itemType;
			if ((int)itemType <= 14)
			{
				if (itemType - 3 > 1)
				{
					if ((int)itemType == 5)
					{
						return true;
					}
					if ((int)itemType != 14)
					{
						goto IL_0057;
					}
				}
			}
			else
			{
				if ((int)itemType == 15)
				{
					return false;
				}
				if ((int)itemType != 19 && (int)itemType != 22)
				{
					goto IL_0057;
				}
			}
			SkillType skillType = shared.m_skillType;
			switch (skillType - 8)
			{
			default:
				if ((int)skillType == 104)
				{
					return SvimmaConfig.AllowFishing.Value;
				}
				break;
			case 4:
				return SvimmaConfig.AllowPickaxes.Value;
			case 6:
				return SvimmaConfig.AllowCrossbows.Value;
			case 0:
				return SvimmaConfig.AllowBows.Value;
			case 1:
			case 2:
				return SvimmaConfig.AllowStaffs.Value;
			case 3:
			case 5:
				break;
			}
			if ((int)shared.m_itemType == 4)
			{
				return SvimmaConfig.AllowBows.Value;
			}
			return SvimmaConfig.AllowMelee.Value;
			IL_0057:
			return false;
		}

		internal static string Name(ItemData item)
		{
			if (item == null)
			{
				return "-";
			}
			if (!((Object)(object)item.m_dropPrefab != (Object)null))
			{
				return item.m_shared.m_name;
			}
			return ((Object)item.m_dropPrefab).name;
		}
	}
	internal static class SvimmaConfig
	{
		internal static ConfigEntry<bool> Enabled;

		internal static ConfigEntry<bool> AllowMelee;

		internal static ConfigEntry<bool> AllowPickaxes;

		internal static ConfigEntry<bool> AllowFishing;

		internal static ConfigEntry<bool> AllowBows;

		internal static ConfigEntry<bool> AllowCrossbows;

		internal static ConfigEntry<bool> AllowStaffs;

		internal static ConfigEntry<bool> AllowBuildingTools;

		internal static ConfigEntry<float> DeepSwingStaminaMultiplier;

		internal static ConfigEntry<bool> AllowBlocking;

		internal static ConfigEntry<bool> Verbose;

		internal static void Bind(ConfigFile cfg)
		{
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Expected O, but got Unknown
			Enabled = cfg.Bind<bool>("Svimma", "Enabled", true, "Off leaves the plugin loaded and changing nothing: swimming puts your hands away exactly as vanilla does.");
			AllowMelee = cfg.Bind<bool>("What may be used", "AllowMelee", true, "Swords, knives, clubs, spears, polearms, axes and anything else swung or thrust that is not claimed by one of the switches below. Shields stay in hand with whatever else is allowed. Torches never do: a flame is put out the way vanilla puts it away, and there is no switch for that.");
			AllowPickaxes = cfg.Bind<bool>("What may be used", "AllowPickaxes", true, "Pickaxes, for deposits you can reach from the water but not stand beside.");
			AllowFishing = cfg.Bind<bool>("What may be used", "AllowFishing", true, "The fishing rod. Fishing from the water is the case the ticket was written around: the rod is a tool, not a weapon, and there is nothing in it that wants a dry foot.");
			AllowBows = cfg.Bind<bool>("What may be used", "AllowBows", false, "Bows. Off by default: a bow in deep water lets you fight anything on shore with no cost for being out of reach, which is a bigger change than swinging a sword.");
			AllowCrossbows = cfg.Bind<bool>("What may be used", "AllowCrossbows", false, "Crossbows. Off for the same reason as bows, and separately because a crossbow's reload is a second action in a state that is already draining stamina.");
			AllowStaffs = cfg.Bind<bool>("What may be used", "AllowStaffs", false, "Staffs (elemental and blood magic). Off by default: they spend eitr, not stamina, so the swim cost below does not touch them, and that would make them free to use in a place everything else is made to pay.");
			AllowBuildingTools = cfg.Bind<bool>("What may be used", "AllowBuildingTools", false, "The hammer, the hoe and the cultivator. Off by default: building on water you are swimming in puts pieces and terrain changes where you could not have stood to make them. Turn it on only if that is what you want.");
			DeepSwingStaminaMultiplier = cfg.Bind<float>("Cost", "DeepSwingStaminaMultiplier", 1.5f, new ConfigDescription("What a swing costs in stamina while you are swimming in deep water, as a multiple of what the same swing costs on land. 1 = no extra. Wading is not deep water: standing on the bottom, even up to the neck, costs the land price. Remember an empty bar while swimming is drowning, and a swing is refused when you cannot pay for it, exactly as on land.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 5f), Array.Empty<object>()));
			AllowBlocking = cfg.Bind<bool>("What may be used", "AllowBlocking", false, "Off: blocking is switched off while you swim in deep water, so a shield in hand is carried and does not block. On: blocking works as on land. Off by default because you cannot plant your feet in the water, and a block that cannot cost you footing is a block that costs nothing.");
			Verbose = cfg.Bind<bool>("Svimma", "Verbose", false, "Write each decision to BepInEx/LogOutput.log: what was allowed to stay in hand in deep water and what a swing cost. Off unless something looks wrong.");
		}
	}
	internal static class SvimmaPatches
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(Player), "OnSpawned")]
		private static void OnSpawned(Player __instance)
		{
			if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && SvimmaConfig.Enabled.Value && SvimmaConfig.Verbose.Value)
			{
				SvimmaPlugin.Log.LogInfo((object)"Player spawned - patches are live.");
			}
		}
	}
	internal static class Swap
	{
		private static readonly MethodInfo IsSwimming = AccessTools.Method(typeof(Character), "IsSwimming", (Type[])null, (Type[])null);

		internal static List<CodeInstruction> Replace(IEnumerable<CodeInstruction> code, string replacement, string where, int expected)
		{
			MethodInfo operand = AccessTools.Method(typeof(Gate), replacement, (Type[])null, (Type[])null);
			List<CodeInstruction> list = new List<CodeInstruction>(code);
			int num = 0;
			foreach (CodeInstruction item in list)
			{
				if (!(item.opcode != OpCodes.Call) || !(item.opcode != OpCodes.Callvirt))
				{
					MethodInfo methodInfo = item.operand as MethodInfo;
					if (!(methodInfo == null) && !(methodInfo != IsSwimming))
					{
						item.opcode = OpCodes.Call;
						item.operand = operand;
						num++;
					}
				}
			}
			if (num == expected)
			{
				SvimmaPlugin.Log.LogInfo((object)(where + ": replaced " + num + " IsSwimming call(s) with Gate." + replacement + "."));
			}
			else
			{
				SvimmaPlugin.Log.LogWarning((object)(where + ": expected to replace " + expected + " IsSwimming call(s) and replaced " + num + ". The game has changed here and this part of Svimma does nothing."));
			}
			return list;
		}
	}
	[HarmonyPatch(typeof(Humanoid), "UpdateEquipment")]
	internal static class HoldPatch
	{
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> code)
		{
			return Swap.Replace(code, "HidesHands", "Humanoid.UpdateEquipment", 1);
		}
	}
	[HarmonyPatch(typeof(Humanoid), "EquipItem")]
	internal static class EquipPatch
	{
		private static void Prefix(ItemData item)
		{
			Gate.Equipping = item;
		}

		private static void Finalizer()
		{
			Gate.Equipping = null;
		}

		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> code)
		{
			return Swap.Replace(code, "BlocksEquip", "Humanoid.EquipItem", 1);
		}
	}
	[HarmonyPatch(typeof(Player), "Update")]
	internal static class DrawPatch
	{
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> code)
		{
			return Swap.Replace(code, "BlocksShowHands", "Player.Update", 1);
		}
	}
	[HarmonyPatch(typeof(Humanoid), "IsBlocking")]
	internal static class BlockPatch
	{
		private static void Postfix(Humanoid __instance, ref bool __result)
		{
			if (__result && !SvimmaConfig.AllowBlocking.Value && Gate.Active((Character)(object)__instance) && Gate.Deep((Character)(object)__instance))
			{
				__result = false;
			}
		}
	}
	[HarmonyPatch(typeof(Attack), "GetAttackStamina")]
	internal static class CostPatch
	{
		private static FieldRef<Attack, Humanoid> _owner;

		private static bool _bound;

		private static void Postfix(Attack __instance, ref float __result)
		{
			if (__result <= 0f)
			{
				return;
			}
			float value = SvimmaConfig.DeepSwingStaminaMultiplier.Value;
			if (value == 1f || !Bind())
			{
				return;
			}
			Humanoid val = _owner.Invoke(__instance);
			if (!((Object)(object)val == (Object)null) && Gate.Active((Character)(object)val) && Gate.Deep((Character)(object)val))
			{
				Gate.LastVanilla = __result;
				__result *= value;
				Gate.LastPaid = __result;
				if (SvimmaConfig.Verbose.Value)
				{
					SvimmaPlugin.Log.LogInfo((object)("Deep swing: vanilla " + Gate.LastVanilla.ToString("0.0") + " stamina, charged " + Gate.LastPaid.ToString("0.0") + "."));
				}
			}
		}

		private static bool Bind()
		{
			if (_bound)
			{
				return _owner != null;
			}
			_bound = true;
			try
			{
				_owner = AccessTools.FieldRefAccess<Attack, Humanoid>("m_character");
			}
			catch (Exception ex)
			{
				_owner = null;
				SvimmaPlugin.Log.LogWarning((object)("Could not read who is swinging, so a deep swing costs the land price: " + ex.Message));
			}
			return _owner != null;
		}
	}
	[BepInPlugin("ezomic.valheim.svimma", "Svimma", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class SvimmaPlugin : BaseUnityPlugin
	{
		public const string PluginGuid = "ezomic.valheim.svimma";

		public const string PluginName = "Svimma";

		public const string PluginVersion = "1.0.0";

		public const string PluginAuthor = "Robbin Thijssen";

		private const string CoreGuid = "ezomic.valheim.core";

		internal static ManualLogSource Log;

		internal static bool CorePresent;

		private Harmony _harmony;

		private void Awake()
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			SvimmaConfig.Bind(((BaseUnityPlugin)this).Config);
			TryRegisterWithCore();
			_harmony = new Harmony("ezomic.valheim.svimma");
			_harmony.PatchAll(typeof(SvimmaPatches));
			_harmony.PatchAll(typeof(HoldPatch));
			_harmony.PatchAll(typeof(EquipPatch));
			_harmony.PatchAll(typeof(DrawPatch));
			_harmony.PatchAll(typeof(BlockPatch));
			_harmony.PatchAll(typeof(CostPatch));
			_harmony.PatchAll(typeof(DevConsole.Hook));
			Log.LogInfo((object)"Svimma 1.0.0 by Robbin Thijssen - ready.");
		}

		private void TryRegisterWithCore()
		{
			CorePresent = Chainloader.PluginInfos.ContainsKey("ezomic.valheim.core");
			if (!CorePresent)
			{
				Log.LogInfo((object)"Core not installed - running standalone, without the version gate.");
			}
			else
			{
				RegisterWithCore();
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private void RegisterWithCore()
		{
			Suite.Register("ezomic.valheim.svimma", "Svimma", "1.0.0", ((BaseUnityPlugin)this).Config, (Requirement)1, (Assembly)null);
			Suite.Sync((ConfigEntryBase)(object)SvimmaConfig.Enabled);
			Suite.Sync((ConfigEntryBase)(object)SvimmaConfig.AllowMelee);
			Suite.Sync((ConfigEntryBase)(object)SvimmaConfig.AllowPickaxes);
			Suite.Sync((ConfigEntryBase)(object)SvimmaConfig.AllowFishing);
			Suite.Sync((ConfigEntryBase)(object)SvimmaConfig.AllowBows);
			Suite.Sync((ConfigEntryBase)(object)SvimmaConfig.AllowCrossbows);
			Suite.Sync((ConfigEntryBase)(object)SvimmaConfig.AllowStaffs);
			Suite.Sync((ConfigEntryBase)(object)SvimmaConfig.AllowBuildingTools);
			Suite.Sync((ConfigEntryBase)(object)SvimmaConfig.DeepSwingStaminaMultiplier);
			Suite.Sync((ConfigEntryBase)(object)SvimmaConfig.AllowBlocking);
			Suite.Local((ConfigEntryBase)(object)SvimmaConfig.Verbose);
		}

		private void OnDestroy()
		{
			if (_harmony != null)
			{
				_harmony.UnpatchSelf();
			}
		}
	}
}