The BepInEx console will not appear when launching like it does for other games on Thunderstore (you can turn it back on in your BepInEx.cfg file). If your PEAK crashes on startup, add -dx12 to your launch parameters.
Decompiled source of PeakLateJoin v1.2.1
plugins/com.github.vavedev.PeakLateJoin.dll
Decompiled a day agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Logging; using ExitGames.Client.Photon; using Microsoft.CodeAnalysis; using Photon.Pun; using Photon.Realtime; using UnityEngine; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("com.github.vavedev.PeakLateJoin")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.2.1.0")] [assembly: AssemblyInformationalVersion("1.2.1+4fcabfc768ce00c98fe128fb458c92d1ac520303")] [assembly: AssemblyProduct("com.github.vavedev.PeakLateJoin")] [assembly: AssemblyTitle("Peak Late Join")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.2.1.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace BepInEx { [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] [Conditional("CodeGeneration")] internal sealed class BepInAutoPluginAttribute : Attribute { public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null) { } } } namespace BepInEx.Preloader.Core.Patching { [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] [Conditional("CodeGeneration")] internal sealed class PatcherAutoPluginAttribute : Attribute { public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null) { } } } namespace PeakLateJoin { public struct ImprovedSpawnTarget { public Character LowestCharacter; public float LowestClimbed { get { //IL_0019: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)LowestCharacter)) { return float.PositiveInfinity; } return LowestCharacter.Center.y; } } public void RegisterCharacter(Character character) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) if (character.Center.y < LowestClimbed) { LowestCharacter = character; } } } public class LateJoinHandler : MonoBehaviourPunCallbacks { [CompilerGenerated] private sealed class <HandleLateJoin>d__6 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public Player newPlayer; public LateJoinHandler <>4__this; private Character <newCharacter>5__2; private bool <wasDead>5__3; private string <savedStage>5__4; private string <currentStage>5__5; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <HandleLateJoin>d__6(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <newCharacter>5__2 = null; <savedStage>5__4 = null; <currentStage>5__5 = null; <>1__state = -2; } private bool MoveNext() { //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Expected O, but got Unknown //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) int num = <>1__state; LateJoinHandler lateJoinHandler = <>4__this; object value; object value2; Scene activeScene; switch (num) { default: return false; case 0: <>1__state = -1; <newCharacter>5__2 = null; goto IL_0062; case 1: <>1__state = -1; goto IL_0062; case 2: <>1__state = -1; goto IL_0191; case 3: { <>1__state = -1; ImprovedSpawnTarget improvedSpawnTarget = PopulateSpawnData(<newCharacter>5__2); if ((Object)(object)improvedSpawnTarget.LowestCharacter == (Object)null) { lateJoinHandler._logger.LogError((object)"No valid spawn target found."); return false; } lateJoinHandler._logger.LogInfo((object)("Peak late join: " + <newCharacter>5__2.characterName + " will be warped near " + improvedSpawnTarget.LowestCharacter.characterName)); <>2__current = TeleportUtils.SafeWarp(<newCharacter>5__2, improvedSpawnTarget.LowestCharacter, lateJoinHandler._logger); <>1__state = 4; return true; } case 4: { <>1__state = -1; if (<wasDead>5__3 && <savedStage>5__4 != <currentStage>5__5) { <newCharacter>5__2.data.dead = false; lateJoinHandler._logger.LogInfo((object)("Revived " + <newCharacter>5__2.characterName + " since stage changed (" + <savedStage>5__4 + " → " + <currentStage>5__5 + ").")); } SaveDeathState(newPlayer, <newCharacter>5__2.data.dead); lateJoinHandler._lastKnownDead[newPlayer.ActorNumber] = <newCharacter>5__2.data.dead; return false; } IL_0062: if ((Object)(object)<newCharacter>5__2 == (Object)null) { <newCharacter>5__2 = PlayerHandler.GetPlayerCharacter(newPlayer); <>2__current = null; <>1__state = 1; return true; } <wasDead>5__3 = false; <savedStage>5__4 = null; if (((Dictionary<object, object>)(object)((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties).TryGetValue((object)$"dead_{newPlayer.ActorNumber}", out value)) { <wasDead>5__3 = (bool)value; } if (((Dictionary<object, object>)(object)((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties).TryGetValue((object)$"stage_{newPlayer.ActorNumber}", out value2)) { <savedStage>5__4 = value2 as string; } activeScene = SceneManager.GetActiveScene(); <currentStage>5__5 = ((Scene)(ref activeScene)).name; if (<wasDead>5__3 && <savedStage>5__4 == <currentStage>5__5) { lateJoinHandler._logger.LogInfo((object)("Player " + <newCharacter>5__2.characterName + " was dead in stage " + <currentStage>5__5 + ", keeping them dead.")); <newCharacter>5__2.data.dead = true; return false; } goto IL_0191; IL_0191: if ((Object)(object)<newCharacter>5__2.data == (Object)null) { <>2__current = null; <>1__state = 2; return true; } <>2__current = (object)new WaitForSeconds(0.5f); <>1__state = 3; return true; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private ManualLogSource _logger; private readonly Dictionary<int, bool> _lastKnownDead = new Dictionary<int, bool>(); public void InitLogger(ManualLogSource logger) { _logger = logger; } private void Update() { foreach (Character allCharacter in Character.AllCharacters) { if ((Object)(object)((allCharacter != null) ? ((MonoBehaviourPun)allCharacter).photonView : null) == (Object)null || ((MonoBehaviourPun)allCharacter).photonView.Owner == null || (Object)(object)allCharacter.data == (Object)null) { continue; } int actorNumber = ((MonoBehaviourPun)allCharacter).photonView.Owner.ActorNumber; bool dead = allCharacter.data.dead; if (!_lastKnownDead.TryGetValue(actorNumber, out var value) || value != dead) { SaveDeathState(((MonoBehaviourPun)allCharacter).photonView.Owner, dead); _lastKnownDead[actorNumber] = dead; ManualLogSource logger = _logger; if (logger != null) { logger.LogInfo((object)("Updated death state for " + allCharacter.characterName + ": " + (dead ? "dead" : "alive"))); } } } } public override void OnPlayerEnteredRoom(Player newPlayer) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) Scene activeScene = SceneManager.GetActiveScene(); if (((Scene)(ref activeScene)).name != "Airport") { ((MonoBehaviour)this).StartCoroutine(HandleLateJoin(newPlayer)); } } public override void OnPlayerLeftRoom(Player otherPlayer) { Character playerCharacter = PlayerHandler.GetPlayerCharacter(otherPlayer); if ((Object)(object)playerCharacter != (Object)null && (Object)(object)playerCharacter.data != (Object)null) { SaveDeathState(otherPlayer, playerCharacter.data.dead); _lastKnownDead[otherPlayer.ActorNumber] = playerCharacter.data.dead; } } [IteratorStateMachine(typeof(<HandleLateJoin>d__6))] private IEnumerator HandleLateJoin(Player newPlayer) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <HandleLateJoin>d__6(0) { <>4__this = this, newPlayer = newPlayer }; } private static ImprovedSpawnTarget PopulateSpawnData(Character newCharacter) { ImprovedSpawnTarget result = default(ImprovedSpawnTarget); foreach (Character allCharacter in Character.AllCharacters) { if (!allCharacter.data.dead && (Object)(object)allCharacter != (Object)(object)newCharacter) { result.RegisterCharacter(allCharacter); } } return result; } private static void SaveDeathState(Player player, bool isDead) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Expected O, but got Unknown //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Expected O, but got Unknown //IL_0051: Expected O, but got Unknown Scene activeScene = SceneManager.GetActiveScene(); string name = ((Scene)(ref activeScene)).name; Hashtable val = new Hashtable(); ((Dictionary<object, object>)val).Add((object)$"dead_{player.ActorNumber}", (object)isDead); ((Dictionary<object, object>)val).Add((object)$"stage_{player.ActorNumber}", (object)name); Hashtable val2 = val; PhotonNetwork.CurrentRoom.SetCustomProperties(val2, (Hashtable)null, (WebFlags)null); } } [BepInPlugin("vavedev.PeakLateJoin", "Peak Late Join", "1.2.1")] public class Plugin : BaseUnityPlugin { public const string PLUGIN_GUID = "vavedev.PeakLateJoin"; public const string PLUGIN_NAME = "Peak Late Join"; public const string PLUGIN_VERSION = "1.2.1"; internal static ManualLogSource Log { get; private set; } private void Awake() { Log = ((BaseUnityPlugin)this).Logger; Log.LogInfo((object)"Plugin Peak Late Join v1.2.1 loaded!"); ((Component)this).gameObject.AddComponent<LateJoinHandler>().InitLogger(Log); } } public static class TeleportUtils { [CompilerGenerated] private sealed class <SafeWarp>d__0 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public Character newCharacter; public Character targetCharacter; public ManualLogSource logger; private Rigidbody <rb>5__2; private Collider <newCol>5__3; private Collider <targetCol>5__4; private Vector3 <safePos>5__5; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <SafeWarp>d__0(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <rb>5__2 = null; <newCol>5__3 = null; <targetCol>5__4 = null; <>1__state = -2; } private bool MoveNext() { //IL_0392: Unknown result type (might be due to invalid IL or missing references) //IL_039c: Expected O, but got Unknown //IL_0356: Unknown result type (might be due to invalid IL or missing references) //IL_0366: Unknown result type (might be due to invalid IL or missing references) //IL_0376: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: 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_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: 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_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Unknown result type (might be due to invalid IL or missing references) //IL_01f9: Unknown result type (might be due to invalid IL or missing references) //IL_0273: Unknown result type (might be due to invalid IL or missing references) //IL_0278: Unknown result type (might be due to invalid IL or missing references) //IL_0282: Unknown result type (might be due to invalid IL or missing references) //IL_0287: Unknown result type (might be due to invalid IL or missing references) //IL_028c: Unknown result type (might be due to invalid IL or missing references) //IL_0260: Unknown result type (might be due to invalid IL or missing references) //IL_0265: Unknown result type (might be due to invalid IL or missing references) //IL_0217: Unknown result type (might be due to invalid IL or missing references) //IL_021c: Unknown result type (might be due to invalid IL or missing references) //IL_0226: Unknown result type (might be due to invalid IL or missing references) //IL_022b: Unknown result type (might be due to invalid IL or missing references) //IL_02d9: Unknown result type (might be due to invalid IL or missing references) //IL_0308: Unknown result type (might be due to invalid IL or missing references) //IL_0327: Unknown result type (might be due to invalid IL or missing references) //IL_0331: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: { <>1__state = -1; if ((Object)(object)newCharacter == (Object)null || (Object)(object)targetCharacter == (Object)null) { return false; } <rb>5__2 = ((Component)newCharacter).GetComponent<Rigidbody>(); <newCol>5__3 = ((Component)newCharacter).GetComponent<Collider>(); <targetCol>5__4 = ((Component)targetCharacter).GetComponent<Collider>(); if ((Object)(object)<rb>5__2 != (Object)null) { <rb>5__2.isKinematic = true; <rb>5__2.velocity = Vector3.zero; <rb>5__2.angularVelocity = Vector3.zero; } if ((Object)(object)<newCol>5__3 != (Object)null && (Object)(object)<targetCol>5__4 != (Object)null) { Physics.IgnoreCollision(<newCol>5__3, <targetCol>5__4, true); } Vector3[] array = (Vector3[])(object)new Vector3[4] { -((Component)targetCharacter).transform.forward * 1.5f, ((Component)targetCharacter).transform.right * 1.5f, -((Component)targetCharacter).transform.right * 1.5f, ((Component)targetCharacter).transform.forward * 1.5f }; List<Vector3> list = new List<Vector3>(); Vector3[] array2 = array; RaycastHit val3 = default(RaycastHit); foreach (Vector3 val in array2) { Vector3 val2 = ((Component)targetCharacter).transform.position + val + Vector3.up * 0.1f; if (Physics.Raycast(val2 + Vector3.up * 2f, Vector3.down, ref val3, 5f, -1, (QueryTriggerInteraction)1)) { float num = Mathf.Abs(((RaycastHit)(ref val3)).point.y - ((Component)targetCharacter).transform.position.y); if (num < 1f) { list.Add(((RaycastHit)(ref val3)).point + Vector3.up * 0.05f); } } } if (list.Count > 0) { int index = Random.Range(0, list.Count); <safePos>5__5 = list[index]; } else { <safePos>5__5 = targetCharacter.Head + Vector3.up * 2f; } logger.LogInfo((object)string.Format("Safely warping {0} {1} {2} at {3}", newCharacter.characterName, (list.Count > 0) ? "near" : "above", targetCharacter.characterName, <safePos>5__5)); ((MonoBehaviourPun)newCharacter).photonView.RPC("WarpPlayerRPC", (RpcTarget)0, new object[2] { <safePos>5__5, false }); <>2__current = (object)new WaitForSeconds(0.3f); <>1__state = 1; return true; } case 1: <>1__state = -1; if ((Object)(object)<rb>5__2 != (Object)null) { <rb>5__2.position = <safePos>5__5; <rb>5__2.velocity = Vector3.zero; <rb>5__2.angularVelocity = Vector3.zero; <rb>5__2.isKinematic = false; } <>2__current = (object)new WaitForSeconds(0.3f); <>1__state = 2; return true; case 2: <>1__state = -1; if ((Object)(object)<newCol>5__3 != (Object)null && (Object)(object)<targetCol>5__4 != (Object)null) { Physics.IgnoreCollision(<newCol>5__3, <targetCol>5__4, false); } return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [IteratorStateMachine(typeof(<SafeWarp>d__0))] public static IEnumerator SafeWarp(Character newCharacter, Character targetCharacter, ManualLogSource logger) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <SafeWarp>d__0(0) { newCharacter = newCharacter, targetCharacter = targetCharacter, logger = logger }; } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }