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));
}
}
}