using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Photon.Pun;
using Photon.Realtime;
using UnityEngine;
using UnityEngine.SceneManagement;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("latejoinfix2")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("latejoinfix2")]
[assembly: AssemblyCopyright("Copyright © 2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("b78d6a4e-bdfc-4a7a-9193-c02df76c2f95")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
[BepInPlugin("com.sol.latejoinfix", "LateJoinFix", "1.3.1")]
public class LateJoinFix : BaseUnityPlugin
{
public class LateJoinRoomListener : MonoBehaviourPunCallbacks
{
[CompilerGenerated]
private sealed class <HandleLateJoin>d__1 : IEnumerator<object>, IDisposable, IEnumerator
{
private int <>1__state;
private object <>2__current;
public Player newPlayer;
public LateJoinRoomListener <>4__this;
private Character <newCharacter>5__1;
private float <elapsed>5__2;
private ImprovedSpawnTarget <spawnTarget>5__3;
private Exception <ex>5__4;
private Vector3 <warpTarget>5__5;
private Exception <ex>5__6;
private Vector3 <revivePos>5__7;
private Exception <ex>5__8;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <HandleLateJoin>d__1(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<newCharacter>5__1 = null;
<spawnTarget>5__3 = null;
<ex>5__4 = null;
<ex>5__6 = null;
<ex>5__8 = null;
<>1__state = -2;
}
private bool MoveNext()
{
//IL_02a3: Unknown result type (might be due to invalid IL or missing references)
//IL_02ad: Expected O, but got Unknown
//IL_0046: Unknown result type (might be due to invalid IL or missing references)
//IL_0050: Expected O, but got Unknown
//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
//IL_00d6: Expected O, but got Unknown
//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
//IL_02ca: Unknown result type (might be due to invalid IL or missing references)
//IL_02e3: Unknown result type (might be due to invalid IL or missing references)
//IL_02e8: Unknown result type (might be due to invalid IL or missing references)
//IL_02ed: Unknown result type (might be due to invalid IL or missing references)
//IL_030c: Unknown result type (might be due to invalid IL or missing references)
//IL_0340: 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_01f7: Unknown result type (might be due to invalid IL or missing references)
//IL_0206: Unknown result type (might be due to invalid IL or missing references)
//IL_020b: Unknown result type (might be due to invalid IL or missing references)
//IL_0210: Unknown result type (might be due to invalid IL or missing references)
//IL_022f: Unknown result type (might be due to invalid IL or missing references)
//IL_024f: Unknown result type (might be due to invalid IL or missing references)
//IL_0254: Unknown result type (might be due to invalid IL or missing references)
//IL_0133: Unknown result type (might be due to invalid IL or missing references)
//IL_013d: Expected O, but got Unknown
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
<>2__current = (object)new WaitForSeconds(0.2f);
<>1__state = 1;
return true;
case 1:
<>1__state = -1;
<newCharacter>5__1 = null;
<elapsed>5__2 = 0f;
goto IL_00f9;
case 2:
<>1__state = -1;
<elapsed>5__2 += 0.1f;
goto IL_00f9;
case 3:
<>1__state = -1;
<spawnTarget>5__3 = PopulateSpawnData(<newCharacter>5__1);
if ((Object)(object)<spawnTarget>5__3.LowestCharacter == (Object)null)
{
LogError("[LateJoinFix] No valid spawn target found.");
return false;
}
LogInfo($"[LateJoinFix] Moving {<newCharacter>5__1.characterName} from [{<newCharacter>5__1.Center}] to lowest character: {<spawnTarget>5__3.LowestCharacter.characterName} [{<spawnTarget>5__3.LowestCharacter.Center}]");
try
{
<warpTarget>5__5 = <spawnTarget>5__3.LowestCharacter.Center + Vector3.forward * WarpForwardOffset.Value;
((MonoBehaviourPun)<newCharacter>5__1).photonView.RPC("WarpPlayerRPC", (RpcTarget)0, new object[2] { <warpTarget>5__5, false });
Vector3 val = <warpTarget>5__5;
LogInfo("[LateJoinFix] Warp sent to " + ((object)(Vector3)(ref val)).ToString());
}
catch (Exception ex)
{
<ex>5__6 = ex;
LogWarning("[LateJoinFix] WarpPlayerRPC failed: " + <ex>5__6.Message);
}
<>2__current = (object)new WaitForSeconds(AfterWarpDelay.Value);
<>1__state = 4;
return true;
case 4:
{
<>1__state = -1;
try
{
<revivePos>5__7 = <spawnTarget>5__3.LowestCharacter.Center + new Vector3(0f, ReviveHeightOffset.Value, 0f);
((MonoBehaviourPun)<newCharacter>5__1).photonView.RPC("RPCA_ReviveAtPosition", (RpcTarget)0, new object[3] { <revivePos>5__7, false, -1 });
LogInfo($"[LateJoinFix] Revived {<newCharacter>5__1.characterName} at {<revivePos>5__7} after delayed revive");
}
catch (Exception ex)
{
<ex>5__8 = ex;
LogWarning("[LateJoinFix] RPCA_ReviveAtPosition failed: " + <ex>5__8.Message);
}
return false;
}
IL_00f9:
if (<elapsed>5__2 < 30f)
{
try
{
<newCharacter>5__1 = PlayerHandler.GetPlayerCharacter(newPlayer);
}
catch (Exception ex)
{
<ex>5__4 = ex;
LogWarning("[LateJoinFix] GetPlayerCharacter exception: " + <ex>5__4.Message);
}
if (!((Object)(object)<newCharacter>5__1 != (Object)null))
{
<>2__current = (object)new WaitForSeconds(0.1f);
<>1__state = 2;
return true;
}
}
if ((Object)(object)<newCharacter>5__1 == (Object)null)
{
LogError("[LateJoinFix] Failed to find new character.");
return false;
}
<>2__current = (object)new WaitForSeconds(0.1f);
<>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();
}
}
public override void OnPlayerEnteredRoom(Player newPlayer)
{
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
if (newPlayer != null && PhotonNetwork.IsMasterClient)
{
Scene activeScene = SceneManager.GetActiveScene();
if (!(((Scene)(ref activeScene)).name == "Airport"))
{
LogInfo("[LateJoinFix] OnPlayerEnteredRoom: " + newPlayer.NickName + " / " + newPlayer.ActorNumber);
((MonoBehaviour)this).StartCoroutine(HandleLateJoin(newPlayer));
}
}
}
[IteratorStateMachine(typeof(<HandleLateJoin>d__1))]
private IEnumerator HandleLateJoin(Player newPlayer)
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <HandleLateJoin>d__1(0)
{
<>4__this = this,
newPlayer = newPlayer
};
}
private static ImprovedSpawnTarget PopulateSpawnData(Character newCharacter)
{
ImprovedSpawnTarget improvedSpawnTarget = new ImprovedSpawnTarget();
foreach (Character allCharacter in Character.AllCharacters)
{
if (!((Object)(object)allCharacter == (Object)null) && !((Object)(object)allCharacter.data == (Object)null) && !((Object)(object)allCharacter == (Object)(object)newCharacter) && !allCharacter.data.dead)
{
improvedSpawnTarget.RegisterCharacter(allCharacter);
}
}
return improvedSpawnTarget;
}
}
public class ImprovedSpawnTarget
{
private float lowestClimbed = float.MaxValue;
public Character LowestCharacter;
public void RegisterCharacter(Character character)
{
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
if (!((Object)(object)character == (Object)null) && character.Center.y < lowestClimbed)
{
lowestClimbed = character.Center.y;
LowestCharacter = character;
}
}
}
internal static ManualLogSource Log;
internal static ConfigEntry<float> AfterWarpDelay;
internal static ConfigEntry<float> WarpForwardOffset;
internal static ConfigEntry<float> ReviveHeightOffset;
private const float InitialDelayAfterJoinEvent = 0.2f;
private const float CharacterSearchInterval = 0.1f;
private const float AfterCharacterFoundDelay = 0.1f;
private const float CharacterSearchTimeoutSeconds = 30f;
private void Awake()
{
Log = ((BaseUnityPlugin)this).Logger;
AfterWarpDelay = ((BaseUnityPlugin)this).Config.Bind<float>("Timing", "AfterWarpDelay", 2f, "워프 후 부활 RPC를 보내기 전 대기 시간(초).");
WarpForwardOffset = ((BaseUnityPlugin)this).Config.Bind<float>("Position", "WarpForwardOffset", 2f, "대상 플레이어 위치에서 월드 전방(Vector3.forward)으로 비껴서 워프할 거리.");
ReviveHeightOffset = ((BaseUnityPlugin)this).Config.Bind<float>("Position", "ReviveHeightOffset", 3f, "대상 플레이어 Center 기준 부활 위치의 높이 오프셋.");
((BaseUnityPlugin)this).Logger.LogInfo((object)"LateJoinFix loaded.");
((Component)this).gameObject.AddComponent<LateJoinRoomListener>();
}
internal static void LogInfo(string msg)
{
Log.LogInfo((object)msg);
}
internal static void LogWarning(string msg)
{
Log.LogWarning((object)msg);
}
internal static void LogError(string msg)
{
Log.LogError((object)msg);
}
}