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 EepyDeepy v1.0.2
plugins/EepyDeepy.dll
Decompiled 3 hours agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Threading; using BepInEx; using BepInEx.Logging; using HarmonyLib; using Jotunn.Entities; using Jotunn.Managers; using UnityEngine; using UnityEngine.Networking; [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("EepyDeepy")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+6a7c5f189dc219057fbc68de64047530ed67ab4b")] [assembly: AssemblyProduct("EepyDeepy")] [assembly: AssemblyTitle("EepyDeepy")] [assembly: AssemblyVersion("1.0.0.0")] namespace EepyDeepy; public class SequenceEntry { public int Seconds; public string Message; } public class EepyDeepyConfig { public List<SequenceEntry> Sequence = new List<SequenceEntry>(); } [BepInPlugin("com.byawn.eepydeepy", "EepyDeepy", "1.0.2")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class EepyDeepyPlugin : BaseUnityPlugin { public const string PluginGUID = "com.byawn.eepydeepy"; public const string PluginName = "EepyDeepy"; public const string PluginVersion = "1.0.2"; internal static ManualLogSource Log; internal static EepyDeepyPlugin Instance; private Harmony harmony; private EepyDeepyConfig config; private string configPath; private FileSystemWatcher configWatcher; private DateTime lastConfigReload = DateTime.MinValue; private DateTime lastBedExit = DateTime.MinValue; private bool inBed; private int sequenceIndex; private bool sequenceActive; private int playersInBed; private ZNetPeer lastBedPeer; private AudioSource audioSource; private AudioClip lullaby; internal CustomRPC bedEnterRPC; internal CustomRPC bedExitRPC; private CustomRPC playLullabyRPC; private CustomRPC stopLullabyRPC; private void Awake() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Expected O, but got Unknown //IL_00d2: Expected O, but got Unknown //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Expected O, but got Unknown //IL_00ff: Expected O, but got Unknown //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Expected O, but got Unknown //IL_012c: Expected O, but got Unknown //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Expected O, but got Unknown //IL_0159: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; Instance = this; harmony = new Harmony("com.byawn.eepydeepy"); harmony.PatchAll(); configPath = Path.Combine(Paths.ConfigPath, "eepydeepy.cfg"); LoadConfig(); StartConfigWatcher(); if (!GUIManager.IsHeadless()) { audioSource = ((Component)this).gameObject.AddComponent<AudioSource>(); audioSource.loop = true; audioSource.volume = 0f; string path = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), "lullaby.ogg"); ((MonoBehaviour)this).StartCoroutine(LoadAudio(path)); } bedEnterRPC = NetworkManager.Instance.AddRPC("BedEnter", new CoroutineHandler(RPC_OnBedEnter), new CoroutineHandler(RPC_NoOp)); bedExitRPC = NetworkManager.Instance.AddRPC("BedExit", new CoroutineHandler(RPC_OnBedExit), new CoroutineHandler(RPC_NoOp)); playLullabyRPC = NetworkManager.Instance.AddRPC("PlayLullaby", new CoroutineHandler(RPC_NoOp), new CoroutineHandler(RPC_OnPlayLullaby)); stopLullabyRPC = NetworkManager.Instance.AddRPC("StopLullaby", new CoroutineHandler(RPC_NoOp), new CoroutineHandler(RPC_OnStopLullaby)); Log.LogInfo((object)"EepyDeepy v1.0.2 loaded."); } private IEnumerator RPC_NoOp(long sender, ZPackage package) { yield break; } private IEnumerator RPC_OnBedEnter(long sender, ZPackage package) { Log.LogInfo((object)$"RPC_OnBedEnter received from {sender}."); ZNetPeer peer = ZNet.instance.GetPeer(sender); OnPlayerBedEnter(peer, "RPC"); yield break; } private IEnumerator RPC_OnBedExit(long sender, ZPackage package) { Log.LogInfo((object)$"RPC_OnBedExit received from {sender}."); OnPlayerBedExit(); yield break; } private IEnumerator RPC_OnPlayLullaby(long sender, ZPackage package) { Log.LogInfo((object)$"RPC_OnPlayLullaby received. lullaby={(Object)(object)lullaby != (Object)null} audioSource={(Object)(object)audioSource != (Object)null}"); StartMusic(); yield break; } private IEnumerator RPC_OnStopLullaby(long sender, ZPackage package) { Log.LogInfo((object)"RPC_OnStopLullaby received."); ((MonoBehaviour)this).StopAllCoroutines(); ((MonoBehaviour)this).StartCoroutine(FadeOutMusic(3f)); yield break; } private IEnumerator LoadAudio(string path) { if (!File.Exists(path)) { Log.LogWarning((object)("Lullaby not found at " + path + ". No music will play.")); yield break; } UnityWebRequest req = UnityWebRequestMultimedia.GetAudioClip("file://" + path, (AudioType)14); try { yield return req.SendWebRequest(); if ((int)req.result != 1) { Log.LogError((object)("Failed to load lullaby: " + req.error)); yield break; } lullaby = DownloadHandlerAudioClip.GetContent(req); Log.LogInfo((object)"Lullaby loaded."); } finally { ((IDisposable)req)?.Dispose(); } } private void StartMusic() { Log.LogInfo((object)$"StartMusic called. lullaby={(Object)(object)lullaby != (Object)null} audioSource={(Object)(object)audioSource != (Object)null}"); if (!((Object)(object)lullaby == (Object)null)) { audioSource.clip = lullaby; audioSource.volume = 0f; audioSource.Play(); Log.LogInfo((object)"Audio playing."); ((MonoBehaviour)this).StartCoroutine(FadeInMusic(3f)); } } private IEnumerator FadeInMusic(float duration) { float t = 0f; while (t < duration) { t += Time.deltaTime; audioSource.volume = Mathf.Clamp01(t / duration); yield return null; } audioSource.volume = 1f; } private IEnumerator FadeOutMusic(float duration) { float startVolume = audioSource.volume; float t = 0f; while (t < duration) { t += Time.deltaTime; audioSource.volume = Mathf.Clamp01(startVolume * (1f - t / duration)); yield return null; } audioSource.Stop(); audioSource.volume = 0f; } private void LoadConfig() { if (!File.Exists(configPath)) { Log.LogError((object)("Config not found at " + configPath + ".")); return; } EepyDeepyConfig eepyDeepyConfig = new EepyDeepyConfig(); string[] array = File.ReadAllLines(configPath); for (int i = 0; i < array.Length; i++) { string text = array[i].Trim(); if (string.IsNullOrEmpty(text) || text.StartsWith("#")) { continue; } int num = text.IndexOf(' '); if (num >= 0) { string s = text.Substring(0, num).Trim(); string text2 = text.Substring(num + 1).Trim(); if (int.TryParse(s, out var result) && !string.IsNullOrEmpty(text2)) { eepyDeepyConfig.Sequence.Add(new SequenceEntry { Seconds = result, Message = text2 }); } } } config = eepyDeepyConfig; LogConfig(); } private void LogConfig() { Log.LogInfo((object)$"Config loaded: {config.Sequence.Count} sequence entries."); foreach (SequenceEntry item in config.Sequence) { Log.LogInfo((object)$" [{item.Seconds}s] {item.Message}"); } } private void StartConfigWatcher() { configWatcher = new FileSystemWatcher(Paths.ConfigPath, "eepydeepy.cfg"); configWatcher.NotifyFilter = NotifyFilters.LastWrite; configWatcher.Changed += OnConfigChanged; configWatcher.EnableRaisingEvents = true; } private void OnConfigChanged(object sender, FileSystemEventArgs e) { if (!((DateTime.Now - lastConfigReload).TotalSeconds < 1.0)) { lastConfigReload = DateTime.Now; Thread.Sleep(200); Log.LogInfo((object)"Config file changed, reloading..."); LoadConfig(); } } public void OnPlayerBedEnter(ZNetPeer peer, string trigger) { //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Expected O, but got Unknown if (!inBed) { inBed = true; playersInBed++; lastBedPeer = peer; Log.LogInfo((object)$"Player {peer?.m_playerName} triggered EepyDeepy via {trigger}. Players in bed: {playersInBed}"); if (!sequenceActive) { sequenceActive = true; sequenceIndex = 0; Log.LogInfo((object)("Starting EepyDeepy sequence, triggered by " + peer?.m_playerName + " via " + trigger + ".")); ((MonoBehaviour)this).StartCoroutine(RunSequence()); playLullabyRPC.SendPackage(ZRoutedRpc.Everybody, new ZPackage()); } } } public void OnPlayerBedExit() { if (!inBed) { return; } inBed = false; if (!((DateTime.Now - lastBedExit).TotalSeconds < 2.0)) { lastBedExit = DateTime.Now; playersInBed = Math.Max(0, playersInBed - 1); Log.LogInfo((object)$"Player left bed. Players in bed: {playersInBed}"); if (playersInBed == 0) { ResetSequence("all players left bed"); } } } public void OnSleepSuccess() { ResetSequence("sleep succeeded"); } private void ResetSequence(string reason) { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Expected O, but got Unknown Log.LogInfo((object)("Resetting sequence: " + reason + ".")); inBed = false; sequenceActive = false; sequenceIndex = 0; playersInBed = 0; lastBedPeer = null; ((MonoBehaviour)this).StopAllCoroutines(); stopLullabyRPC.SendPackage(ZRoutedRpc.Everybody, new ZPackage()); } private IEnumerator RunSequence() { while (sequenceActive && sequenceIndex < config.Sequence.Count) { SequenceEntry entry = config.Sequence[sequenceIndex]; yield return (object)new WaitForSeconds((float)entry.Seconds); if (!sequenceActive) { yield break; } BroadcastChatMessage(entry.Message); sequenceIndex++; } if (sequenceActive) { Log.LogInfo((object)"Sequence exhausted."); sequenceActive = false; } } private void BroadcastChatMessage(string text) { if (!((Object)(object)ZNet.instance == (Object)null) && ZRoutedRpc.instance != null) { ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.Everybody, "ShowMessage", new object[2] { 2, text }); Log.LogInfo((object)("[EepyDeepy] " + text)); } } private void OnDestroy() { configWatcher?.Dispose(); Harmony obj = harmony; if (obj != null) { obj.UnpatchSelf(); } } } [HarmonyPatch(typeof(Bed), "Interact")] public static class Patch_Bed_Interact { private static void Postfix(Humanoid human, bool __result) { if (!ZNet.instance.IsServer() || !__result) { return; } ZNetPeer peer = null; foreach (ZNetPeer peer2 in ZNet.instance.GetPeers()) { if (peer2.m_playerName == ((Character)human).GetHoverName()) { peer = peer2; break; } } EepyDeepyPlugin.Instance.OnPlayerBedEnter(peer, "entered bed"); } } [HarmonyPatch(typeof(Bed), "SetOwner")] public static class Patch_Bed_SetOwner { private static void Postfix(long uid) { if (ZNet.instance.IsServer() && uid == 0L) { EepyDeepyPlugin.Instance.OnPlayerBedExit(); } } } [HarmonyPatch(typeof(EnvMan), "SkipToMorning")] public static class Patch_EnvMan_SkipToMorning { private static void Postfix() { if (ZNet.instance.IsServer()) { EepyDeepyPlugin.Instance.OnSleepSuccess(); } } } [HarmonyPatch(typeof(Player), "StartEmote")] public static class Patch_Player_StartEmote { private static void Postfix(string emote, Player __instance) { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Expected O, but got Unknown if (!(emote != "rest")) { EepyDeepyPlugin.Log.LogInfo((object)("Player " + ((Character)__instance).GetHoverName() + " used rest emote, notifying server.")); EepyDeepyPlugin.Instance.bedEnterRPC.SendPackage(ZNet.instance.GetServerPeer().m_uid, new ZPackage()); } } } [HarmonyPatch(typeof(Player), "StopEmote")] public static class Patch_Player_StopEmote { private static void Prefix(Player __instance) { //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Expected O, but got Unknown if (!(Player.LastEmote != "rest")) { EepyDeepyPlugin.Log.LogInfo((object)("Player " + ((Character)__instance).GetHoverName() + " stopped rest emote, notifying server.")); EepyDeepyPlugin.Instance.bedExitRPC.SendPackage(ZNet.instance.GetServerPeer().m_uid, new ZPackage()); } } }