Decompiled source of moreStrafts v0.0.3

moreStrafts.dll

Decompiled 2 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using FishNet;
using FishNet.Object;
using FishNet.Object.Synchronizing;
using FishNet.Transporting;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Steamworks;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("moreStrafts")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("moreStrafts")]
[assembly: AssemblyTitle("moreStrafts")]
[assembly: AssemblyVersion("1.0.0.0")]
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;
		}
	}
}
namespace moreStrafts
{
	[BepInPlugin("com.nitrogenia.morestrafts", "More Strafts Players", "0.0.1")]
	public class moreStraftsMod : BaseUnityPlugin
	{
		private void Awake()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			new Harmony("com.nitrogenia.morestrafts").PatchAll(Assembly.GetExecutingAssembly());
			((BaseUnityPlugin)this).Logger.LogInfo((object)"More Strafts Mod alpha v0.0.1 by Nitrogenia loaded! Max players extended to 10.");
		}
	}
	[HarmonyPatch(typeof(SteamLobby), "Start")]
	public static class SteamLobbyStartPatch
	{
		private static void Postfix(SteamLobby __instance)
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Expected O, but got Unknown
			if ((Object)(object)__instance.MaxPlayersDropdown != (Object)null)
			{
				__instance.MaxPlayersDropdown.options.Clear();
				for (int i = 2; i <= 10; i++)
				{
					__instance.MaxPlayersDropdown.options.Add(new OptionData($"{i} Players"));
				}
				__instance.MaxPlayersDropdown.value = 2;
				__instance.MaxPlayersDropdown.RefreshShownValue();
				Debug.Log((object)"[moreStrafts] Main menu MaxPlayersDropdown expanded to 2-10 players");
			}
			try
			{
				Transport val = InstanceFinder.TransportManager?.Transport;
				if ((Object)(object)val != (Object)null)
				{
					val.SetMaximumClients(9);
					Debug.Log((object)"[moreStrafts] Set transport maximum clients to 9");
				}
			}
			catch (Exception ex)
			{
				Debug.LogError((object)("[moreStrafts] Failed to set transport max clients: " + ex.Message));
			}
		}
	}
	[HarmonyPatch(typeof(SteamLobby), "OnLobbyCreated")]
	public static class OnLobbyCreatedPatch
	{
		private static void Prefix(SteamLobby __instance, LobbyCreated_t callback)
		{
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Expected O, but got Unknown
			if ((Object)(object)__instance.MaxPlayersDropdown != (Object)null)
			{
				int value = __instance.MaxPlayersDropdown.value;
				__instance.MaxPlayersDropdown.options.Clear();
				for (int i = 2; i <= 10; i++)
				{
					__instance.MaxPlayersDropdown.options.Add(new OptionData($"{i} Players"));
				}
				__instance.MaxPlayersDropdown.value = value;
				__instance.MaxPlayersDropdown.RefreshShownValue();
				Debug.Log((object)$"[moreStrafts] OnLobbyCreated Prefix: Expanded dropdown to 2-10, preserved value {value}");
			}
		}

		private static void Postfix(SteamLobby __instance, LobbyCreated_t callback)
		{
			Debug.Log((object)$"[moreStrafts] Lobby created with {__instance.maxPlayers} max players (dropdown value: {__instance.MaxPlayersDropdown.value})");
			try
			{
				Transport val = InstanceFinder.TransportManager?.Transport;
				if ((Object)(object)val != (Object)null)
				{
					val.SetMaximumClients(__instance.maxPlayers - 1);
					Debug.Log((object)$"[moreStrafts] Lobby created - transport max clients set to {__instance.maxPlayers - 1}");
				}
			}
			catch (Exception ex)
			{
				Debug.LogError((object)("[moreStrafts] Failed to set transport max clients on lobby creation: " + ex.Message));
			}
		}
	}
	[HarmonyPatch(typeof(SteamLobby), "OnLobbyEntered")]
	public static class OnLobbyEnteredPatch
	{
		private static void Postfix(SteamLobby __instance, LobbyEnter_t callback)
		{
			int maxPlayers = __instance.maxPlayers;
			Debug.Log((object)$"[moreStrafts] Lobby entered - max players: {maxPlayers}");
			try
			{
				Transport val = InstanceFinder.TransportManager?.Transport;
				if ((Object)(object)val != (Object)null)
				{
					val.SetMaximumClients(maxPlayers - 1);
					Debug.Log((object)$"[moreStrafts] Transport configured for {maxPlayers - 1} clients (max players: {maxPlayers})");
				}
			}
			catch (Exception ex)
			{
				Debug.LogError((object)("[moreStrafts] Failed to configure transport on lobby enter: " + ex.Message));
			}
		}
	}
	[HarmonyPatch(typeof(SteamLobby), "OnGetLobbyList")]
	public static class OnGetLobbyListPatch
	{
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Expected O, but got Unknown
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			for (int i = 0; i < list.Count; i++)
			{
				if (list[i].opcode == OpCodes.Ldc_I4_4 && i + 1 < list.Count && (list[i + 1].opcode == OpCodes.Bgt || list[i + 1].opcode == OpCodes.Bgt_S || list[i + 1].opcode == OpCodes.Ble || list[i + 1].opcode == OpCodes.Ble_S))
				{
					list[i] = new CodeInstruction(OpCodes.Ldc_I4_S, (object)(sbyte)10);
					Debug.Log((object)"[moreStrafts] Patched OnGetLobbyList: Changed lobby member limit check from 4 to 10");
				}
			}
			return list;
		}
	}
	[HarmonyPatch(typeof(LobbyController), "RemoveExtraPlayerItem")]
	public static class RemoveExtraPlayerItemPatch
	{
		private static bool Prefix(LobbyController __instance)
		{
			List<PlayerListItem> value = Traverse.Create((object)__instance).Field("PlayerListItems").GetValue<List<PlayerListItem>>();
			List<PlayerListItem> value2 = Traverse.Create((object)__instance).Field("PlayerListItemsTab").GetValue<List<PlayerListItem>>();
			int maxPlayers = SteamLobby.Instance.maxPlayers;
			List<PlayerListItem> list = new List<PlayerListItem>();
			for (int i = 0; i < value.Count; i++)
			{
				if (i >= maxPlayers)
				{
					list.Add(value[i]);
				}
			}
			foreach (PlayerListItem item in list)
			{
				Object.Destroy((Object)(object)((Component)item).gameObject);
				value.Remove(item);
			}
			List<PlayerListItem> list2 = new List<PlayerListItem>();
			for (int j = 0; j < value2.Count; j++)
			{
				if (j >= maxPlayers)
				{
					list2.Add(value2[j]);
				}
			}
			foreach (PlayerListItem item2 in list2)
			{
				Object.Destroy((Object)(object)((Component)item2).gameObject);
				value2.Remove(item2);
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(LobbyController), "CreateClientPlayerItem")]
	public static class CreateClientPlayerItemPatch
	{
		private static bool Prefix(LobbyController __instance)
		{
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0272: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: 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_01a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a8: Unknown result type (might be due to invalid IL or missing references)
			List<PlayerListItem> value = Traverse.Create((object)__instance).Field("PlayerListItems").GetValue<List<PlayerListItem>>();
			List<PlayerListItem> value2 = Traverse.Create((object)__instance).Field("PlayerListItemsTab").GetValue<List<PlayerListItem>>();
			SteamLobby value3 = Traverse.Create((object)__instance).Field("manager").GetValue<SteamLobby>();
			Transform value4 = Traverse.Create((object)__instance).Field("tabScreen").GetValue<Transform>();
			foreach (NetworkObject player in value3.players)
			{
				if (!value.Any((PlayerListItem b) => b.ConnectionID == player.Owner.ClientId))
				{
					GameObject val = Object.Instantiate<GameObject>(__instance.PlayerListItemPrefab);
					PlayerListItem component = val.GetComponent<PlayerListItem>();
					ClientInstance component2 = ((Component)player).GetComponent<ClientInstance>();
					component.PlayerName = component2.PlayerName;
					component.ConnectionID = component2.ConnectionID;
					component.PlayerIdNumber = component2.PlayerId;
					component.PlayerSteamID = component2.PlayerSteamID;
					component.Ready = component2.Ready;
					component.SetPlayerValues();
					val.transform.SetParent(__instance.PlayerListViewContent.transform);
					val.transform.localScale = Vector3.one;
					int num = component2.PlayerId - 1;
					if (num >= 0 && num < __instance.clientPosition.Length)
					{
						val.transform.position = __instance.clientPosition[num].position;
					}
					else
					{
						Vector3 position = __instance.clientPosition[__instance.clientPosition.Length - 1].position;
						val.transform.position = position + Vector3.down * 60f * (float)(num - __instance.clientPosition.Length + 1);
						Debug.LogWarning((object)$"[moreStrafts] Player {component2.PlayerId} exceeds available positions, stacking below");
					}
					value.Add(component);
				}
				if (!value2.Any((PlayerListItem b) => b.ConnectionID == player.Owner.ClientId))
				{
					GameObject val2 = Object.Instantiate<GameObject>(__instance.PlayerListItemPrefab);
					PlayerListItem component3 = val2.GetComponent<PlayerListItem>();
					ClientInstance component4 = ((Component)player).GetComponent<ClientInstance>();
					component3.PlayerName = component4.PlayerName;
					component3.ConnectionID = component4.ConnectionID;
					component3.PlayerIdNumber = component4.PlayerId;
					component3.PlayerSteamID = component4.PlayerSteamID;
					component3.Ready = component4.Ready;
					component3.SetPlayerValues();
					val2.transform.SetParent(value4);
					val2.transform.localScale = Vector3.one;
					Transform[] tabclientPosition = __instance.tabclientPosition;
					int num2 = component4.PlayerId - 1;
					if (num2 >= 0 && num2 < tabclientPosition.Length)
					{
						val2.transform.position = tabclientPosition[num2].position;
					}
					else
					{
						Vector3 position2 = tabclientPosition[^1].position;
						val2.transform.position = position2 + Vector3.down * 60f * (float)(num2 - tabclientPosition.Length + 1);
					}
					value2.Add(component3);
				}
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(PlayerListItem), "Update")]
	public static class PlayerListItemUpdatePatch
	{
		private static bool Prefix(PlayerListItem __instance)
		{
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: 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_01de: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			GameObject value = Traverse.Create((object)__instance).Field("cosmeticbutton").GetValue<GameObject>();
			PauseManager value2 = Traverse.Create((object)__instance).Field("pauseManager").GetValue<PauseManager>();
			LobbyController value3 = Traverse.Create((object)__instance).Field("lobbyController").GetValue<LobbyController>();
			GameManager value4 = Traverse.Create((object)__instance).Field("gameManager").GetValue<GameManager>();
			TMP_Dropdown value5 = Traverse.Create((object)__instance).Field("teamIdDropdown").GetValue<TMP_Dropdown>();
			ulong value6 = Traverse.Create((object)__instance).Field("localSteamId").GetValue<ulong>();
			if ((Object)(object)value != (Object)null && (Object)(object)value2 != (Object)null)
			{
				value.transform.localScale = (value2.inMainMenu ? Vector3.one : Vector3.zero);
			}
			bool flag = ((Object)((Component)((Component)__instance).transform.parent).gameObject).name == "-- TAB SCREEN --";
			if (__instance.PlayerIdNumber > 0 && (Object)(object)value3 != (Object)null)
			{
				int num = __instance.PlayerIdNumber - 1;
				if (flag)
				{
					if (num < value3.tabclientPosition.Length)
					{
						((Component)__instance).transform.position = value3.tabclientPosition[num].position;
					}
					else
					{
						Vector3 position = value3.tabclientPosition[value3.tabclientPosition.Length - 1].position;
						int num2 = num - (value3.tabclientPosition.Length - 1);
						((Component)__instance).transform.position = new Vector3(position.x, position.y - (float)num2 * 0.5f, position.z);
					}
				}
				else if (num < value3.clientPosition.Length)
				{
					((Component)__instance).transform.position = value3.clientPosition[num].position;
				}
				else
				{
					Vector3 position2 = value3.clientPosition[value3.clientPosition.Length - 1].position;
					int num3 = num - (value3.clientPosition.Length - 1);
					((Component)__instance).transform.position = new Vector3(position2.x, position2.y - (float)num3 * 0.5f, position2.z);
				}
			}
			if ((Object)(object)value4 != (Object)null && (Object)(object)value5 != (Object)null)
			{
				bool value7 = Traverse.Create((object)value4).Field("playingTeams").GetValue<bool>();
				((Component)value5).gameObject.SetActive(value7);
				if (InstanceFinder.NetworkManager.IsServer)
				{
					((Selectable)value5).interactable = !flag;
				}
				else if (value6 == __instance.PlayerSteamID)
				{
					((Selectable)value5).interactable = !flag;
				}
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(ClientInstance), "RpcLogic___RunIntoLobby_3316948804")]
	public static class RunIntoLobbyPatch
	{
		private static bool Prefix(ClientInstance __instance, int id)
		{
			AboubiPreviewLobby[] previews = LobbyController.Instance.previews;
			if (id >= 0 && id < previews.Length && (Object)(object)previews[id] != (Object)null)
			{
				return true;
			}
			Debug.Log((object)$"[moreStrafts] Skipping lobby run animation for player {id} - no preview slot available");
			return false;
		}
	}
	[HarmonyPatch(typeof(ClientInstance), "RpcLogic___MenuAnimationObservers_1692629761")]
	public static class MenuAnimationObserversPatch
	{
		private static bool Prefix(ClientInstance __instance, int index, int id)
		{
			AboubiPreviewLobby[] previews = LobbyController.Instance.previews;
			if (id >= 0 && id < previews.Length && (Object)(object)previews[id] != (Object)null)
			{
				return true;
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(ClientInstance), "RpcLogic___DressAboubiObservers_2497120398")]
	public static class DressAboubiObserversPatch
	{
		private static bool Prefix(ClientInstance __instance, GameObject hat, int matIndex, int cigIndex, int id)
		{
			AboubiPreviewLobby[] previews = LobbyController.Instance.previews;
			if (id >= 0 && id < previews.Length)
			{
				return true;
			}
			Debug.Log((object)$"[moreStrafts] Skipping cosmetics for player {id} - no preview slot available");
			return false;
		}
	}
	[HarmonyPatch(typeof(SteamLobby), "SetMaxPlayers")]
	public static class SetMaxPlayersPatch
	{
		private static void Postfix(SteamLobby __instance, TMP_Dropdown _dropdown)
		{
			Debug.Log((object)$"[moreStrafts] Max players set to: {__instance.maxPlayers} (dropdown value: {_dropdown.value})");
			try
			{
				Transport val = InstanceFinder.TransportManager?.Transport;
				if ((Object)(object)val != (Object)null)
				{
					val.SetMaximumClients(__instance.maxPlayers - 1);
					Debug.Log((object)$"[moreStrafts] Updated transport max clients to {__instance.maxPlayers - 1}");
				}
			}
			catch (Exception ex)
			{
				Debug.LogError((object)("[moreStrafts] Failed to update transport max clients: " + ex.Message));
			}
		}
	}
	[HarmonyPatch(typeof(ClientInstance), "RpcLogic___UpdateOnClients_3316948804")]
	public static class UpdateOnClientsPatch
	{
		private static void Prefix(ref int maxPlayers)
		{
			if (maxPlayers < 2)
			{
				maxPlayers = 2;
			}
			if (maxPlayers > 10)
			{
				maxPlayers = 10;
			}
		}
	}
	[HarmonyPatch(typeof(LobbyController), "Update")]
	public static class LobbyControllerUpdatePatch
	{
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			for (int i = 0; i < list.Count; i++)
			{
				if ((list[i].opcode == OpCodes.Ldc_I4_2 || list[i].opcode == OpCodes.Ldc_I4_4) && i + 1 < list.Count && !(list[i + 1].opcode == OpCodes.Bgt) && !(list[i + 1].opcode == OpCodes.Bgt_S) && !(list[i + 1].opcode == OpCodes.Ble) && !(list[i + 1].opcode == OpCodes.Ble_S) && !(list[i + 1].opcode == OpCodes.Blt))
				{
					_ = list[i + 1].opcode == OpCodes.Blt_S;
				}
			}
			return list;
		}
	}
	[HarmonyPatch(typeof(RoundManager), "NextRoundCall")]
	public static class RoundManagerNextRoundCallPatch
	{
		private static bool Prefix(RoundManager __instance, int playerId, bool won, int winningTeamId)
		{
			string[] array = new string[10];
			int[] array2 = new int[10];
			ClientInstance[] array3 = (ClientInstance[])(object)new ClientInstance[SteamLobby.Instance.players.Count];
			if (won)
			{
				Settings.Instance.IncreaseRoundsWon();
			}
			else
			{
				Settings.Instance.IncreaseRoundsLost();
			}
			for (int i = 0; i < array3.Length; i++)
			{
				array3[i] = ((Component)SteamLobby.Instance.players[i]).GetComponent<ClientInstance>();
			}
			for (int j = 0; j < array.Length; j++)
			{
				if (ClientInstance.playerInstances.TryGetValue(j, out var value))
				{
					array[j] = value.PlayerName;
				}
				else
				{
					array[j] = "";
				}
			}
			for (int k = 0; k < array2.Length; k++)
			{
				array2[k] = ScoreManager.Instance.GetPoints(ScoreManager.Instance.GetTeamId(k));
			}
			Traverse.Create((object)__instance).Field("names").SetValue((object)array);
			Traverse.Create((object)__instance).Field("scores").SetValue((object)array2);
			Traverse.Create((object)__instance).Field("players").SetValue((object)array3);
			IEnumerator value2 = Traverse.Create((object)__instance).Method("InterfaceSetup", new object[3] { playerId, won, winningTeamId }).GetValue<IEnumerator>();
			Traverse.Create((object)__instance).Field("InterfaceSetupCoroutine").SetValue((object)value2);
			((MonoBehaviour)__instance).StartCoroutine(value2);
			return false;
		}
	}
	[HarmonyPatch(typeof(PlayerListItem), "Start")]
	public static class ExpandTeamDropdownPatch
	{
		private static void Postfix(PlayerListItem __instance)
		{
			TMP_Dropdown value = Traverse.Create((object)__instance).Field("teamIdDropdown").GetValue<TMP_Dropdown>();
			if ((Object)(object)value == (Object)null)
			{
				return;
			}
			int maxPlayers = SteamLobby.Instance.maxPlayers;
			if (maxPlayers > 4)
			{
				value.ClearOptions();
				List<string> list = new List<string>();
				for (int i = 1; i <= maxPlayers; i++)
				{
					list.Add($"Team {i}");
				}
				value.AddOptions(list);
				int teamId = ScoreManager.Instance.GetTeamId(__instance.PlayerIdNumber);
				value.value = teamId;
				Debug.Log((object)$"[moreStrafts] Expanded team dropdown to {maxPlayers} options for player {__instance.PlayerIdNumber}");
			}
		}
	}
	[HarmonyPatch(typeof(SteamLobby), "SetGamemode", new Type[] { typeof(int) })]
	public static class FFATeamAssignmentPatch
	{
		private static void Postfix(SteamLobby __instance, int value)
		{
			if (value == 0 && InstanceFinder.NetworkManager.IsServer)
			{
				int count = __instance.players.Count;
				ScoreManager.Instance.ResetTeams();
				for (int i = 0; i < count; i++)
				{
					ScoreManager.Instance.SetTeamId(i, i);
				}
				Debug.Log((object)$"[moreStrafts] FFA mode activated - assigned unique team IDs for {count} players");
			}
		}
	}
	[HarmonyPatch(typeof(GameManager), "StartGame")]
	public static class GameStartFFAPatch
	{
		private static void Postfix(GameManager __instance)
		{
			if (!Traverse.Create((object)__instance).Field("playingTeams").GetValue<bool>() && InstanceFinder.NetworkManager.IsServer)
			{
				int count = SteamLobby.Instance.players.Count;
				ScoreManager.Instance.ResetTeams();
				for (int i = 0; i < count; i++)
				{
					ScoreManager.Instance.SetTeamId(i, i);
				}
				Debug.Log((object)$"[moreStrafts] Game starting in FFA mode - assigned unique team IDs for {count} players");
			}
		}
	}
	[HarmonyPatch(typeof(MatchPoitnsHUD), "UpdateVisuals", new Type[]
	{
		typeof(int),
		typeof(Dictionary<int, int>)
	})]
	public static class MatchPoitnsHUDMainUpdateVisualsPatch
	{
		private static bool Prefix(MatchPoitnsHUD __instance, int winnerTeamId, Dictionary<int, int> roundScores)
		{
			MeshRenderer[] value = Traverse.Create((object)__instance).Field("secondaryPointObjects").GetValue<MeshRenderer[]>();
			TMP_Text[] value2 = Traverse.Create((object)__instance).Field("pointsTexts").GetValue<TMP_Text[]>();
			MeshRenderer value3 = Traverse.Create((object)__instance).Field("primaryPointMesh").GetValue<MeshRenderer>();
			if (ClientInstance.playerInstances.Count <= 1)
			{
				return false;
			}
			List<int> list = new List<int>();
			foreach (int key in ScoreManager.Instance.TeamIdToPlayerIds.Keys)
			{
				foreach (int item in ((SyncIDictionary<int, List<int>>)(object)ScoreManager.Instance.TeamIdToPlayerIds)[key])
				{
					if (ClientInstance.playerInstances.ContainsKey(item))
					{
						list.Add(key);
						break;
					}
				}
			}
			int num = Mathf.Min(list.Count - 2, value.Length);
			for (int i = 0; i < num; i++)
			{
				((Component)value[i]).gameObject.SetActive(true);
			}
			int num2 = value.Length - num;
			if (num2 > 0)
			{
				for (int num3 = value.Length - 1; num3 >= value.Length - num2; num3--)
				{
					if (num3 >= 0)
					{
						((Component)value[num3]).gameObject.SetActive(false);
					}
				}
			}
			TMP_Text[] array = value2;
			for (int j = 0; j < array.Length; j++)
			{
				array[j].text = "";
			}
			Material[] materials = ((Renderer)value3).materials;
			int num4 = Mathf.Min(list.Count, 4);
			for (int k = 0; k < num4; k++)
			{
				int num5 = ScoreManager.Instance.TeamIdToPlayerIds.Keys.ElementAt(k);
				int roundScore = (roundScores.ContainsKey(num5) ? roundScores[num5] : 0);
				UpdateVisualsSafe(__instance, k, roundScore, num5 == winnerTeamId, materials);
			}
			((Renderer)value3).materials = materials;
			return false;
		}

		private static void UpdateVisualsSafe(MatchPoitnsHUD instance, int teamNumber, int roundScore, bool isWinner, Material[] primaryPointMeshMaterials)
		{
			Material[] value = Traverse.Create((object)instance).Field("activeMaterials").GetValue<Material[]>();
			Material value2 = Traverse.Create((object)instance).Field("inactiveMaterial").GetValue<Material>();
			MeshRenderer[] value3 = Traverse.Create((object)instance).Field("secondaryPointObjects").GetValue<MeshRenderer[]>();
			TMP_Text[] value4 = Traverse.Create((object)instance).Field("pointsTexts").GetValue<TMP_Text[]>();
			if (teamNumber < 0 || teamNumber >= value.Length)
			{
				return;
			}
			Material val = ((roundScore > 0) ? value[teamNumber] : value2);
			if (teamNumber < 2)
			{
				int num = ((teamNumber == 0) ? 1 : 3);
				primaryPointMeshMaterials[num] = val;
			}
			else
			{
				int num2 = teamNumber - 2;
				if (num2 < value3.Length)
				{
					Material[] materials = ((Renderer)value3[num2]).materials;
					materials[1] = val;
					((Renderer)value3[num2]).materials = materials;
				}
			}
			if (((roundScore == 2 && !isWinner) || roundScore > 2) && teamNumber < value4.Length)
			{
				value4[teamNumber].text = roundScore.ToString();
			}
			if (isWinner)
			{
				primaryPointMeshMaterials[2] = val;
			}
		}
	}
}