Please disclose if your mod was created primarily using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of Underwater v1.0.9
Underwater.dll
Decompiled 6 months agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using CrystalLib; using HarmonyLib; using UnityEngine; using UnityEngine.InputSystem; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("Underwater")] [assembly: AssemblyDescription("Underwater")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("Crystal")] [assembly: AssemblyProduct("Underwater")] [assembly: AssemblyCopyright("Copyright © 2023 Crystal Ferrai")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("3cdab7b7-951c-4013-8b57-7931e76589d4")] [assembly: AssemblyFileVersion("1.0.9.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyVersion("1.0.9.0")] namespace Underwater; [BepInPlugin("dev.crystal.underwater", "Underwater", "1.0.9.0")] [BepInProcess("valheim.exe")] [BepInProcess("valheim_server.exe")] public class UnderwaterPlugin : BaseUnityPlugin { [HarmonyPatch(typeof(Character))] private static class Character_Patches { [HarmonyPatch("InLiquidDepth")] [HarmonyPrefix] private static bool InLiquidDepth_Prefix(Character __instance, ref float __result) { __result = 0f; if (__instance.IsPlayer()) { return PlayerSwims.Value; } return true; } } [HarmonyPatch(typeof(GameCamera))] private static class GameCamera_Patches { private enum TranspilerState { Searching, Checking, Searching2, Checking2, Updating, Finishing } [CompilerGenerated] private sealed class <GetCameraPosition_Transpiler>d__1 : IEnumerable<CodeInstruction>, IEnumerable, IEnumerator<CodeInstruction>, IDisposable, IEnumerator { private int <>1__state; private CodeInstruction <>2__current; private int <>l__initialThreadId; private IEnumerable<CodeInstruction> instructions; public IEnumerable<CodeInstruction> <>3__instructions; private TranspilerState <state>5__2; private CodeInstruction <instruction1>5__3; private CodeInstruction <instruction2>5__4; private CodeInstruction <instruction3>5__5; private IEnumerator<CodeInstruction> <>7__wrap5; private CodeInstruction <instruction>5__7; CodeInstruction IEnumerator<CodeInstruction>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <GetCameraPosition_Transpiler>d__1(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if (num == -3 || (uint)(num - 1) <= 8u) { try { } finally { <>m__Finally1(); } } <instruction1>5__3 = null; <instruction2>5__4 = null; <instruction3>5__5 = null; <>7__wrap5 = null; <instruction>5__7 = null; <>1__state = -2; } private bool MoveNext() { try { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <state>5__2 = TranspilerState.Searching; <instruction1>5__3 = null; <instruction2>5__4 = null; <instruction3>5__5 = null; <>7__wrap5 = instructions.GetEnumerator(); <>1__state = -3; goto IL_03b3; case 1: <>1__state = -3; goto IL_03ac; case 2: <>1__state = -3; <instruction1>5__3 = null; if (<instruction2>5__4 != null) { <>2__current = <instruction2>5__4; <>1__state = 3; return true; } goto IL_0250; case 3: <>1__state = -3; <instruction2>5__4 = null; goto IL_0250; case 4: <>1__state = -3; <instruction3>5__5 = null; goto IL_0281; case 5: <>1__state = -3; <state>5__2 = TranspilerState.Searching; goto IL_03ac; case 6: <>1__state = -3; <>2__current = <instruction2>5__4; <>1__state = 7; return true; case 7: <>1__state = -3; <>2__current = <instruction>5__7; <>1__state = 8; return true; case 8: <>1__state = -3; <state>5__2 = TranspilerState.Finishing; goto IL_03ac; case 9: { <>1__state = -3; goto IL_03ac; } IL_03ac: <instruction>5__7 = null; goto IL_03b3; IL_0250: if (<instruction3>5__5 != null) { <>2__current = <instruction3>5__5; <>1__state = 4; return true; } goto IL_0281; IL_0281: <>2__current = <instruction>5__7; <>1__state = 5; return true; IL_03b3: if (<>7__wrap5.MoveNext()) { <instruction>5__7 = <>7__wrap5.Current; switch (<state>5__2) { case TranspilerState.Searching: if (<instruction>5__7.opcode == OpCodes.Ldloc_S) { <instruction1>5__3 = <instruction>5__7; <state>5__2 = TranspilerState.Checking; break; } <>2__current = <instruction>5__7; <>1__state = 1; return true; case TranspilerState.Checking: if (<instruction3>5__5 != null && <instruction>5__7.opcode == OpCodes.Call && ((MethodInfo)<instruction>5__7.operand).Name.Equals("GetLiquidLevel")) { <instruction1>5__3 = (<instruction2>5__4 = (<instruction3>5__5 = null)); <state>5__2 = TranspilerState.Searching2; break; } if (<instruction2>5__4 != null && <instruction>5__7.opcode == OpCodes.Ldc_I4_S && (sbyte)<instruction>5__7.operand == 10) { <instruction3>5__5 = <instruction>5__7; break; } if (<instruction>5__7.opcode == OpCodes.Ldc_R4 && (float)<instruction>5__7.operand == 1f) { <instruction2>5__4 = <instruction>5__7; break; } <>2__current = <instruction1>5__3; <>1__state = 2; return true; case TranspilerState.Searching2: if (<instruction>5__7.opcode == OpCodes.Ldarg_0) { <instruction1>5__3 = <instruction>5__7; <state>5__2 = TranspilerState.Checking2; } break; case TranspilerState.Checking2: if (<instruction>5__7.opcode == OpCodes.Ldc_I4_0) { <instruction2>5__4 = <instruction>5__7; <state>5__2 = TranspilerState.Updating; } else { <instruction1>5__3 = null; <state>5__2 = TranspilerState.Searching2; } break; case TranspilerState.Updating: <>2__current = <instruction1>5__3; <>1__state = 6; return true; case TranspilerState.Finishing: <>2__current = <instruction>5__7; <>1__state = 9; return true; } goto IL_03ac; } <>m__Finally1(); <>7__wrap5 = null; return false; } } catch { //try-fault ((IDisposable)this).Dispose(); throw; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; if (<>7__wrap5 != null) { <>7__wrap5.Dispose(); } } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator<CodeInstruction> IEnumerable<CodeInstruction>.GetEnumerator() { <GetCameraPosition_Transpiler>d__1 <GetCameraPosition_Transpiler>d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; <GetCameraPosition_Transpiler>d__ = this; } else { <GetCameraPosition_Transpiler>d__ = new <GetCameraPosition_Transpiler>d__1(0); } <GetCameraPosition_Transpiler>d__.instructions = <>3__instructions; return <GetCameraPosition_Transpiler>d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable<CodeInstruction>)this).GetEnumerator(); } } [IteratorStateMachine(typeof(<GetCameraPosition_Transpiler>d__1))] [HarmonyPatch("GetCameraPosition")] [HarmonyTranspiler] private static IEnumerable<CodeInstruction> GetCameraPosition_Transpiler(IEnumerable<CodeInstruction> instructions) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <GetCameraPosition_Transpiler>d__1(-2) { <>3__instructions = instructions }; } } public const string ModId = "dev.crystal.underwater"; public static ConfigEntry<bool> PlayerSwims; public static ConfigEntry<bool> CameraIgnoreWater; public static ConfigEntry<Key> ToggleSwimKey; private static InputBinding sToggleSwimBinding; private static Harmony sCharacterHarmony; private static Harmony sGameCameraHarmony; private void Awake() { //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Expected O, but got Unknown //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Expected O, but got Unknown //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Expected O, but got Unknown PlayerSwims = ((BaseUnityPlugin)this).Config.Bind<bool>("Underwater", "PlayerSwims", true, "Whether players should swim or ignore water, walking along the terrain beneath it. Can also be toggled by pressing Backspace. Game default true."); PlayerSwims.SettingChanged += IgnoreWater_SettingChanged; CameraIgnoreWater = ((BaseUnityPlugin)this).Config.Bind<bool>("Underwater", "CameraIgnoreWater", false, "Whether the camera should ignore water, allowing it to move beneath the surface. This setting is implied true if PlayerSwims is false. Game default false."); CameraIgnoreWater.SettingChanged += IgnoreWater_SettingChanged; ToggleSwimKey = ((BaseUnityPlugin)this).Config.Bind<Key>("Underwater", "ToggleSwimKey", (Key)65, "Binds a shortcut key for toggling the PlayerSwims option."); sToggleSwimBinding = new InputBinding("ToggleSwim", ToggleSwimKey); sToggleSwimBinding.InputPressed += ToggleSwimBinding_InputPressed; sCharacterHarmony = new Harmony("dev.crystal.underwater_Character"); sGameCameraHarmony = new Harmony("dev.crystal.underwater_GameCamera"); sCharacterHarmony.PatchAll(typeof(Character_Patches)); if (!PlayerSwims.Value || CameraIgnoreWater.Value) { sGameCameraHarmony.PatchAll(typeof(GameCamera_Patches)); } } private void OnDestroy() { sCharacterHarmony.UnpatchSelf(); sGameCameraHarmony.UnpatchSelf(); sToggleSwimBinding.Dispose(); } private void IgnoreWater_SettingChanged(object sender, EventArgs e) { sGameCameraHarmony.UnpatchSelf(); if (!PlayerSwims.Value || CameraIgnoreWater.Value) { sGameCameraHarmony.PatchAll(typeof(GameCamera_Patches)); } } private void ToggleSwimBinding_InputPressed(object sender, InputEventArgs e) { PlayerSwims.Value = !PlayerSwims.Value; ((Character)e.Player).Message((MessageType)1, PlayerSwims.Value ? "Swimming On" : "Swimming Off", 0, (Sprite)null); } }