Please disclose if any significant portion of your mod was created 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 BuildCamera Ymiron v1.0.2
BuildCamera.dll
Decompiled 15 hours agousing System; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("BuildCamera")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.2.0")] [assembly: AssemblyInformationalVersion("1.0.2")] [assembly: AssemblyProduct("BuildCamera")] [assembly: AssemblyTitle("BuildCamera")] [assembly: AssemblyVersion("1.0.2.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 BuildCamera { internal static class BuildCam { private const float GroundClearance = 0.5f; private static Vector3 _position; private static float _yaw; private static float _pitch; internal static bool Active { get; private set; } internal static void Update() { Player localPlayer = Player.m_localPlayer; if (Active && !CanStay(localPlayer)) { Exit(null); } else if (TogglePressed()) { if (Active) { Exit("Build camera off"); } else { TryEnter(localPlayer); } } } private static void TryEnter(Player player) { //IL_0046: 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) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)player == (Object)null) && !((Object)(object)GameCamera.instance == (Object)null) && !GameCamera.InFreeFly()) { if (!((Character)player).InPlaceMode()) { Message(player, "Equip the hammer to use the build camera"); } else if (CanStay(player)) { Transform transform = ((Component)GameCamera.instance).transform; _position = transform.position; Quaternion rotation = transform.rotation; Vector3 eulerAngles = ((Quaternion)(ref rotation)).eulerAngles; _yaw = eulerAngles.y; _pitch = Mathf.Clamp((eulerAngles.x > 180f) ? (eulerAngles.x - 360f) : eulerAngles.x, -89f, 89f); Active = true; Message(player, "Build camera on"); } } } internal static void Exit(string message) { if (Active) { Active = false; if (message != null) { Message(Player.m_localPlayer, message); } } } private static bool CanStay(Player player) { if ((Object)(object)player != (Object)null && (Object)(object)GameCamera.instance != (Object)null && !GameCamera.InFreeFly() && ((Character)player).InPlaceMode() && !((Character)player).IsDead() && !((Character)player).IsTeleporting() && !((Character)player).IsAttached()) { return !((Character)player).InCutscene(); } return false; } internal static void Drive(GameCamera gameCamera, float dt) { //IL_0202: Unknown result type (might be due to invalid IL or missing references) //IL_021b: Unknown result type (might be due to invalid IL or missing references) //IL_001a: 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) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01ba: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_01cb: Unknown result type (might be due to invalid IL or missing references) //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_01d2: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_01dd: Unknown result type (might be due to invalid IL or missing references) //IL_01e6: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_01f0: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { return; } if (InputFree()) { Vector2 val = ZInput.GetMouseDelta() * PlayerController.m_mouseSens * ModConfig.MouseSensitivity.Value; if (PlayerController.m_invertMouse) { val.y = 0f - val.y; } _yaw = Mathf.Repeat(_yaw + val.x, 360f); _pitch = Mathf.Clamp(_pitch - val.y, -89f, 89f); Vector3 zero = Vector3.zero; if (ZInput.GetButton("Forward")) { zero.z += 1f; } if (ZInput.GetButton("Backward")) { zero.z -= 1f; } if (ZInput.GetButton("Right")) { zero.x += 1f; } if (ZInput.GetButton("Left")) { zero.x -= 1f; } if (ZInput.GetButton("Jump")) { zero.y += 1f; } if (ZInput.GetButton("Crouch")) { zero.y -= 1f; } if (((Vector3)(ref zero)).sqrMagnitude > 1f) { ((Vector3)(ref zero)).Normalize(); } float num = ModConfig.Speed.Value; if (ZInput.GetButton("Run")) { num *= ModConfig.FastMultiplier.Value; } Vector3 val2 = (ModConfig.FlatMovement.Value ? Quaternion.Euler(0f, _yaw, 0f) : Quaternion.Euler(_pitch, _yaw, 0f)) * new Vector3(zero.x, 0f, zero.z); _position += (val2 + Vector3.up * zero.y) * (num * dt); } ClampPosition(localPlayer); Transform transform = ((Component)gameCamera).transform; transform.position = _position; transform.rotation = Quaternion.Euler(_pitch, _yaw, 0f); Camera component = ((Component)gameCamera).GetComponent<Camera>(); if ((Object)(object)component != (Object)null && component.nearClipPlane != gameCamera.m_nearClipPlaneMin) { component.nearClipPlane = gameCamera.m_nearClipPlaneMin; } } private static void ClampPosition(Player player) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) Vector3 position = ((Character)player).m_eye.position; Vector3 val = _position - position; float value = ModConfig.MaxDistance.Value; if (((Vector3)(ref val)).sqrMagnitude > value * value) { _position = position + ((Vector3)(ref val)).normalized * value; } float num = default(float); if (ModConfig.StayAboveGround.Value && (Object)(object)ZoneSystem.instance != (Object)null && ZoneSystem.instance.GetGroundHeight(_position, ref num) && _position.y < num + 0.5f) { _position.y = num + 0.5f; } } private static bool InputFree() { if (((Object)(object)Chat.instance == (Object)null || !Chat.instance.HasFocus()) && !Console.IsVisible() && !TextInput.IsVisible() && !Menu.IsVisible() && !InventoryGui.IsVisible() && !Minimap.IsOpen() && !StoreGui.IsVisible() && !Hud.IsPieceSelectionVisible() && !Hud.InRadial()) { if (!((Object)(object)Hud.instance == (Object)null)) { return !Hud.instance.m_buildUi.SearchFieldFocused; } return true; } return false; } private static bool TogglePressed() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: 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_0016: Unknown result type (might be due to invalid IL or missing references) KeyboardShortcut value = ModConfig.ToggleKey.Value; if ((int)((KeyboardShortcut)(ref value)).MainKey == 0 || !ZInput.GetKeyDown(((KeyboardShortcut)(ref value)).MainKey, false)) { return false; } if (((Object)(object)Chat.instance != (Object)null && Chat.instance.HasFocus()) || Console.IsVisible() || TextInput.IsVisible() || Menu.IsVisible() || ((Object)(object)Hud.instance != (Object)null && Hud.instance.m_buildUi.SearchFieldFocused)) { return false; } return ((KeyboardShortcut)(ref value)).Modifiers.All(Held); } private static bool Held(KeyCode key) { //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_0024: Expected I4, but got Unknown //IL_0077: Unknown result type (might be due to invalid IL or missing references) switch (key - 303) { case 0: case 1: if (!ZInput.GetKey((KeyCode)304, false)) { return ZInput.GetKey((KeyCode)303, false); } return true; case 2: case 3: if (!ZInput.GetKey((KeyCode)306, false)) { return ZInput.GetKey((KeyCode)305, false); } return true; case 4: case 5: if (!ZInput.GetKey((KeyCode)308, false)) { return ZInput.GetKey((KeyCode)307, false); } return true; default: return ZInput.GetKey(key, false); } } private static void Message(Player player, string text) { if ((Object)(object)player != (Object)null) { ((Character)player).Message((MessageType)1, text, 0, (Sprite)null, false); } } } internal static class ModConfig { internal static ConfigEntry<KeyboardShortcut> ToggleKey; internal static ConfigEntry<float> Speed; internal static ConfigEntry<float> FastMultiplier; internal static ConfigEntry<float> MouseSensitivity; internal static ConfigEntry<bool> FlatMovement; internal static ConfigEntry<float> MaxDistance; internal static ConfigEntry<float> PlaceReach; internal static ConfigEntry<bool> StayAboveGround; internal static ConfigEntry<bool> StationNearPiece; internal static ConfigEntry<bool> ExitOnDamage; internal static void Bind(ConfigFile cfg) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Expected O, but got Unknown //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Expected O, but got Unknown //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Expected O, but got Unknown //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Expected O, but got Unknown //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Expected O, but got Unknown ToggleKey = cfg.Bind<KeyboardShortcut>("1 - Keys", "Toggle", new KeyboardShortcut((KeyCode)98, Array.Empty<KeyCode>()), "Detaches the camera from your character (you must be holding a building tool: hammer, hoe or cultivator); press it again to reattach. Modifiers are allowed, e.g. \"B + LeftAlt\"."); Speed = cfg.Bind<float>("2 - Movement", "Speed", 10f, new ConfigDescription("Camera speed in meters per second.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 50f), Array.Empty<object>())); FastMultiplier = cfg.Bind<float>("2 - Movement", "RunMultiplier", 3f, new ConfigDescription("Holding the run key (Shift) makes the camera faster by this factor.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 10f), Array.Empty<object>())); MouseSensitivity = cfg.Bind<float>("2 - Movement", "MouseSensitivity", 1f, new ConfigDescription("Multiplies the mouse sensitivity set in the game options.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 5f), Array.Empty<object>())); FlatMovement = cfg.Bind<bool>("2 - Movement", "HorizontalMovement", true, "true = forward/backward stay horizontal even when looking up or down; you only go up and down with Jump and Crouch. false = the camera flies where you look, like the game's free camera."); MaxDistance = cfg.Bind<float>("3 - Limits", "MaxDistance", 40f, new ConfigDescription("How far (in meters) the camera can move away from your character.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 60f), Array.Empty<object>())); PlaceReach = cfg.Bind<float>("3 - Limits", "PlacementReach", 10f, new ConfigDescription("Up to what distance from the camera (in meters) you can place, repair and remove pieces. In the normal game the limit is 5 m from your character.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(3f, 50f), Array.Empty<object>())); StayAboveGround = cfg.Bind<bool>("3 - Limits", "StayAboveGround", true, "true = the camera cannot go below the terrain. Walls and pieces can still be passed through."); StationNearPiece = cfg.Bind<bool>("3 - Limits", "WorkbenchNearPiece", true, "true = the workbench (or forge, etc.) must be near the piece you place or remove, not near your character: the camera can't be used to build far away from your base. false = only your character's position counts, as in the normal game."); ExitOnDamage = cfg.Bind<bool>("3 - Limits", "ExitWhenHit", true, "true = if your character takes damage the camera snaps back to them."); } } internal static class Reach { private const float Unlimited = 1000f; private static readonly FieldRef<Player, int> PlaceRayMask = AccessTools.FieldRefAccess<Player, int>("m_placeRayMask"); private static readonly FieldRef<Player, int> PlaceWaterRayMask = AccessTools.FieldRefAccess<Player, int>("m_placeWaterRayMask"); private static readonly FieldRef<Player, int> RemoveRayMask = AccessTools.FieldRefAccess<Player, int>("m_removeRayMask"); internal static readonly FieldRef<Player, GameObject> PlacementGhost = AccessTools.FieldRefAccess<Player, GameObject>("m_placementGhost"); internal static readonly FieldRef<Player, Piece> HoveringPiece = AccessTools.FieldRefAccess<Player, Piece>("m_hoveringPiece"); internal static bool Applies(Player player) { if (BuildCam.Active && (Object)(object)player != (Object)null && (Object)(object)player == (Object)(object)Player.m_localPlayer) { return (Object)(object)GameCamera.instance != (Object)null; } return false; } internal static int PlaceMask(Player player, bool water) { if (!water) { return PlaceRayMask.Invoke(player); } return PlaceWaterRayMask.Invoke(player); } internal static int RemoveMask(Player player) { return RemoveRayMask.Invoke(player); } internal static bool CameraHitWithin(int mask, float reach) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) Transform transform = ((Component)GameCamera.instance).transform; RaycastHit val = default(RaycastHit); if (Physics.Raycast(transform.position, transform.forward, ref val, 50f, mask)) { return ((RaycastHit)(ref val)).distance <= reach; } return false; } internal static float Lift(Player player) { float maxPlaceDistance = player.m_maxPlaceDistance; player.m_maxPlaceDistance = 1000f; return maxPlaceDistance; } internal static void Restore(Player player, float saved) { if (saved >= 0f) { player.m_maxPlaceDistance = saved; } } } [HarmonyPatch(typeof(Player), "PieceRayTest")] internal static class PieceRayTestPatch { private static bool Prefix(Player __instance, bool water, ref Vector3 point, ref Vector3 normal, ref Piece piece, ref Heightmap heightmap, ref Collider waterSurface, ref bool __result, out float __state) { //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0065: 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_0070: Unknown result type (might be due to invalid IL or missing references) __state = -1f; if (!Reach.Applies(__instance)) { return true; } float num = ModConfig.PlaceReach.Value; GameObject val = Reach.PlacementGhost.Invoke(__instance); Piece val2 = (((Object)(object)val != (Object)null) ? val.GetComponent<Piece>() : null); if ((Object)(object)val2 != (Object)null) { num += (float)val2.m_extraPlacementDistance; } if (!Reach.CameraHitWithin(Reach.PlaceMask(__instance, water), num)) { point = Vector3.zero; normal = Vector3.zero; piece = null; heightmap = null; waterSurface = null; __result = false; return false; } __state = Reach.Lift(__instance); return true; } private static void Finalizer(Player __instance, float __state) { Reach.Restore(__instance, __state); } } [HarmonyPatch(typeof(Player), "UpdateWearNTearHover")] internal static class WearNTearHoverPatch { private static bool Prefix(Player __instance, out float __state) { __state = -1f; if (!Reach.Applies(__instance) || !((Character)__instance).InPlaceMode()) { return true; } if (!Reach.CameraHitWithin(Reach.RemoveMask(__instance), ModConfig.PlaceReach.Value)) { Reach.HoveringPiece.Invoke(__instance) = null; return false; } __state = Reach.Lift(__instance); return true; } private static void Finalizer(Player __instance, float __state) { Reach.Restore(__instance, __state); } } [HarmonyPatch(typeof(Player), "RemovePiece")] internal static class RemovePiecePatch { private static bool Prefix(Player __instance, ref bool __result, out float __state) { __state = -1f; if (!Reach.Applies(__instance)) { return true; } if (!Reach.CameraHitWithin(Reach.RemoveMask(__instance), ModConfig.PlaceReach.Value)) { __result = false; return false; } __state = Reach.Lift(__instance); return true; } private static void Finalizer(Player __instance, float __state) { Reach.Restore(__instance, __state); } } [HarmonyPatch(typeof(Player), "CopyPiece")] internal static class CopyPiecePatch { private static bool Prefix(Player __instance, ref bool __result, out float __state) { __state = -1f; if (!Reach.Applies(__instance)) { return true; } if (!Reach.CameraHitWithin(Reach.RemoveMask(__instance), ModConfig.PlaceReach.Value)) { __result = false; return false; } __state = Reach.Lift(__instance); return true; } private static void Finalizer(Player __instance, float __state) { Reach.Restore(__instance, __state); } } internal static class Station { internal static Vector3? Point; internal static bool Applies(Player player) { if (Reach.Applies(player)) { return ModConfig.StationNearPiece.Value; } return false; } } [HarmonyPatch(typeof(Player), "HaveRequirements", new Type[] { typeof(Piece), typeof(RequirementMode) })] internal static class HaveRequirementsPatch { private static void Prefix(Player __instance, RequirementMode mode) { //IL_0000: 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) if ((int)mode == 0 && Station.Applies(__instance)) { GameObject val = Reach.PlacementGhost.Invoke(__instance); if ((Object)(object)val != (Object)null) { Station.Point = val.transform.position; } } } private static void Finalizer() { Station.Point = null; } } [HarmonyPatch(typeof(Player), "CheckCanRemovePiece")] internal static class CheckCanRemovePiecePatch { private static void Prefix(Player __instance, Piece piece) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)piece != (Object)null && Station.Applies(__instance)) { Station.Point = ((Component)piece).transform.position; } } private static void Finalizer() { Station.Point = null; } } [HarmonyPatch(typeof(CraftingStation), "HaveBuildStationInRange")] internal static class HaveBuildStationInRangePatch { private static void Prefix(ref Vector3 point) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) if (Station.Point.HasValue) { point = Station.Point.Value; } } } [HarmonyPatch(typeof(GameCamera), "UpdateCamera")] internal static class UpdateCameraPatch { private static bool Prefix(GameCamera __instance, float dt) { if (!BuildCam.Active) { return true; } BuildCam.Drive(__instance, dt); return false; } } [HarmonyPatch(typeof(GameCamera), "UpdateListner")] internal static class UpdateListenerPatch { private static readonly FieldRef<GameCamera, AudioListener> Listener = AccessTools.FieldRefAccess<GameCamera, AudioListener>("m_listner"); private static bool Prefix(GameCamera __instance) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) if (!BuildCam.Active) { return true; } AudioListener val = Listener.Invoke(__instance); if ((Object)(object)val != (Object)null) { ((Component)val).transform.localPosition = Vector3.zero; } return false; } } [HarmonyPatch(typeof(PlayerController), "FixedUpdate")] internal static class PlayerControllerFixedUpdatePatch { private static readonly FieldRef<float> TakeInputDelay = AccessTools.StaticFieldRefAccess<float>(AccessTools.Field(typeof(PlayerController), "takeInputDelay")); private static bool Prefix(PlayerController __instance) { //IL_004f: Unknown result type (might be due to invalid IL or missing references) if (!BuildCam.Active) { return true; } Player component = ((Component)__instance).GetComponent<Player>(); if ((Object)(object)component == (Object)null || (Object)(object)component != (Object)(object)Player.m_localPlayer) { return true; } TakeInputDelay.Invoke() = Mathf.Max(0f, TakeInputDelay.Invoke() - Time.deltaTime); component.SetControls(Vector3.zero, false, false, false, false, false, false, false, false, false, false, false); return false; } } [HarmonyPatch(typeof(PlayerController), "LateUpdate")] internal static class PlayerControllerLateUpdatePatch { private static bool Prefix(PlayerController __instance) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) if (!BuildCam.Active) { return true; } Player component = ((Component)__instance).GetComponent<Player>(); if ((Object)(object)component == (Object)null || (Object)(object)component != (Object)(object)Player.m_localPlayer) { return true; } component.SetMouseLook(Vector2.zero); return false; } } [HarmonyPatch(typeof(Player), "OnDamaged")] internal static class OnDamagedPatch { private static void Postfix(Player __instance) { if (BuildCam.Active && (Object)(object)__instance == (Object)(object)Player.m_localPlayer && ModConfig.ExitOnDamage.Value) { BuildCam.Exit("You were hit: camera back to your character"); } } } [BepInPlugin("ymiron.valheim.buildcamera", "BuildCamera-Ymiron", "1.0.2")] [BepInProcess("valheim.exe")] public class BuildCameraPlugin : BaseUnityPlugin { public const string PluginGuid = "ymiron.valheim.buildcamera"; public const string PluginName = "BuildCamera-Ymiron"; public const string PluginVersion = "1.0.2"; private Harmony _harmony; internal static ManualLogSource Log { get; private set; } private void Awake() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; ModConfig.Bind(((BaseUnityPlugin)this).Config); _harmony = new Harmony("ymiron.valheim.buildcamera"); _harmony.PatchAll(typeof(BuildCameraPlugin).Assembly); Log.LogInfo((object)"BuildCamera-Ymiron 1.0.2 loaded."); } private void Update() { BuildCam.Update(); } private void OnDestroy() { BuildCam.Exit(null); Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } } }