Decompiled source of FusionPlayerJoinLogger v1.0.0

Mods/FusionPlayerJoinLogger.dll

Decompiled 2 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.CompilerServices;
using FusionPlayerJoinLogger;
using LabFusion.Player;
using LabFusion.SDK.Metadata;
using LabFusion.Utilities;
using MelonLoader;

[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: MelonInfo(typeof(Core), "FusionPlayerJoinLogger", "1.0.0", "FAIXI", null)]
[assembly: MelonGame("Stress Level Zero", "BONELAB")]
[assembly: CompilationRelaxations(8)]
[assembly: AssemblyVersion("0.0.0.0")]
namespace FusionPlayerJoinLogger;

public class Core : MelonMod
{
	private const string TAG = "[FPJL] ";

	private const int SNAPSHOT_DELAY_FRAMES = 90;

	private const int RETRY_DELAY_FRAMES = 90;

	private static bool _hooked;

	private static int _lastSnapshotCount;

	public override void OnInitializeMelon()
	{
		//IL_0009: Unknown result type (might be due to invalid IL or missing references)
		//IL_0013: Expected O, but got Unknown
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0025: Expected O, but got Unknown
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0037: Expected O, but got Unknown
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: Expected O, but got Unknown
		//IL_0051: Unknown result type (might be due to invalid IL or missing references)
		//IL_005b: Expected O, but got Unknown
		try
		{
			MultiplayerHooking.OnPlayerJoined += new PlayerUpdate(HandlePlayerJoined);
			MultiplayerHooking.OnPlayerLeft += new PlayerUpdate(HandlePlayerLeft);
			MultiplayerHooking.OnJoinedServer += new ServerEvent(HandleJoinedServer);
			MultiplayerHooking.OnStartedServer += new ServerEvent(HandleStartedServer);
			MultiplayerHooking.OnDisconnected += new ServerEvent(HandleDisconnected);
			_hooked = true;
			((MelonBase)this).LoggerInstance.Msg("v1.0.0 ready — join hook + lobby snapshot armed.");
		}
		catch (global::System.Exception ex)
		{
			((MelonBase)this).LoggerInstance.Error(string.Concat((object)"init failed: ", (object)ex));
		}
	}

	public override void OnDeinitializeMelon()
	{
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0027: Expected O, but got Unknown
		//IL_0039: Unknown result type (might be due to invalid IL or missing references)
		//IL_0043: Expected O, but got Unknown
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		//IL_005f: Expected O, but got Unknown
		//IL_0071: Unknown result type (might be due to invalid IL or missing references)
		//IL_007b: Expected O, but got Unknown
		//IL_008d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0097: Expected O, but got Unknown
		if (!_hooked)
		{
			return;
		}
		_hooked = false;
		try
		{
			MultiplayerHooking.OnPlayerJoined -= new PlayerUpdate(HandlePlayerJoined);
		}
		catch (global::System.Exception)
		{
		}
		try
		{
			MultiplayerHooking.OnPlayerLeft -= new PlayerUpdate(HandlePlayerLeft);
		}
		catch (global::System.Exception)
		{
		}
		try
		{
			MultiplayerHooking.OnJoinedServer -= new ServerEvent(HandleJoinedServer);
		}
		catch (global::System.Exception)
		{
		}
		try
		{
			MultiplayerHooking.OnStartedServer -= new ServerEvent(HandleStartedServer);
		}
		catch (global::System.Exception)
		{
		}
		try
		{
			MultiplayerHooking.OnDisconnected -= new ServerEvent(HandleDisconnected);
		}
		catch (global::System.Exception)
		{
		}
	}

	private static void HandlePlayerJoined(PlayerID id)
	{
		try
		{
			if (id == null)
			{
				MelonLogger.Warning("[FPJL] WARNING: player joined with a null PlayerID, skipped.");
				return;
			}
			bool flag = false;
			try
			{
				flag = id.IsMe;
			}
			catch (global::System.Exception)
			{
			}
			if (!flag)
			{
				MelonLogger.Msg("[FPJL] Player joined | " + Describe(id));
			}
		}
		catch (global::System.Exception ex2)
		{
			MelonLogger.Warning("[FPJL] join handler failed: " + ex2.Message);
		}
	}

	private static void HandlePlayerLeft(PlayerID id)
	{
		try
		{
			if (id != null)
			{
				bool flag = false;
				try
				{
					flag = id.IsMe;
				}
				catch (global::System.Exception)
				{
				}
				if (!flag)
				{
					MelonLogger.Msg("[FPJL] Player left | " + Describe(id));
				}
			}
		}
		catch (global::System.Exception ex2)
		{
			MelonLogger.Warning("[FPJL] leave handler failed: " + ex2.Message);
		}
	}

	private static void HandleJoinedServer()
	{
		try
		{
			MelonCoroutines.Start(SnapshotRoutine());
		}
		catch (global::System.Exception ex)
		{
			MelonLogger.Warning("[FPJL] could not start snapshot routine: " + ex.Message);
		}
	}

	private static void HandleStartedServer()
	{
		try
		{
			MelonCoroutines.Start(SnapshotRoutine());
		}
		catch (global::System.Exception ex)
		{
			MelonLogger.Warning("[FPJL] could not start snapshot routine: " + ex.Message);
		}
	}

	private static void HandleDisconnected()
	{
		try
		{
			_lastSnapshotCount = 0;
		}
		catch (global::System.Exception)
		{
		}
	}

	private static global::System.Collections.IEnumerator SnapshotRoutine()
	{
		for (int i = 0; i < 90; i++)
		{
			yield return null;
		}
		SnapshotLobbyMembers();
		if (_lastSnapshotCount == 0 && SafePlayerCount() > 1)
		{
			MelonLogger.Msg("[FPJL] no members found yet, retrying snapshot...");
			for (int j = 0; j < 90; j++)
			{
				yield return null;
			}
			SnapshotLobbyMembers();
		}
	}

	private static void SnapshotLobbyMembers()
	{
		//IL_014b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0150: Unknown result type (might be due to invalid IL or missing references)
		int num = 0;
		MelonLogger.Msg("[FPJL] Lobby snapshot start | Local player: " + LocalNickname());
		HashSet<byte> val = new HashSet<byte>();
		try
		{
			int num2 = SafeMinId();
			int num3 = SafeMaxId();
			for (int i = num2; i <= num3; i++)
			{
				try
				{
					PlayerID playerID = PlayerIDManager.GetPlayerID((byte)i);
					if (playerID != null)
					{
						byte b;
						try
						{
							b = playerID.SmallID;
						}
						catch (global::System.Exception)
						{
							b = (byte)i;
						}
						if (val.Add(b) && !IsLocal(playerID) && ReportMember(playerID))
						{
							num++;
						}
					}
				}
				catch (global::System.Exception ex2)
				{
					MelonLogger.Warning(string.Concat(new object[4] { "[FPJL] scan error at session id ", i, ": ", ex2.Message }));
				}
			}
		}
		catch (global::System.Exception ex2)
		{
			MelonLogger.Warning("[FPJL] id scan failed: " + ex2.Message);
		}
		if (num == 0 && SafePlayerCount() > 1)
		{
			List<PlayerID> val2 = new List<PlayerID>();
			try
			{
				Enumerator<PlayerID> enumerator = PlayerIDManager.PlayerIDs.GetEnumerator();
				try
				{
					while (enumerator.MoveNext())
					{
						PlayerID playerID = enumerator.Current;
						if (playerID != null)
						{
							val2.Add(playerID);
						}
					}
				}
				finally
				{
					((global::System.IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
				}
			}
			catch (global::System.Exception ex2)
			{
				MelonLogger.Warning("[FPJL] PlayerIDs enumeration failed: " + ex2.Message);
			}
			for (int i = 0; i < val2.Count; i++)
			{
				try
				{
					PlayerID playerID = val2[i];
					byte b;
					try
					{
						b = playerID.SmallID;
					}
					catch (global::System.Exception)
					{
						b = 0;
					}
					if (val.Add(b) && !IsLocal(playerID) && ReportMember(playerID))
					{
						num++;
					}
				}
				catch (global::System.Exception ex2)
				{
					MelonLogger.Warning("[FPJL] member report failed: " + ex2.Message);
				}
			}
		}
		_lastSnapshotCount = num;
		MelonLogger.Msg(string.Concat((object)"[FPJL] Lobby snapshot end | Total members: ", (object)num));
	}

	private static bool ReportMember(PlayerID p)
	{
		ulong num = 0uL;
		bool flag = true;
		try
		{
			num = p.PlatformID;
		}
		catch (global::System.Exception)
		{
			flag = false;
		}
		if (!flag || num == 0)
		{
			MelonLogger.Warning(string.Concat((object)"[FPJL] WARNING: PlayerID is null for session ID ", (object)SafeSmallId(p), (object)", PlatformID unavailable."));
			return false;
		}
		MelonLogger.Msg(string.Concat(new object[4]
		{
			"[FPJL] Lobby member | Nickname: ",
			Nickname(p),
			" | PlatformID: ",
			num
		}));
		return true;
	}

	private static string Describe(PlayerID p)
	{
		ulong num = 0uL;
		try
		{
			num = p.PlatformID;
		}
		catch (global::System.Exception)
		{
		}
		return string.Concat(new object[4]
		{
			"Nickname: ",
			Nickname(p),
			" | PlatformID: ",
			num
		});
	}

	private static string Nickname(PlayerID p)
	{
		try
		{
			PlayerMetadata metadata = p.Metadata;
			if (metadata == null)
			{
				return "(no metadata)";
			}
			MetadataVariable nickname = metadata.Nickname;
			if (nickname != null)
			{
				string valueOrEmpty = nickname.GetValueOrEmpty();
				if (!string.IsNullOrEmpty(valueOrEmpty))
				{
					return valueOrEmpty;
				}
			}
			MetadataVariable username = metadata.Username;
			if (username != null)
			{
				string valueOrEmpty2 = username.GetValueOrEmpty();
				if (!string.IsNullOrEmpty(valueOrEmpty2))
				{
					return valueOrEmpty2;
				}
			}
		}
		catch (global::System.Exception)
		{
		}
		return "(unknown)";
	}

	private static string LocalNickname()
	{
		try
		{
			PlayerID localID = PlayerIDManager.LocalID;
			if (localID == null)
			{
				return "(none)";
			}
			return Nickname(localID);
		}
		catch (global::System.Exception)
		{
			return "(unknown)";
		}
	}

	private static bool IsLocal(PlayerID p)
	{
		try
		{
			return p.IsMe;
		}
		catch (global::System.Exception)
		{
			return false;
		}
	}

	private static byte SafeSmallId(PlayerID p)
	{
		try
		{
			return p.SmallID;
		}
		catch (global::System.Exception)
		{
			return 0;
		}
	}

	private static int SafePlayerCount()
	{
		try
		{
			return PlayerIDManager.PlayerCount;
		}
		catch (global::System.Exception)
		{
			return 0;
		}
	}

	private static int SafeMinId()
	{
		try
		{
			return 0;
		}
		catch (global::System.Exception)
		{
			return 0;
		}
	}

	private static int SafeMaxId()
	{
		try
		{
			return 255;
		}
		catch (global::System.Exception)
		{
			return 255;
		}
	}
}