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.3.0
plugins/com.github.vavedev.PeakLateJoin.dll
Decompiled a month 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.3.0.0")] [assembly: AssemblyInformationalVersion("1.3.0+3fa897d6573d254d234718a7b49321b711dd01cf")] [assembly: AssemblyProduct("com.github.vavedev.PeakLateJoin")] [assembly: AssemblyTitle("Peak Late Join")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.3.0.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; private float _lowestY; public void RegisterCharacter(Character character, float y) { if ((Object)(object)LowestCharacter == (Object)null || y < _lowestY) { LowestCharacter = character; _lowestY = y; } } } 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_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Expected O, but got Unknown //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_0238: Unknown result type (might be due to invalid IL or missing references) //IL_0225: Unknown result type (might be due to invalid IL or missing references) //IL_023d: Unknown result type (might be due to invalid IL or missing references) //IL_0261: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Expected O, but got Unknown //IL_029f: Unknown result type (might be due to invalid IL or missing references) int num = <>1__state; LateJoinHandler lateJoinHandler = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; <newCharacter>5__2 = null; goto IL_0066; case 1: <>1__state = -1; goto IL_0066; case 2: <>1__state = -1; goto IL_008d; case 3: { <>1__state = -1; <wasDead>5__3 = false; <savedStage>5__4 = null; if (((Dictionary<object, object>)(object)((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties).TryGetValue((object)$"dead_{newPlayer.ActorNumber}", out object value)) { <wasDead>5__3 = (bool)value; } if (((Dictionary<object, object>)(object)((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties).TryGetValue((object)$"stage_{newPlayer.ActorNumber}", out object value2)) { <savedStage>5__4 = value2 as string; } Scene activeScene = SceneManager.GetActiveScene(); <currentStage>5__5 = ((Scene)(ref activeScene)).name; ManualLogSource logger = lateJoinHandler._logger; if (logger != null) { logger.LogInfo((object)$"[LateJoin] {<newCharacter>5__2.characterName} joined. SavedStage={<savedStage>5__4}, CurrentStage={<currentStage>5__5}, WasDead={<wasDead>5__3}"); } <>2__current = (object)new WaitForSeconds(0.5f); <>1__state = 4; return true; } case 4: { <>1__state = -1; ImprovedSpawnTarget improvedSpawnTarget = PopulateSpawnData(<newCharacter>5__2); if ((Object)(object)improvedSpawnTarget.LowestCharacter == (Object)null) { lateJoinHandler._logger.LogWarning((object)("[LateJoin] No valid spawn target found. Keeping " + <newCharacter>5__2.characterName + " at spawn.")); return false; } Vector3 val = (improvedSpawnTarget.LowestCharacter.data.isGrounded ? improvedSpawnTarget.LowestCharacter.data.groundPos : ((Component)improvedSpawnTarget.LowestCharacter).transform.position); lateJoinHandler._logger.LogInfo((object)$"[LateJoin] {<newCharacter>5__2.characterName} → warping near {improvedSpawnTarget.LowestCharacter.characterName} at Y={val.y:F2}"); if ((Object)(object)<newCharacter>5__2.data.spawnPoint != (Object)null) { <newCharacter>5__2.data.spawnPoint.position = val; } <>2__current = TeleportUtils.SafeWarp(<newCharacter>5__2, improvedSpawnTarget.LowestCharacter, lateJoinHandler._logger); <>1__state = 5; return true; } case 5: { <>1__state = -1; if (<wasDead>5__3) { if (<savedStage>5__4 == <currentStage>5__5) { <newCharacter>5__2.data.dead = true; lateJoinHandler._logger.LogInfo((object)("[LateJoin] " + <newCharacter>5__2.characterName + " kept dead (same stage).")); } else { <newCharacter>5__2.data.dead = false; lateJoinHandler._logger.LogInfo((object)("[LateJoin] " + <newCharacter>5__2.characterName + " revived (stage changed).")); } } SaveDeathState(newPlayer, <newCharacter>5__2.data.dead); lateJoinHandler._lastKnownDead[newPlayer.ActorNumber] = <newCharacter>5__2.data.dead; lateJoinHandler._logger.LogInfo((object)("[LateJoin] Finished processing " + <newCharacter>5__2.characterName + ".")); return false; } IL_008d: if ((Object)(object)<newCharacter>5__2.data == (Object)null) { <>2__current = null; <>1__state = 2; return true; } <>2__current = (object)new WaitForSeconds(1.5f); <>1__state = 3; return true; IL_0066: if ((Object)(object)<newCharacter>5__2 == (Object)null) { <newCharacter>5__2 = PlayerHandler.GetPlayerCharacter(newPlayer); <>2__current = null; <>1__state = 1; return true; } goto IL_008d; } } 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)("[DeathSync] " + 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) { //IL_005d: Unknown result type (might be due to invalid IL or missing references) ImprovedSpawnTarget result = default(ImprovedSpawnTarget); foreach (Character allCharacter in Character.AllCharacters) { if (!((Object)(object)allCharacter == (Object)null) && !((Object)(object)allCharacter == (Object)(object)newCharacter) && !((Object)(object)allCharacter.data == (Object)null) && !allCharacter.data.dead) { float y = (allCharacter.data.isGrounded ? allCharacter.data.groundPos.y : ((Component)allCharacter).transform.position.y); result.RegisterCharacter(allCharacter, y); } } 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.3.0")] 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.3.0"; internal static ManualLogSource Log { get; private set; } private void Awake() { Log = ((BaseUnityPlugin)this).Logger; Log.LogInfo((object)"Plugin Peak Late Join v1.3.0 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_03a2: Unknown result type (might be due to invalid IL or missing references) //IL_03ac: Expected O, but got Unknown //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_0386: 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_010b: 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) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_011d: 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_01d2: Unknown result type (might be due to invalid IL or missing references) //IL_01d4: Unknown result type (might be due to invalid IL or missing references) //IL_01d5: 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) //IL_01dc: Unknown result type (might be due to invalid IL or missing references) //IL_01e6: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Unknown result type (might be due to invalid IL or missing references) //IL_01f4: Unknown result type (might be due to invalid IL or missing references) //IL_01fe: Unknown result type (might be due to invalid IL or missing references) //IL_0203: Unknown result type (might be due to invalid IL or missing references) //IL_0208: Unknown result type (might be due to invalid IL or missing references) //IL_021f: Unknown result type (might be due to invalid IL or missing references) //IL_0229: Unknown result type (might be due to invalid IL or missing references) //IL_0296: Unknown result type (might be due to invalid IL or missing references) //IL_0297: Unknown result type (might be due to invalid IL or missing references) //IL_02a1: Unknown result type (might be due to invalid IL or missing references) //IL_02a6: Unknown result type (might be due to invalid IL or missing references) //IL_02ab: Unknown result type (might be due to invalid IL or missing references) //IL_0289: Unknown result type (might be due to invalid IL or missing references) //IL_028e: Unknown result type (might be due to invalid IL or missing references) //IL_0243: Unknown result type (might be due to invalid IL or missing references) //IL_0248: Unknown result type (might be due to invalid IL or missing references) //IL_0252: Unknown result type (might be due to invalid IL or missing references) //IL_0257: Unknown result type (might be due to invalid IL or missing references) //IL_0337: Unknown result type (might be due to invalid IL or missing references) //IL_0341: Expected O, but got Unknown //IL_0318: Unknown result type (might be due to invalid IL or missing references) 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 val = (((Object)(object)targetCharacter.data != (Object)null && targetCharacter.data.isGrounded) ? targetCharacter.data.groundPos : ((Component)targetCharacter).transform.position); 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 val4 = default(RaycastHit); foreach (Vector3 val2 in array2) { Vector3 val3 = val + val2 + Vector3.up * 0.1f; if (Physics.Raycast(val3 + Vector3.up * 2f, Vector3.down, ref val4, 6f, -1, (QueryTriggerInteraction)1)) { float num = Mathf.Abs(((RaycastHit)(ref val4)).point.y - val.y); if (num < 1.5f) { list.Add(((RaycastHit)(ref val4)).point + Vector3.up * 0.05f); } } } if (list.Count > 0) { <safePos>5__5 = list[Random.Range(0, list.Count)]; } else { <safePos>5__5 = val + Vector3.up * 1.5f; } logger.LogInfo((object)$"[SafeWarp] Warping {newCharacter.characterName} near {targetCharacter.characterName} → Y={<safePos>5__5.y:F2}"); if ((Object)(object)((MonoBehaviourPun)newCharacter).photonView != (Object)null) { ((MonoBehaviourPun)newCharacter).photonView.RPC("WarpPlayerRPC", (RpcTarget)0, new object[2] { <safePos>5__5, false }); } <>2__current = (object)new WaitForSeconds(0.5f); <>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.5f); <>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) { } } }