Decompiled source of ForceRespawn v1.1.0

plugins/ForceRespawn.dll

Decompiled 7 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
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 BepInEx.Logging;
using HarmonyLib;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("OutwardSleepLonger")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("OutwardSleepLonger")]
[assembly: AssemblyCopyright("Copyright © Jdbye 2024")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("c5450fe0-edcf-483f-b9ea-4b1ef9d36da7")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace ForceRespawn;

[BepInPlugin("JdbyeForceRespawn", "ForceRespawn", "1.1.0")]
public class ForceRespawnPlugin : BaseUnityPlugin
{
	public enum SpawnSelectionTypes
	{
		[Description("Closest")]
		Closest,
		[Description("Random")]
		Random,
		[Description("Last Used")]
		LastUsedSpawn,
		[Description("Current Position")]
		SamePlace
	}

	public const string NAME = "ForceRespawn";

	public const string VERSION = "1.1.0";

	public const string CREATOR = "Jdbye";

	public const string GUID = "JdbyeForceRespawn";

	internal static ManualLogSource Log;

	public static ConfigEntry<SpawnSelectionTypes> SpawnType;

	public static ConfigEntry<bool> EnableInventoryStackBugFix;

	internal static ForceRespawnPlugin Instance;

	internal static Dictionary<string, Vector3> playerPositions = new Dictionary<string, Vector3>();

	internal static Dictionary<string, Quaternion> playerRotations = new Dictionary<string, Quaternion>();

	internal void Awake()
	{
		//IL_0065: Unknown result type (might be due to invalid IL or missing references)
		Log = ((BaseUnityPlugin)this).Logger;
		Log.LogInfo((object)"ForceRespawn 1.1.0 by Jdbye loaded!");
		Instance = this;
		SpawnType = ((BaseUnityPlugin)this).Config.Bind<SpawnSelectionTypes>("Force Respawn", "Spawn Point", SpawnSelectionTypes.SamePlace, "Select the spawn type to be used");
		EnableInventoryStackBugFix = ((BaseUnityPlugin)this).Config.Bind<bool>("Bug Fixes", "Inventory Stack Bug Fix", false, "Fixes the rare bug where your stacks are reduced to 1 when joining a multiplayer session by forcing a respawn");
		new Harmony("JdbyeForceRespawn").PatchAll();
	}

	internal void Update()
	{
	}

	internal static int GetClosestSpawn()
	{
		//IL_0011: 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)
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		//IL_0037: Unknown result type (might be due to invalid IL or missing references)
		int result = -1;
		Vector3 position = ((Component)CharacterManager.Instance.GetWorldHostCharacter()).transform.position;
		float num = float.MaxValue;
		for (int i = 0; i < SpawnPointManager.Instance.SpawnPoints.Count(); i++)
		{
			float num2 = Vector3.Distance(((Component)SpawnPointManager.Instance.SpawnPoints[i]).transform.position, position);
			if (num2 < num)
			{
				num = num2;
				result = i;
			}
		}
		return result;
	}

	internal static int GetSpawnIndex(SpawnSelectionTypes spawnType)
	{
		if ((spawnType == SpawnSelectionTypes.Closest || spawnType == SpawnSelectionTypes.SamePlace) ? true : false)
		{
			return GetClosestSpawn();
		}
		if (spawnType == SpawnSelectionTypes.LastUsedSpawn)
		{
			return SpawnPointManager.Instance.LastSpawnPointUsed;
		}
		return Random.Range(0, SpawnPointManager.Instance.SpawnPoints.Count());
	}

	internal static IEnumerator ReloadMap(SpawnSelectionTypes? spawnType = null)
	{
		if (!spawnType.HasValue)
		{
			spawnType = SpawnType.Value;
		}
		Log.LogInfo((object)("Forcing respawn (" + spawnType.GetDescription() + ") - " + AreaManager.Instance.CurrentArea.SceneName + " - " + AreaManager.Instance.CurrentArea.MapResourcesName));
		int spawnIndex = GetSpawnIndex(spawnType.Value);
		string sceneName = AreaManager.Instance.CurrentArea.SceneName;
		if (spawnType == SpawnSelectionTypes.SamePlace)
		{
			StorePlayerPositions();
		}
		NetworkLevelLoader.Instance.RequestReloadLevel(spawnIndex);
		if (spawnType == SpawnSelectionTypes.SamePlace)
		{
			IEnumerator e = WaitForMapToLoad();
			while (e.MoveNext())
			{
				yield return e.Current;
			}
			if (AreaManager.Instance.CurrentArea.SceneName == sceneName)
			{
				NetworkLevelLoader.Instance.RequestReloadLevel(spawnIndex);
			}
		}
	}

	internal static IEnumerator ReloadMapAfterJoin()
	{
		IEnumerator e = WaitForJoin();
		while (e.MoveNext())
		{
			yield return e.Current;
		}
		Log.LogInfo((object)"Joined multiplayer session, performing stack bug fix...");
		IEnumerator f = ReloadMap(SpawnSelectionTypes.SamePlace);
		while (f.MoveNext())
		{
			yield return f.Current;
		}
	}

	internal static IEnumerator WaitForMapToLoad()
	{
		while (!NetworkLevelLoader.Instance.IsSceneLoading)
		{
			yield return null;
		}
		while (NetworkLevelLoader.Instance.InLoading || !NetworkLevelLoader.Instance.AllPlayerDoneLoading)
		{
			yield return null;
		}
	}

	internal static IEnumerator WaitForJoin()
	{
		while ((!NetworkLevelLoader.Instance.IsJoiningWorld || !NetworkLevelLoader.Instance.m_sequenceStarted) && !NetworkLevelLoader.Instance.m_failedJoin)
		{
			yield return null;
		}
		if (NetworkLevelLoader.Instance.m_failedJoin)
		{
			Log.LogInfo((object)"Joining room failed, no need to perform stack bug fix.");
		}
	}

	internal static void StorePlayerPositions()
	{
		//IL_004b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0061: Unknown result type (might be due to invalid IL or missing references)
		playerPositions.Clear();
		playerRotations.Clear();
		foreach (string value in CharacterManager.Instance.PlayerCharacters.Values)
		{
			Character character = CharacterManager.Instance.GetCharacter(value);
			playerPositions.Add(value, ((Component)character).transform.position);
			playerRotations.Add(value, ((Component)character).transform.rotation);
		}
	}

	internal static void TeleportPlayers()
	{
		//IL_005f: Unknown result type (might be due to invalid IL or missing references)
		//IL_007a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0085: Unknown result type (might be due to invalid IL or missing references)
		foreach (string value in CharacterManager.Instance.PlayerCharacters.Values)
		{
			Character character = CharacterManager.Instance.GetCharacter(value);
			if (playerPositions.ContainsKey(value) && playerRotations.ContainsKey(value))
			{
				Log.LogDebug((object)$"Teleporting character '{character.Name}' ({value}) to {playerPositions[value]}");
				character.Teleport(playerPositions[value], playerRotations[value]);
				if ((Object)(object)character.CharacterCamera != (Object)null)
				{
					character.CharacterCamera.ResetCameraToPlayer();
				}
			}
			else
			{
				Log.LogDebug((object)("Not teleporting character '" + character.Name + "' (" + value + ") because their position is not stored"));
			}
		}
	}
}
public static class EnumExtensions
{
	public static string GetDescription<T>(this T? enumerationValue) where T : struct
	{
		if (!enumerationValue.HasValue)
		{
			return "null";
		}
		Type type = enumerationValue.GetType();
		if (!type.IsEnum)
		{
			throw new ArgumentException("EnumerationValue must be of Enum type", "enumerationValue");
		}
		MemberInfo[] member = type.GetMember(enumerationValue.ToString());
		if (member != null && member.Length != 0)
		{
			object[] customAttributes = member[0].GetCustomAttributes(typeof(DescriptionAttribute), inherit: false);
			if (customAttributes != null && customAttributes.Length != 0)
			{
				return ((DescriptionAttribute)customAttributes[0]).Description;
			}
		}
		return enumerationValue.ToString();
	}
}
[HarmonyPatch(typeof(NetworkLevelLoader))]
public static class NetworkLevelLoaderPatches
{
	[HarmonyPatch("OnJoinedRoom")]
	[HarmonyPostfix]
	private static void NetworkLevelLoader_OnJoinedRoom_Postfix(NetworkLevelLoader __instance)
	{
		try
		{
			if (ForceRespawnPlugin.EnableInventoryStackBugFix.Value && PhotonNetwork.isNonMasterClientInRoom)
			{
				((MonoBehaviour)ForceRespawnPlugin.Instance).StartCoroutine(ForceRespawnPlugin.ReloadMapAfterJoin());
			}
		}
		catch (Exception ex)
		{
			ForceRespawnPlugin.Log.LogError((object)$"NetworkLevelLoader.OnJoinedRoom Postfix failed! ({ex.GetType()}): {ex.Message}");
			ForceRespawnPlugin.Log.LogDebug((object)("Stack trace: " + ex.StackTrace));
		}
	}
}
public static class UIHelper
{
	public static GameObject AddButton(GameObject baseButton, string name, int index, string title, UnityAction onClick)
	{
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_004c: Expected O, but got Unknown
		GameObject obj = Object.Instantiate<GameObject>(baseButton, baseButton.transform.parent);
		((Object)obj).name = name;
		obj.transform.SetSiblingIndex(index);
		Text componentInChildren = obj.GetComponentInChildren<Text>();
		Object.Destroy((Object)(object)((Component)componentInChildren).GetComponent<UILocalize>());
		componentInChildren.text = title;
		Button component = obj.GetComponent<Button>();
		component.onClick = new ButtonClickedEvent();
		((UnityEvent)component.onClick).AddListener(onClick);
		return obj;
	}
}
[HarmonyPatch(typeof(PauseMenu))]
public static class PauseMenuPatches
{
	[Serializable]
	[CompilerGenerated]
	private sealed class <>c
	{
		public static readonly <>c <>9 = new <>c();

		public static UnityAction <>9__0_0;

		internal void <PauseMenu_StartInit_Postfix>b__0_0()
		{
			((MonoBehaviour)ForceRespawnPlugin.Instance).StartCoroutine(ForceRespawnPlugin.ReloadMap(ForceRespawnPlugin.SpawnType.Value));
		}
	}

	[HarmonyPatch("StartInit")]
	[HarmonyPostfix]
	private static void PauseMenu_StartInit_Postfix(PauseMenu __instance)
	{
		//IL_0065: Unknown result type (might be due to invalid IL or missing references)
		//IL_0074: 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_0039: Unknown result type (might be due to invalid IL or missing references)
		//IL_003e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Expected O, but got Unknown
		try
		{
			GameObject gameObject = ((Component)__instance.m_hideOnPauseButtons.transform.Find("btnOptions")).gameObject;
			object obj = <>c.<>9__0_0;
			if (obj == null)
			{
				UnityAction val = delegate
				{
					((MonoBehaviour)ForceRespawnPlugin.Instance).StartCoroutine(ForceRespawnPlugin.ReloadMap(ForceRespawnPlugin.SpawnType.Value));
				};
				<>c.<>9__0_0 = val;
				obj = (object)val;
			}
			UIHelper.AddButton(gameObject, "btnForceRespawn", 5, "Respawn", (UnityAction)obj);
			RectTransform component = ((Component)UnityEngineExtensions.FindInAllChildren(((Component)__instance).transform, "BG")).gameObject.GetComponent<RectTransform>();
			component.anchorMin -= new Vector2(0f, 0.1f);
		}
		catch (Exception ex)
		{
			ForceRespawnPlugin.Log.LogError((object)$"Failed to patch PauseMenu UI for player {((UIElement)__instance).CharacterUI.TargetCharacter.Name} ({ex.GetType()}): {ex.Message}");
			ForceRespawnPlugin.Log.LogDebug((object)("Stack trace: " + ex.StackTrace));
		}
	}
}