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 SleepingBodies v0.2.1
SleepingBodies.dll
Decompiled a week agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; 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: AssemblyVersion("0.0.0.0")] namespace SleepingBodies; [BepInPlugin("com.burks.sleepingbodies", "Sleeping Bodies", "0.2.1")] public class SleepingBodiesPlugin : BaseUnityPlugin { public const string GUID = "com.burks.sleepingbodies"; public const string NAME = "Sleeping Bodies"; public const string VERSION = "0.2.1"; public const string PrefabName = "burks_sleeping_body"; public const string ZdoPlayerId = "burks_sleeper_pid"; public const string ZdoPlayerName = "burks_sleeper_name"; public const string ZdoCreated = "burks_sleeper_time"; public const string RpcFind = "burks_sleeper_find"; public const string RpcFound = "burks_sleeper_found"; public static ManualLogSource Log; public static ConfigEntry<bool> Enabled; public static ConfigEntry<bool> RideVehicles; public static ConfigEntry<bool> ReturnToBody; public static SleepingBodiesPlugin Instance; public static ConfigEntry<string> Pose; public static bool LoggingOut; private void Update() { Return.Expire(); } private void Awake() { //IL_009a: Unknown result type (might be due to invalid IL or missing references) Log = ((BaseUnityPlugin)this).Logger; Instance = this; Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Leave a sleeping body where you log out, and remove it when you log back in."); RideVehicles = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "RideValheimRaftVehicles", true, "If you log out on a ValheimRAFT vehicle, the body is attached to it and travels with it."); ReturnToBody = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ReturnToBodyOnLogin", true, "When you log in and your body is somewhere else (for example on a ship that was sailed away), you are moved to it. Needs the mod on the server."); Pose = ((BaseUnityPlugin)this).Config.Bind<string>("General", "PoseAnimation", "attach_bed", "Animator flag used for the pose. attach_bed is the game's lying-in-bed pose."); new Harmony("com.burks.sleepingbodies").PatchAll(Assembly.GetExecutingAssembly()); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Sleeping Bodies 0.2.1 loaded."); } } [HarmonyPatch(typeof(ZNetScene), "Awake")] public static class PrefabPatch { private static GameObject _holder; private static GameObject _prefab; private static readonly FieldRef<ZNetScene, Dictionary<int, GameObject>> Named = AccessTools.FieldRefAccess<ZNetScene, Dictionary<int, GameObject>>("m_namedPrefabs"); [HarmonyPostfix] public static void Postfix(ZNetScene __instance) { SleepingBodiesPlugin.LoggingOut = false; Return.Reset(); try { if ((Object)(object)_prefab == (Object)null) { _prefab = Build(__instance); } if (!((Object)(object)_prefab == (Object)null)) { Named.Invoke(__instance)[StringExtensionMethods.GetStableHashCode("burks_sleeping_body")] = _prefab; if (!__instance.m_prefabs.Contains(_prefab)) { __instance.m_prefabs.Add(_prefab); } } } catch (Exception ex) { SleepingBodiesPlugin.Log.LogWarning((object)("Could not set up the sleeping body, the mod will do nothing: " + ex)); } } private static GameObject Build(ZNetScene scene) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown //IL_019d: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Unknown result type (might be due to invalid IL or missing references) GameObject prefab = scene.GetPrefab("Player"); if ((Object)(object)prefab == (Object)null) { SleepingBodiesPlugin.Log.LogWarning((object)"Player prefab not found; no sleeping bodies."); return null; } _holder = new GameObject("BurksSleepingBodyHolder"); _holder.SetActive(false); Object.DontDestroyOnLoad((Object)(object)_holder); GameObject val = Object.Instantiate<GameObject>(prefab, _holder.transform); ((Object)val).name = "burks_sleeping_body"; int num = 0; MonoBehaviour[] componentsInChildren = val.GetComponentsInChildren<MonoBehaviour>(true); foreach (MonoBehaviour val2 in componentsInChildren) { if (!((Object)(object)val2 == (Object)null) && !(val2 is ZNetView) && !(val2 is VisEquipment)) { Object.DestroyImmediate((Object)(object)val2); num++; } } Joint[] componentsInChildren2 = val.GetComponentsInChildren<Joint>(true); for (int i = 0; i < componentsInChildren2.Length; i++) { Object.DestroyImmediate((Object)(object)componentsInChildren2[i]); } Rigidbody[] componentsInChildren3 = val.GetComponentsInChildren<Rigidbody>(true); for (int i = 0; i < componentsInChildren3.Length; i++) { Object.DestroyImmediate((Object)(object)componentsInChildren3[i]); } Collider[] componentsInChildren4 = val.GetComponentsInChildren<Collider>(true); for (int i = 0; i < componentsInChildren4.Length; i++) { Object.DestroyImmediate((Object)(object)componentsInChildren4[i]); } AudioSource[] componentsInChildren5 = val.GetComponentsInChildren<AudioSource>(true); for (int i = 0; i < componentsInChildren5.Length; i++) { Object.DestroyImmediate((Object)(object)componentsInChildren5[i]); } ZNetView component = val.GetComponent<ZNetView>(); VisEquipment component2 = val.GetComponent<VisEquipment>(); if ((Object)(object)component == (Object)null || (Object)(object)component2 == (Object)null) { SleepingBodiesPlugin.Log.LogWarning((object)"Player prefab is not built the way this mod expects; no sleeping bodies."); Object.Destroy((Object)(object)_holder); _holder = null; return null; } component.m_persistent = true; component.m_distant = false; component.m_type = (ObjectType)0; component.m_syncInitialScale = false; component2.m_isPlayer = true; int num2 = LayerMask.NameToLayer("piece_nonsolid"); if (num2 >= 0) { val.layer = num2; } SphereCollider obj = val.AddComponent<SphereCollider>(); obj.radius = 0.55f; obj.center = new Vector3(0f, 0.35f, 0f); val.AddComponent<Sleeper>(); SleepingBodiesPlugin.Log.LogInfo((object)("Sleeping body prefab ready (" + num + " player scripts removed).")); return val; } } public class Sleeper : MonoBehaviour, Hoverable { private ZNetView _view; private Animator _anim; private float _nextPose; private float _nextCheck; private void Awake() { _view = ((Component)this).GetComponent<ZNetView>(); _anim = ((Component)this).GetComponentInChildren<Animator>(); if ((Object)(object)_anim != (Object)null) { _anim.applyRootMotion = false; } _nextCheck = Time.time + 3f; } private void Update() { float time = Time.time; if (time >= _nextPose) { _nextPose = time + 1f; ApplyPose(); } if (time >= _nextCheck) { _nextCheck = time + 1f; RemoveIfOwnerIsBack(); } } private void ApplyPose() { if ((Object)(object)_anim == (Object)null) { return; } try { _anim.SetBool("onGround", true); _anim.SetFloat("forward_speed", 0f); _anim.SetFloat("sideway_speed", 0f); string value = SleepingBodiesPlugin.Pose.Value; if (!string.IsNullOrEmpty(value)) { _anim.SetBool(value, true); } } catch { } } public long OwnerPlayerId() { if ((Object)(object)_view == (Object)null || !_view.IsValid()) { return 0L; } return _view.GetZDO().GetLong("burks_sleeper_pid", 0L); } public string OwnerName() { if ((Object)(object)_view == (Object)null || !_view.IsValid()) { return ""; } return _view.GetZDO().GetString("burks_sleeper_name", ""); } private void RemoveIfOwnerIsBack() { //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) try { if (SleepingBodiesPlugin.LoggingOut) { return; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || (Object)(object)Game.instance == (Object)null || (Object)(object)ZNetScene.instance == (Object)null) { return; } long num = OwnerPlayerId(); if (num == 0L || num != Game.instance.GetPlayerProfile().GetPlayerID() || ((Character)localPlayer).IsTeleporting() || !Return.SpawnSeen) { return; } if (Return.Pending || (SleepingBodiesPlugin.ReturnToBody.Value && Return.JustLoggedIn)) { Vector3 position = ((Component)this).transform.position; Vector3 val = ((Component)localPlayer).transform.position - position; if (((Vector3)(ref val)).magnitude < 150f) { ((Component)localPlayer).transform.position = position + Vector3.up * 0.15f; Physics.SyncTransforms(); SleepingBodiesPlugin.Log.LogInfo((object)("Back at your body at " + ((Vector3)(ref position)).ToString("F0") + ".")); } Return.Pending = false; Return.Arrived(); } Vehicles.Detach(_view); _view.ClaimOwnership(); ZNetScene.instance.Destroy(((Component)this).gameObject); } catch (Exception ex) { SleepingBodiesPlugin.Log.LogWarning((object)("Could not remove your sleeping body: " + ex.Message)); _nextCheck = Time.time + 10f; } } public string GetHoverText() { string text = OwnerName(); return (string.IsNullOrEmpty(text) ? "Someone" : text) + "\n<color=#a0a0a0>Sleeping</color>"; } public float GetHoverOffset() { return 0f; } public string GetHoverName() { string text = OwnerName(); if (!string.IsNullOrEmpty(text)) { return text; } return "Sleeper"; } } [HarmonyPatch(typeof(Game), "Shutdown")] public static class LogoutPatch { private static readonly int[] IntKeys = new int[23] { ZDOVars.s_leftItem, ZDOVars.s_rightItem, ZDOVars.s_chestItem, ZDOVars.s_legItem, ZDOVars.s_helmetItem, ZDOVars.s_shoulderItem, ZDOVars.s_utilityItem, ZDOVars.s_trinketItem, ZDOVars.s_beardItem, ZDOVars.s_hairItem, ZDOVars.s_leftBackItem, ZDOVars.s_rightBackItem, ZDOVars.s_leftItemVariant, ZDOVars.s_shoulderItemVariant, ZDOVars.s_leftBackItemVariant, ZDOVars.s_leftItemQuality, ZDOVars.s_rightItemQuality, ZDOVars.s_shoulderItemQuality, ZDOVars.s_leftBackItemQuality, ZDOVars.s_rightBackItemQuality, ZDOVars.s_modelIndex, ZDOVars.s_noBeard, ZDOVars.s_noHair }; [HarmonyPrefix] public static void Prefix() { try { LeaveBody(); } catch (Exception ex) { SleepingBodiesPlugin.Log.LogWarning((object)("Could not leave a sleeping body: " + ex)); } } private static void LeaveBody() { //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: 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_01d2: Unknown result type (might be due to invalid IL or missing references) //IL_01d7: Unknown result type (might be due to invalid IL or missing references) if (!SleepingBodiesPlugin.Enabled.Value || SleepingBodiesPlugin.LoggingOut) { return; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || ((Character)localPlayer).IsDead() || (Object)(object)ZNetScene.instance == (Object)null || (Object)(object)Game.instance == (Object)null) { return; } GameObject prefab = ZNetScene.instance.GetPrefab("burks_sleeping_body"); if ((Object)(object)prefab == (Object)null) { return; } ZNetView component = ((Component)localPlayer).GetComponent<ZNetView>(); if ((Object)(object)component == (Object)null || !component.IsValid()) { return; } SleepingBodiesPlugin.LoggingOut = true; long playerID = Game.instance.GetPlayerProfile().GetPlayerID(); Sleeper[] array = Object.FindObjectsByType<Sleeper>((FindObjectsSortMode)0); foreach (Sleeper sleeper in array) { if (sleeper.OwnerPlayerId() == playerID) { ZNetView component2 = ((Component)sleeper).GetComponent<ZNetView>(); Vehicles.Detach(component2); component2.ClaimOwnership(); ZNetScene.instance.Destroy(((Component)sleeper).gameObject); } } Vector3 position = ((Component)localPlayer).transform.position; Quaternion rotation = ((Component)localPlayer).transform.rotation; GameObject val = Object.Instantiate<GameObject>(prefab, position, rotation); ZNetView component3 = val.GetComponent<ZNetView>(); if ((Object)(object)component3 == (Object)null || !component3.IsValid()) { Object.Destroy((Object)(object)val); return; } ZDO zDO = component.GetZDO(); ZDO zDO2 = component3.GetZDO(); zDO2.Set("burks_sleeper_pid", playerID); zDO2.Set("burks_sleeper_name", localPlayer.GetPlayerName()); zDO2.Set("burks_sleeper_time", DateTime.UtcNow.Ticks); int[] intKeys = IntKeys; foreach (int num in intKeys) { zDO2.Set(num, zDO.GetInt(num, 0), false); } zDO2.Set(ZDOVars.s_skinColor, zDO.GetVec3(ZDOVars.s_skinColor, Vector3.one)); zDO2.Set(ZDOVars.s_hairColor, zDO.GetVec3(ZDOVars.s_hairColor, Vector3.one)); bool flag = SleepingBodiesPlugin.RideVehicles.Value && Vehicles.Attach(localPlayer, component3); SleepingBodiesPlugin.Log.LogInfo((object)("Left a sleeping body at " + ((Vector3)(ref position)).ToString("F0") + (flag ? " on a vehicle." : "."))); } } public static class Vehicles { private static bool _looked; private static Type _controller; private static MethodInfo _add; private static MethodInfo _remove; private static bool Ready() { if (!_looked) { _looked = true; _controller = AccessTools.TypeByName("ValheimVehicles.Controllers.VehiclePiecesController"); if (_controller != null) { _add = _controller.GetMethod("AddNewPiece", new Type[1] { typeof(ZNetView) }); _remove = _controller.GetMethod("RemovePiece", new Type[1] { typeof(ZNetView) }); } } if (_controller != null) { return _add != null; } return false; } private static Component Find(Player me) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: 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_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_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) Component componentInParent = ((Component)me).GetComponentInParent(_controller); if ((Object)(object)componentInParent != (Object)null) { return componentInParent; } Collider lastGroundCollider = ((Character)me).GetLastGroundCollider(); if ((Object)(object)lastGroundCollider != (Object)null) { componentInParent = ((Component)lastGroundCollider).GetComponentInParent(_controller); if ((Object)(object)componentInParent != (Object)null) { return componentInParent; } } RaycastHit[] array = Physics.RaycastAll(((Component)me).transform.position + Vector3.up * 1.5f, Vector3.down, 5f); for (int i = 0; i < array.Length; i++) { RaycastHit val = array[i]; if (!((Object)(object)((RaycastHit)(ref val)).collider == (Object)null)) { componentInParent = ((Component)((RaycastHit)(ref val)).collider).GetComponentInParent(_controller); if ((Object)(object)componentInParent != (Object)null) { return componentInParent; } } } return null; } public static bool Attach(Player me, ZNetView body) { try { if (!Ready()) { return false; } Component val = Find(me); if ((Object)(object)val == (Object)null) { return false; } _add.Invoke(val, new object[1] { body }); return true; } catch (Exception ex) { SleepingBodiesPlugin.Log.LogWarning((object)("Could not attach the body to the vehicle; it stays where it is: " + (ex.InnerException ?? ex).Message)); return false; } } public static void Detach(ZNetView body) { try { if (!((Object)(object)body == (Object)null) && Ready() && !(_remove == null)) { Component componentInParent = ((Component)body).GetComponentInParent(_controller); if ((Object)(object)componentInParent != (Object)null) { _remove.Invoke(componentInParent, new object[1] { body }); } } } catch { } } } public static class Return { [HarmonyPatch(typeof(Game), "Start")] public static class RegisterPatch { [HarmonyPostfix] public static void Postfix() { try { ZRoutedRpc.instance.Register<long>("burks_sleeper_find", (Action<long, long>)Server_Find); ZRoutedRpc.instance.Register<Vector3, bool>("burks_sleeper_found", (Action<long, Vector3, bool>)Client_Found); } catch (Exception ex) { SleepingBodiesPlugin.Log.LogWarning((object)("Could not set up return-to-body messages: " + ex.Message)); } } } [HarmonyPatch(typeof(Player), "OnSpawned")] public static class SpawnPatch { [HarmonyPostfix] public static void Postfix(Player __instance) { try { if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && !_asked) { _asked = true; _firstSpawn = Time.time; if (SleepingBodiesPlugin.Enabled.Value && SleepingBodiesPlugin.ReturnToBody.Value) { ((MonoBehaviour)SleepingBodiesPlugin.Instance).StartCoroutine(AskAfterDelay()); } } } catch (Exception ex) { SleepingBodiesPlugin.Log.LogWarning((object)("Could not ask the server for your body: " + ex.Message)); } } } public static bool Pending; private static bool _asked; private static bool _arrived; private static float _pendingSince; private static float _firstSpawn; public static bool SpawnSeen => _asked; public static bool JustLoggedIn { get { if (_asked && !_arrived) { return Time.time - _firstSpawn < 60f; } return false; } } public static void Arrived() { _arrived = true; } public static void Reset() { Pending = false; _asked = false; _arrived = false; } private static IEnumerator AskAfterDelay() { yield return (object)new WaitForSeconds(2f); if (!((Object)(object)Player.m_localPlayer == (Object)null) && !((Object)(object)Game.instance == (Object)null) && ZRoutedRpc.instance != null) { long playerID = Game.instance.GetPlayerProfile().GetPlayerID(); ZRoutedRpc.instance.InvokeRoutedRPC("burks_sleeper_find", new object[1] { playerID }); } } private static void Server_Find(long sender, long playerId) { //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: 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) try { if ((Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer() || ZDOMan.instance == null) { return; } List<ZDO> list = new List<ZDO>(); int num = 0; int num2 = 0; while (!ZDOMan.instance.GetAllZDOsWithPrefabIterative("burks_sleeping_body", list, ref num) && num2++ < 100000) { } ZDO val = null; long num3 = long.MinValue; foreach (ZDO item in list) { if (item != null && item.GetLong("burks_sleeper_pid", 0L) == playerId) { long num4 = item.GetLong("burks_sleeper_time", 0L); if (val == null || num4 > num3) { val = item; num3 = num4; } } } Vector3 val2 = ((val != null) ? val.GetPosition() : Vector3.zero); SleepingBodiesPlugin.Log.LogInfo((object)("Body lookup for player " + playerId + ": " + ((val != null) ? ("found at " + ((Vector3)(ref val2)).ToString("F0")) : "none"))); ZRoutedRpc.instance.InvokeRoutedRPC(sender, "burks_sleeper_found", new object[2] { val2, val != null }); } catch (Exception ex) { SleepingBodiesPlugin.Log.LogWarning((object)("Body lookup failed: " + ex)); } } private static void Client_Found(long sender, Vector3 pos, bool found) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: 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_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) try { Player localPlayer = Player.m_localPlayer; if (!found || (Object)(object)localPlayer == (Object)null || ((Character)localPlayer).IsDead() || _arrived) { return; } Vector3 position = ((Component)localPlayer).transform.position; float num = position.x - pos.x; float num2 = position.z - pos.z; float num3 = Mathf.Sqrt(num * num + num2 * num2); Pending = true; _pendingSince = Time.time; if (!(num3 < 12f) || !(Mathf.Abs(position.y - pos.y) < 12f)) { SleepingBodiesPlugin.Log.LogInfo((object)("Your body is " + Mathf.RoundToInt(num3) + " m away at " + ((Vector3)(ref pos)).ToString("F0") + "; going to it.")); if (!((Character)localPlayer).TeleportTo(pos + Vector3.up * 1f, ((Component)localPlayer).transform.rotation, true)) { ((MonoBehaviour)SleepingBodiesPlugin.Instance).StartCoroutine(RetryTeleport(pos)); } } } catch (Exception ex) { SleepingBodiesPlugin.Log.LogWarning((object)("Could not go to your body: " + ex.Message)); } } private static IEnumerator RetryTeleport(Vector3 pos) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < 20; i++) { if (!Pending) { break; } yield return (object)new WaitForSeconds(1.5f); Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || ((Character)localPlayer).IsDead()) { break; } if (!((Character)localPlayer).IsTeleporting()) { float num = ((Component)localPlayer).transform.position.x - pos.x; float num2 = ((Component)localPlayer).transform.position.z - pos.z; if (num * num + num2 * num2 < 144f || ((Character)localPlayer).TeleportTo(pos + Vector3.up * 1f, ((Component)localPlayer).transform.rotation, true)) { break; } } } } public static void Expire() { if (Pending && Time.time - _pendingSince > 120f) { Pending = false; } } }