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 ItWasAllADream v1.0.0
plugins/ItWasAllADream.dll
Decompiled 3 weeks agousing System; using System.Collections; using System.Collections.Generic; 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 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("ItWasAllADream")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("ItWasAllADream")] [assembly: AssemblyTitle("ItWasAllADream")] [assembly: AssemblyVersion("1.0.0.0")] namespace ItWasAllADream; [BepInPlugin("itwasalladream", "ItWasAllADream", "1.0.0")] public class Plugin : BaseUnityPlugin { private enum DreamPhase { Idle, Collecting, Active, Resetting } [HarmonyPatch(/*Could not decode attribute arguments.*/)] private static class Patch_ZRoutedRpc_Ctor { private static void Postfix() { ZRoutedRpc.instance.Register<ZPackage>("ItWasAllADream_RequestInventory", (Action<long, ZPackage>)RPC_RequestInventory); ZRoutedRpc.instance.Register<ZPackage>("ItWasAllADream_UploadInventory", (Action<long, ZPackage>)RPC_UploadInventory); ZRoutedRpc.instance.Register<ZPackage>("ItWasAllADream_RestoreInventory", (Action<long, ZPackage>)RPC_RestoreInventory); ZRoutedRpc.instance.Register<ZPackage>("ItWasAllADream_PlayerDied", (Action<long, ZPackage>)RPC_PlayerDied); } } [HarmonyPatch(typeof(EnvMan), "SkipToMorning")] private static class Patch_EnvMan_SkipToMorning { private static bool Prefix() { if ((Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer()) { return true; } if (_phase != 0) { return true; } Instance.TriggerDream(); return false; } } [HarmonyPatch(typeof(Player), "OnDeath")] private static class Patch_Player_OnDeath { private static bool Prefix(Player __instance) { //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Expected O, but got Unknown if (!IsEventActive && !IsEventStarting) { return true; } if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer) { return false; } Log.LogInfo((object)"[ItWasAllADream] Local player died in dream."); if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer()) { _hostDied = true; Log.LogInfo((object)("[ItWasAllADream] Host died. " + $"{_deadPeers.Count + 1}/{_totalPlayers} dead.")); } else { ZRoutedRpc.instance.InvokeRoutedRPC("ItWasAllADream_PlayerDied", new object[1] { (object)new ZPackage() }); } return false; } } [HarmonyPatch(typeof(SleepText), "ShowDreamText")] private static class Patch_SuppressDreamText { private static bool Prefix() { if (!IsEventActive) { return !IsEventStarting; } return false; } } [HarmonyPatch(typeof(Player), "AddKnownItem")] private static class Patch_SuppressNewItem { private static bool Prefix() { if (!IsEventActive) { return !IsEventStarting; } return false; } } [HarmonyPatch(typeof(Player), "AddKnownBiome")] private static class Patch_SuppressNewBiome { private static bool Prefix() { if (!IsEventActive) { return !IsEventStarting; } return false; } } public const string PluginGUID = "itwasalladream"; public const string PluginName = "ItWasAllADream"; public const string PluginVersion = "1.0.0"; internal static Plugin Instance; internal static ManualLogSource Log; private Harmony _harmony; private static DreamPhase _phase = DreamPhase.Idle; private static readonly Dictionary<long, byte[]> _savedInventories = new Dictionary<long, byte[]>(); private static readonly Dictionary<long, Vector3> _bedPositions = new Dictionary<long, Vector3>(); private static readonly HashSet<long> _deadPeers = new HashSet<long>(); private static bool _hostDied = false; private static byte[] _hostInventory = null; private static Vector3 _hostBedPosition = Vector3.zero; private static bool _hostIsPlayer = false; private static int _totalPlayers = 0; private ConfigEntry<int> _cfgMonstersPerWave; private ConfigEntry<string> _cfgWaveMonsters; private ConfigEntry<float> _cfgWaveDuration; private ConfigEntry<int> _cfgWaveCount; public static bool IsEventActive => _phase == DreamPhase.Active; public static bool IsEventStarting => _phase == DreamPhase.Collecting; private void Awake() { //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; Instance = this; _cfgMonstersPerWave = ((BaseUnityPlugin)this).Config.Bind<int>("Dream", "MonstersPerWave", 4, "Number of monsters spawned near each player per wave."); _cfgWaveMonsters = ((BaseUnityPlugin)this).Config.Bind<string>("Dream", "WaveMonsters", "Greyling,Greydwarf,Greydwarf_Elite,Skeleton,Draugr,Draugr_Elite,Troll,Fuling", "Comma-separated prefab names. Waves escalate from left (easy) to right (hard)."); _cfgWaveDuration = ((BaseUnityPlugin)this).Config.Bind<float>("Dream", "WaveDuration", 30f, "Seconds between monster waves."); _cfgWaveCount = ((BaseUnityPlugin)this).Config.Bind<int>("Dream", "WaveCount", 5, "Total number of monster waves before the dream ends itself."); _harmony = new Harmony("itwasalladream"); _harmony.PatchAll(); Log.LogInfo((object)"ItWasAllADream v1.0.0 loaded."); } private void OnDestroy() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } private void TriggerDream() { if (_phase == DreamPhase.Idle) { _phase = DreamPhase.Collecting; ((MonoBehaviour)this).StartCoroutine(DreamSequence()); } } private IEnumerator DreamSequence() { Log.LogInfo((object)"[ItWasAllADream] Dream sequence starting — collecting inventories..."); _savedInventories.Clear(); _bedPositions.Clear(); _deadPeers.Clear(); _hostDied = false; _hostInventory = null; _hostIsPlayer = (Object)(object)Player.m_localPlayer != (Object)null; List<ZNetPeer> peers = (from p in ZNet.instance.GetPeers() where p.m_uid != 0 select p).ToList(); foreach (ZNetPeer item in peers) { _bedPositions[item.m_uid] = item.m_refPos; } if (_hostIsPlayer) { _hostBedPosition = ((Component)Player.m_localPlayer).transform.position; ZPackage val = new ZPackage(); ((Humanoid)Player.m_localPlayer).GetInventory().Save(val); _hostInventory = val.GetArray(); } _totalPlayers = peers.Count + (_hostIsPlayer ? 1 : 0); if (_totalPlayers == 0) { _phase = DreamPhase.Idle; yield break; } ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.Everybody, "ItWasAllADream_RequestInventory", new object[1] { (object)new ZPackage() }); yield return (object)new WaitForSeconds(2.2f); _phase = DreamPhase.Active; Log.LogInfo((object)$"[ItWasAllADream] Dream active. Players: {_totalPlayers}"); ShowMessageAll((MessageType)2, "A terrible dream grips you..."); string[] monsterList = (from s in _cfgWaveMonsters.Value.Split(',') select s.Trim() into s where !string.IsNullOrEmpty(s) select s).ToArray(); int waves = _cfgWaveCount.Value; for (int wave = 0; wave < waves; wave++) { if (_phase != DreamPhase.Active) { yield break; } SpawnWave(monsterList, wave, waves, peers); if (wave == 0) { ShowMessageAll((MessageType)2, "They come for you in the dark..."); } else if (wave == waves - 1) { ShowMessageAll((MessageType)2, "There is no escape from the dream..."); } float elapsed = 0f; while (elapsed < _cfgWaveDuration.Value) { if (_phase != DreamPhase.Active) { yield break; } elapsed += 2f; yield return (object)new WaitForSeconds(2f); if (IsCatastrophe()) { ((MonoBehaviour)this).StartCoroutine(ResetSequence()); yield break; } } } while (_phase == DreamPhase.Active) { yield return (object)new WaitForSeconds(2f); if (IsCatastrophe()) { ((MonoBehaviour)this).StartCoroutine(ResetSequence()); break; } } } private bool IsCatastrophe() { return _deadPeers.Count + (_hostDied ? 1 : 0) >= _totalPlayers; } private void SpawnWave(string[] monsters, int waveIndex, int totalWaves, List<ZNetPeer> peers) { //IL_003a: 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) if (monsters.Length == 0) { return; } int baseIdx = Mathf.FloorToInt(((totalWaves <= 1) ? 1f : ((float)waveIndex / (float)(totalWaves - 1))) * (float)(monsters.Length - 1)); foreach (ZNetPeer peer in peers) { SpawnMonstersAround(monsters, baseIdx, peer.m_refPos); } if (_hostIsPlayer && (Object)(object)Player.m_localPlayer != (Object)null) { SpawnMonstersAround(monsters, baseIdx, ((Component)Player.m_localPlayer).transform.position); } } private void SpawnMonstersAround(string[] monsters, int baseIdx, Vector3 centre) { //IL_0047: 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_0064: 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_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < _cfgMonstersPerWave.Value; i++) { int num = Mathf.Clamp(baseIdx + Random.Range(0, 2), 0, monsters.Length - 1); string str = monsters[num]; float num2 = Random.Range(0f, 360f) * (MathF.PI / 180f); float num3 = Random.Range(6f, 22f); Vector3 val = centre + new Vector3(Mathf.Cos(num2) * num3, 0f, Mathf.Sin(num2) * num3); if (WorldGenerator.instance != null) { val.y = WorldGenerator.instance.GetHeight(val.x, val.z); } ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.Everybody, "SpawnObject", new object[3] { val, Quaternion.identity, StableHash(str) }); } } private IEnumerator ResetSequence() { if (_phase != DreamPhase.Active) { yield break; } _phase = DreamPhase.Resetting; Log.LogInfo((object)"[ItWasAllADream] Catastrophe! Triggering dream reset..."); yield return (object)new WaitForSeconds(1.5f); ShowMessageAll((MessageType)2, "It was all a dream..."); yield return (object)new WaitForSeconds(1f); foreach (ZNetPeer item in from p in ZNet.instance.GetPeers() where p.m_uid != 0 select p) { if (_savedInventories.TryGetValue(item.m_uid, out var value)) { ZRoutedRpc.instance.InvokeRoutedRPC(item.m_uid, "ItWasAllADream_RestoreInventory", new object[1] { (object)new ZPackage(value) }); } if (_bedPositions.TryGetValue(item.m_uid, out var value2)) { ZRoutedRpc.instance.InvokeRoutedRPC(item.m_uid, "RPC_TeleportPlayer", new object[3] { value2, Quaternion.identity, false }); } } if (_hostIsPlayer && (Object)(object)Player.m_localPlayer != (Object)null) { if (_hostInventory != null) { ((Humanoid)Player.m_localPlayer).UnequipAllItems(); ((Humanoid)Player.m_localPlayer).GetInventory().Load(new ZPackage(_hostInventory)); } ((Character)Player.m_localPlayer).SetHealth(((Character)Player.m_localPlayer).GetMaxHealth()); ((Character)Player.m_localPlayer).TeleportTo(_hostBedPosition, Quaternion.identity, false); } yield return (object)new WaitForSeconds(2f); _phase = DreamPhase.Idle; Log.LogInfo((object)"[ItWasAllADream] Dream reset complete. Returning to Idle."); } private static void RPC_UploadInventory(long sender, ZPackage pkg) { if (!((Object)(object)ZNet.instance == (Object)null) && ZNet.instance.IsServer()) { _savedInventories[sender] = pkg.GetArray(); Log.LogInfo((object)$"[ItWasAllADream] Stored inventory for peer {sender}."); } } private static void RPC_RestoreInventory(long sender, ZPackage pkg) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Expected O, but got Unknown if (!((Object)(object)Player.m_localPlayer == (Object)null)) { ((Humanoid)Player.m_localPlayer).UnequipAllItems(); ((Humanoid)Player.m_localPlayer).GetInventory().Load(new ZPackage(pkg.GetArray())); ((Character)Player.m_localPlayer).SetHealth(((Character)Player.m_localPlayer).GetMaxHealth()); Log.LogInfo((object)"[ItWasAllADream] Inventory restored and player healed."); } } private static void RPC_RequestInventory(long sender, ZPackage _pkg) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected O, but got Unknown if (!((Object)(object)Player.m_localPlayer == (Object)null) && (!((Object)(object)ZNet.instance != (Object)null) || !ZNet.instance.IsServer())) { ZPackage val = new ZPackage(); ((Humanoid)Player.m_localPlayer).GetInventory().Save(val); ZRoutedRpc.instance.InvokeRoutedRPC("ItWasAllADream_UploadInventory", new object[1] { val }); } } private static void RPC_PlayerDied(long sender, ZPackage _pkg) { if (!((Object)(object)ZNet.instance == (Object)null) && ZNet.instance.IsServer() && _phase == DreamPhase.Active) { _deadPeers.Add(sender); Log.LogInfo((object)($"[ItWasAllADream] Peer {sender} died. " + $"{_deadPeers.Count + (_hostDied ? 1 : 0)}/{_totalPlayers} dead.")); } } private static int StableHash(string str) { int num = 5381; int num2 = num; for (int i = 0; i < str.Length && str[i] != 0; i += 2) { num = ((num << 5) + num) ^ str[i]; if (i == str.Length - 1 || str[i + 1] == '\0') { break; } num2 = ((num2 << 5) + num2) ^ str[i + 1]; } return num + num2 * 1566083941; } private static void ShowMessageAll(MessageType type, string text) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Expected I4, but got Unknown if (!string.IsNullOrWhiteSpace(text) && ZRoutedRpc.instance != null) { ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.Everybody, "ShowMessage", new object[2] { (int)type, text }); } } }