Decompiled source of JustSleep v1.0.4

JustSleep.dll

Decompiled 2 months ago
using System.Diagnostics;
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.Configuration;
using HarmonyLib;
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("JustSleep")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("JustSleep")]
[assembly: AssemblyCopyright("Copyright ©  2024")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("1f044c3f-2bd7-41a4-981b-5e0e47ba84e3")]
[assembly: AssemblyFileVersion("1.0.3")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.3.0")]
[module: UnverifiableCode]
namespace JustSleep;

[BepInPlugin("shudnal.JustSleep", "JustSleep", "1.0.4")]
public class JustSleep : BaseUnityPlugin
{
	[HarmonyPatch(typeof(Fireplace), "GetHoverText")]
	private class Fireplace_GetHoverText_HoverTextWithSleepAction
	{
		[HarmonyPriority(800)]
		private static void Postfix(ref string __result)
		{
			if (IsSleepingWhileRestingAvailable() && !((Character)Player.m_localPlayer).InBed())
			{
				if (!EnvMan.instance.CanSleep())
				{
					__result += Localization.instance.Localize("\n$msg_cantsleep");
					return;
				}
				if (((Character)Player.m_localPlayer).GetSEMan().HaveStatusEffect(Player.s_statusEffectWet))
				{
					__result += Localization.instance.Localize("\n$msg_bedwet");
					return;
				}
				if (Player.m_localPlayer.IsSensed())
				{
					__result += Localization.instance.Localize("\n$msg_bedenemiesnearby");
					return;
				}
				string text = ((!ZInput.IsNonClassicFunctionality() || !ZInput.IsGamepadActive()) ? "$KEY_AltPlace" : "$KEY_JoyAltKeys");
				__result += Localization.instance.Localize("\n[<color=yellow><b>" + text + " + $KEY_Use</b></color>] $piece_bed_sleep");
			}
		}
	}

	[HarmonyPatch(typeof(Fireplace), "Interact")]
	private class Fireplace_Interact_SleepAction
	{
		private static bool Prefix(Humanoid user, bool hold, bool alt)
		{
			if (!alt || hold || (Object)(object)user != (Object)(object)Player.m_localPlayer || !CanSleep())
			{
				return true;
			}
			SetSleepingWhileResting(sleeping: true);
			return false;
		}
	}

	[HarmonyPatch(typeof(Player), "SetControls")]
	private class Player_SetControls_StopSleeping
	{
		private static void Prefix(Player __instance, Vector3 movedir, bool attack, bool secondaryAttack, bool block, bool blockHold, bool jump, bool crouch)
		{
			//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)
			if ((((Character)__instance).IsAttached() || ((Character)__instance).InEmote()) && ((Character)__instance).InBed() && !__instance.IsSleeping() && (movedir != Vector3.zero || attack || secondaryAttack || block || blockHold || jump || crouch) && __instance.GetDoodadController() == null)
			{
				SetSleepingWhileResting(sleeping: false);
			}
		}
	}

	[HarmonyPatch(typeof(Player), "SetSleeping")]
	private class Player_SetSleeping_StopSleeping
	{
		private static void Prefix(Player __instance, bool sleep)
		{
			if ((Object)(object)Player.m_localPlayer == (Object)(object)__instance && isSittingSleeping && __instance.IsSleeping() && !sleep)
			{
				SetSleepingWhileResting(sleeping: false);
				if (((Character)__instance).IsSitting())
				{
					((Character)__instance).StopEmote();
				}
			}
		}
	}

	[HarmonyPatch(typeof(Bed))]
	public static class BedPatches
	{
		private static Bed alternativeInteractingBed;

		[HarmonyPostfix]
		[HarmonyPatch("GetHoverText")]
		public static void GetHoverText(Bed __instance, ref string __result)
		{
			if (modEnabled.Value && sleepingInNotOwnedBed.Value && !__result.Contains(Localization.instance.Localize("$piece_bed_sleep")) && (!__instance.IsMine() || !__instance.IsCurrent()))
			{
				string text = ((!ZInput.IsNonClassicFunctionality() || !ZInput.IsGamepadActive()) ? "$KEY_AltPlace" : "$KEY_JoyAltKeys");
				__result += Localization.instance.Localize("\n[<color=yellow><b>" + text + " + $KEY_Use</b></color>] $piece_bed_sleep");
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch("Interact")]
		public static void InteractPrefix(Bed __instance, bool alt)
		{
			alternativeInteractingBed = ((modEnabled.Value && sleepingInNotOwnedBed.Value && alt) ? __instance : null);
		}

		[HarmonyPostfix]
		[HarmonyPatch("Interact")]
		public static void InteractPostfix()
		{
			alternativeInteractingBed = null;
		}

		[HarmonyPostfix]
		[HarmonyPatch("GetOwner")]
		public static void GetOwner(Bed __instance, ref long __result)
		{
			if ((Object)(object)__instance == (Object)(object)alternativeInteractingBed)
			{
				__result = Game.instance.GetPlayerProfile().GetPlayerID();
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("IsCurrent")]
		public static void IsCurrent(Bed __instance, ref bool __result)
		{
			__result = __result || (Object)(object)__instance == (Object)(object)alternativeInteractingBed;
		}
	}

	private const string pluginID = "shudnal.JustSleep";

	private const string pluginName = "JustSleep";

	private const string pluginVersion = "1.0.4";

	private Harmony harmony;

	private static JustSleep instance;

	private static ConfigEntry<bool> modEnabled;

	private static ConfigEntry<bool> sleepingInNotOwnedBed;

	private static ConfigEntry<bool> sleepingWhileResting;

	private static ConfigEntry<int> sleepingWhileRestingSeconds;

	private static float restingTimer;

	private static bool isSittingSleeping;

	private void Awake()
	{
		harmony = Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "shudnal.JustSleep");
		instance = this;
		ConfigInit();
		Game.isModded = true;
	}

	private void FixedUpdate()
	{
		if (!((Object)(object)Player.m_localPlayer == (Object)null))
		{
			if (((Character)Player.m_localPlayer).GetSEMan().HaveStatusEffect(Player.s_statusEffectResting))
			{
				restingTimer += Time.fixedDeltaTime;
			}
			else
			{
				restingTimer = 0f;
			}
			if (isSittingSleeping && !Game.instance.m_sleeping && !CanSleep())
			{
				SetSleepingWhileResting(sleeping: false);
			}
		}
	}

	private void OnDestroy()
	{
		((BaseUnityPlugin)this).Config.Save();
		Harmony obj = harmony;
		if (obj != null)
		{
			obj.UnpatchSelf();
		}
	}

	private void ConfigInit()
	{
		((BaseUnityPlugin)this).Config.Bind<int>("General", "NexusID", 2561, "Nexus mod ID for updates");
		modEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Enable the mod.");
		sleepingInNotOwnedBed = ((BaseUnityPlugin)this).Config.Bind<bool>("Sleeping in not owned beds", "Enabled", true, "Enable sleeping in not owned beds.");
		sleepingWhileResting = ((BaseUnityPlugin)this).Config.Bind<bool>("Sleeping while resting", "Enabled", true, "Enable option to sleep while Resting.");
		sleepingWhileRestingSeconds = ((BaseUnityPlugin)this).Config.Bind<int>("Sleeping while resting", "Seconds to stay resting", 20, "How many seconds should pass while resting for sleep in front of fireplace to be available");
	}

	private static bool CanSleep()
	{
		return (Object)(object)Player.m_localPlayer != (Object)null && IsSleepingWhileRestingAvailable() && EnvMan.instance.CanSleep() && !((Character)Player.m_localPlayer).GetSEMan().HaveStatusEffect(Player.s_statusEffectWet) && !Player.m_localPlayer.IsSensed();
	}

	private static bool IsSleepingWhileRestingAvailable()
	{
		return modEnabled.Value && sleepingWhileResting.Value && restingTimer >= (float)sleepingWhileRestingSeconds.Value && (Object)(object)Player.m_localPlayer != (Object)null && (((Character)Player.m_localPlayer).IsSitting() || ((Character)Player.m_localPlayer).IsAttached());
	}

	private static void SetSleepingWhileResting(bool sleeping)
	{
		//IL_003e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0043: Unknown result type (might be due to invalid IL or missing references)
		isSittingSleeping = sleeping;
		((Character)Player.m_localPlayer).m_nview.GetZDO().Set(ZDOVars.s_inBed, isSittingSleeping);
		if (isSittingSleeping)
		{
			Chat.instance.SetNpcText(((Component)Player.m_localPlayer).gameObject, Vector2.op_Implicit(Vector2.up), 20f, 600f, "", "$se_resting_start", false);
		}
		else
		{
			Chat.instance.ClearNpcText(((Component)Player.m_localPlayer).gameObject);
		}
	}
}