Decompiled source of Team Mode v0.3.2
Team_Mode.dll
Decompiled 6 days ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using Mirror; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.Localization; using UnityEngine.Localization.Components; using UnityEngine.Localization.Settings; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: IgnoresAccessChecksTo("GameAssembly")] [assembly: IgnoresAccessChecksTo("SharedAssembly")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("Team_Mode")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.3.2.0")] [assembly: AssemblyInformationalVersion("0.3.2")] [assembly: AssemblyProduct("Team_Mode")] [assembly: AssemblyTitle("Team_Mode")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.3.2.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace System.Runtime.CompilerServices { [CompilerGenerated] [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] [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] [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")] [Embedded] 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")] [Embedded] internal sealed class PatcherAutoPluginAttribute : Attribute { public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null) { } } } namespace Microsoft.CodeAnalysis { [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace Team_Mode { [BepInPlugin("Team_Mode", "Team_Mode", "0.3.2")] public class Plugin : BaseUnityPlugin { public static bool EnabledSetting = false; public static bool FriendlyFireEnabled = false; public static bool RoundsMode = false; public static bool EarlyHoleEnd = false; public static int TeamCount = 2; public static Dictionary<ulong, int> PlayerTeams = new Dictionary<ulong, int>(); public static readonly Color[] TeamColors = (Color[])(object)new Color[4] { new Color(0.9f, 0.2f, 0.2f), new Color(0.2f, 0.4f, 0.9f), new Color(0.2f, 0.8f, 0.2f), new Color(0.9f, 0.8f, 0.1f) }; public const string Id = "Team_Mode"; internal static ManualLogSource Log { get; private set; } = null; public static bool Enabled { get { if (EnabledSetting) { return !NativeTeamsMode; } return false; } set { EnabledSetting = value; } } public static bool NativeTeamsMode { get { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Invalid comparison between Unknown and I4 try { return (int)MatchSetupMenu.CurrentGameMode == 1; } catch { return false; } } } public static string[] TeamNames => new string[4] { Lang.Get("Rouge", "Red"), Lang.Get("Bleu", "Blue"), Lang.Get("Vert", "Green"), Lang.Get("Jaune", "Yellow") }; public static string Name => "Team_Mode"; public static string Version => "0.3.2"; public static int GetTeam(ulong guid) { if (!PlayerTeams.TryGetValue(guid, out var value)) { return 0; } return value; } public static bool SameTeam(ulong a, ulong b) { if (Enabled && TeamCount > 1) { return GetTeam(a) == GetTeam(b); } return false; } private void Awake() { //IL_0021: Unknown result type (might be due to invalid IL or missing references) Log = ((BaseUnityPlugin)this).Logger; TeamSerialization.Register(); ((Component)this).gameObject.AddComponent<TeamModeRuntime>(); new Harmony("Team_Mode").PatchAll(); PlayerId.AnyPlayerNameChanged += delegate { TeamModeUi.RebuildPlayerDropdowns(); }; Log.LogInfo((object)("Plugin " + Name + " loaded!")); } } public struct TeamAssignmentMessage : NetworkMessage { public ulong playerGuid; public int teamIndex; } public struct TeamStateSyncMessage : NetworkMessage { public ulong[] guids; public int[] teams; public int teamCount; public bool enabled; public bool friendlyFireEnabled; public bool roundsMode; } public struct TeamScoreSyncMessage : NetworkMessage { public ulong[] guids; public int[] totals; } [StructLayout(LayoutKind.Sequential, Size = 1)] public struct TeamStateRequestMessage : NetworkMessage { } public static class TeamSerialization { private const int MaxEntries = 1024; public static void Register() { Writer<TeamAssignmentMessage>.write = delegate(NetworkWriter w, TeamAssignmentMessage m) { NetworkWriterExtensions.WriteULong(w, m.playerGuid); NetworkWriterExtensions.WriteInt(w, m.teamIndex); }; Reader<TeamAssignmentMessage>.read = (NetworkReader r) => new TeamAssignmentMessage { playerGuid = NetworkReaderExtensions.ReadULong(r), teamIndex = NetworkReaderExtensions.ReadInt(r) }; Writer<TeamStateSyncMessage>.write = delegate(NetworkWriter w, TeamStateSyncMessage m) { WriteEntries(w, m.guids, m.teams); NetworkWriterExtensions.WriteInt(w, m.teamCount); NetworkWriterExtensions.WriteBool(w, m.enabled); NetworkWriterExtensions.WriteBool(w, m.friendlyFireEnabled); NetworkWriterExtensions.WriteBool(w, m.roundsMode); }; Reader<TeamStateSyncMessage>.read = delegate(NetworkReader r) { var (guids, teams) = ReadEntries(r); return new TeamStateSyncMessage { guids = guids, teams = teams, teamCount = NetworkReaderExtensions.ReadInt(r), enabled = NetworkReaderExtensions.ReadBool(r), friendlyFireEnabled = NetworkReaderExtensions.ReadBool(r), roundsMode = (r.Remaining > 0 && NetworkReaderExtensions.ReadBool(r)) }; }; Writer<TeamScoreSyncMessage>.write = delegate(NetworkWriter w, TeamScoreSyncMessage m) { WriteEntries(w, m.guids, m.totals); }; Reader<TeamScoreSyncMessage>.read = delegate(NetworkReader r) { var (guids, totals) = ReadEntries(r); return new TeamScoreSyncMessage { guids = guids, totals = totals }; }; Writer<TeamStateRequestMessage>.write = delegate { }; Reader<TeamStateRequestMessage>.read = (NetworkReader r) => default(TeamStateRequestMessage); } private static void WriteEntries(NetworkWriter w, ulong[]? keys, int[]? values) { int num = Math.Min((keys != null) ? keys.Length : 0, (values != null) ? values.Length : 0); NetworkWriterExtensions.WriteInt(w, num); for (int i = 0; i < num; i++) { NetworkWriterExtensions.WriteULong(w, keys[i]); NetworkWriterExtensions.WriteInt(w, values[i]); } } private static (ulong[] keys, int[] values) ReadEntries(NetworkReader r) { int num = NetworkReaderExtensions.ReadInt(r); if (num < 0 || num > 1024) { throw new InvalidOperationException($"Team_Mode: invalid entry count {num}"); } ulong[] array = new ulong[num]; int[] array2 = new int[num]; for (int i = 0; i < num; i++) { array[i] = NetworkReaderExtensions.ReadULong(r); array2[i] = NetworkReaderExtensions.ReadInt(r); } return (keys: array, values: array2); } } public static class TeamSyncManager { private static bool _serverEventHooked; private static bool _isRemoteClient; public static void OnServerStarted() { NetworkServer.RegisterHandler<TeamStateRequestMessage>((Action<NetworkConnectionToClient, TeamStateRequestMessage>)OnServerReceiveStateRequest, true); if (!_serverEventHooked) { _serverEventHooked = true; GameManager.RemotePlayerRegistered += OnRemotePlayerRegistered; } Plugin.Log.LogInfo((object)"[Sync/Host] Server started — handlers registered"); } public static void OnClientStarted() { _isRemoteClient = !NetworkServer.active; NetworkClient.RegisterHandler<TeamAssignmentMessage>((Action<TeamAssignmentMessage>)OnClientReceiveAssignment, true); NetworkClient.RegisterHandler<TeamStateSyncMessage>((Action<TeamStateSyncMessage>)OnClientReceiveStateSync, true); NetworkClient.RegisterHandler<TeamScoreSyncMessage>((Action<TeamScoreSyncMessage>)OnClientReceiveScoreSync, true); Plugin.Log.LogInfo((object)$"[Sync] Client started (remote={_isRemoteClient}) — handlers registered"); } public static void OnClientStopped() { if (_isRemoteClient) { _isRemoteClient = false; Plugin.Enabled = false; Plugin.FriendlyFireEnabled = false; Plugin.TeamCount = 2; Plugin.RoundsMode = false; Plugin.PlayerTeams.Clear(); ScoreboardTeamData.TeamRounds.Clear(); RoundsTracker.NewHole(); Plugin.Log.LogInfo((object)"[Sync/Client] Disconnected from host — team state reset"); } } public static void RequestState() { if (!NetworkServer.active && NetworkClient.isConnected) { NetworkClient.Send<TeamStateRequestMessage>(default(TeamStateRequestMessage), 0); Plugin.Log.LogInfo((object)"[Sync/Client] Requested full state from host"); } } private static void OnRemotePlayerRegistered(PlayerInfo playerInfo) { if (!NetworkServer.active) { return; } try { NetworkConnectionToClient connectionToClient = ((NetworkBehaviour)playerInfo).connectionToClient; if (connectionToClient == null) { Plugin.Log.LogWarning((object)"[Sync/Host] New player registered but connectionToClient is null — cannot send state"); return; } ManualLogSource log = Plugin.Log; PlayerId playerId = playerInfo.PlayerId; log.LogInfo((object)$"[Sync/Host] New remote player registered: guid={((playerId != null) ? new ulong?(playerId.Guid) : ((ulong?)null))} — sending full state..."); SendFullStateTo(connectionToClient); } catch (Exception ex) { Plugin.Log.LogError((object)("[Sync] OnRemotePlayerRegistered: " + ex.Message)); } } private static void OnServerReceiveStateRequest(NetworkConnectionToClient conn, TeamStateRequestMessage msg) { Plugin.Log.LogInfo((object)$"[Sync/Host] State requested by connId={conn.connectionId}"); SendFullStateTo(conn); } public static void SendFullStateTo(NetworkConnectionToClient conn) { if (!NetworkServer.active) { return; } try { ulong[] array = new ulong[Plugin.PlayerTeams.Count]; int[] array2 = new int[Plugin.PlayerTeams.Count]; int num = 0; foreach (KeyValuePair<ulong, int> playerTeam in Plugin.PlayerTeams) { array[num] = playerTeam.Key; array2[num] = playerTeam.Value; num++; } TeamStateSyncMessage teamStateSyncMessage = new TeamStateSyncMessage { guids = array, teams = array2, teamCount = Plugin.TeamCount, enabled = Plugin.EnabledSetting, friendlyFireEnabled = Plugin.FriendlyFireEnabled, roundsMode = Plugin.RoundsMode }; ((NetworkConnection)conn).Send<TeamStateSyncMessage>(teamStateSyncMessage, 0); ((NetworkConnection)conn).Send<TeamScoreSyncMessage>(BuildScoreMessage(), 0); Plugin.Log.LogInfo((object)$"[Sync/Host] Full state sent → connId={conn.connectionId} | {array.Length} assignments | TeamCount={Plugin.TeamCount} | Enabled={Plugin.EnabledSetting} | FF={Plugin.FriendlyFireEnabled} | Rounds={Plugin.RoundsMode}"); for (int i = 0; i < array.Length; i++) { Plugin.Log.LogInfo((object)$"[Sync/Host] guid={array[i]} → team={Plugin.TeamNames[array2[i]]}"); } } catch (Exception ex) { Plugin.Log.LogError((object)("[Sync] SendFullStateTo: " + ex.Message)); } } private static TeamScoreSyncMessage BuildScoreMessage() { Dictionary<int, int> teamRounds = ScoreboardTeamData.TeamRounds; ulong[] array = new ulong[teamRounds.Count]; int[] array2 = new int[teamRounds.Count]; int num = 0; foreach (KeyValuePair<int, int> item in teamRounds) { array[num] = (ulong)item.Key; array2[num] = item.Value; num++; } return new TeamScoreSyncMessage { guids = array, totals = array2 }; } public static void BroadcastAssignment(ulong guid, int team) { if (NetworkServer.active) { TeamAssignmentMessage teamAssignmentMessage = new TeamAssignmentMessage { playerGuid = guid, teamIndex = team }; NetworkServer.SendToAll<TeamAssignmentMessage>(teamAssignmentMessage, 0, false); Plugin.Log.LogInfo((object)$"[Sync/Host] Broadcast assignment → guid={guid} team={Plugin.TeamNames[team]}"); } } public static void BroadcastScores() { if (NetworkServer.active) { NetworkServer.SendToAll<TeamScoreSyncMessage>(BuildScoreMessage(), 0, false); } } public static void BroadcastFullState() { if (!NetworkServer.active) { return; } foreach (NetworkConnectionToClient value in NetworkServer.connections.Values) { if ((object)value != NetworkServer.localConnection) { SendFullStateTo(value); } } Plugin.Log.LogInfo((object)"[Sync/Host] Full state broadcast to all clients"); } private static void OnClientReceiveAssignment(TeamAssignmentMessage msg) { if (!NetworkServer.active) { int num = Mathf.Clamp(msg.teamIndex, 0, Plugin.TeamColors.Length - 1); Plugin.PlayerTeams[msg.playerGuid] = num; Plugin.Log.LogInfo((object)$"[Sync/Client] ✅ Received assignment → guid={msg.playerGuid} team={Plugin.TeamNames[num]}"); RefreshVisualsForGuid(msg.playerGuid); RefreshScoreboards(); } } private static void OnClientReceiveStateSync(TeamStateSyncMessage msg) { if (NetworkServer.active) { return; } ManualLogSource log = Plugin.Log; object[] array = new object[4]; ulong[] guids = msg.guids; array[0] = ((guids != null) ? guids.Length : 0); array[1] = msg.teamCount; array[2] = msg.enabled; array[3] = msg.friendlyFireEnabled; log.LogInfo((object)string.Format("[Sync/Client] ✅ Received full state from host — {0} assignments | TeamCount={1} | Enabled={2} | FF={3}", array)); Plugin.PlayerTeams.Clear(); if (msg.guids != null && msg.teams != null) { for (int i = 0; i < msg.guids.Length && i < msg.teams.Length; i++) { int num = Mathf.Clamp(msg.teams[i], 0, Plugin.TeamColors.Length - 1); Plugin.PlayerTeams[msg.guids[i]] = num; Plugin.Log.LogInfo((object)$"[Sync/Client] guid={msg.guids[i]} → team={Plugin.TeamNames[num]}"); } } Plugin.TeamCount = Mathf.Clamp(msg.teamCount, 1, Plugin.TeamColors.Length); Plugin.Enabled = msg.enabled; Plugin.FriendlyFireEnabled = msg.friendlyFireEnabled; Plugin.RoundsMode = msg.roundsMode; Plugin.Log.LogInfo((object)"[Sync/Client] State applied — refreshing visuals for all players..."); RefreshAllVisuals(); RefreshScoreboards(); TeamModeUi.RebuildPlayerDropdowns(); EnhancedMode.Refresh(); } private static void OnClientReceiveScoreSync(TeamScoreSyncMessage msg) { if (NetworkServer.active) { return; } ScoreboardTeamData.TeamRounds.Clear(); if (msg.guids != null && msg.totals != null) { for (int i = 0; i < msg.guids.Length && i < msg.totals.Length; i++) { if (msg.guids[i] < (ulong)Plugin.TeamColors.Length) { ScoreboardTeamData.TeamRounds[(int)msg.guids[i]] = msg.totals[i]; } } } Plugin.Log.LogInfo((object)$"[Sync/Client] ✅ Received team rounds from host — {ScoreboardTeamData.TeamRounds.Count} entries"); RefreshScoreboards(); } private static void RefreshVisualsForGuid(ulong guid) { try { PlayerInfo val = null; GameManager.TryFindPlayerByGuid(guid, ref val); if (!((Object)(object)val == (Object)null)) { PlayerCosmeticsSwitcher componentInChildren = ((Component)val).GetComponentInChildren<PlayerCosmeticsSwitcher>(); if (!((Object)(object)componentInChildren == (Object)null)) { componentInChildren.SetSkinColor(componentInChildren.CurrentSkinColorIndex); Plugin.Log.LogInfo((object)$"[Sync/Client] Refreshed visuals for guid={guid}"); } } } catch (Exception ex) { Plugin.Log.LogError((object)("[Sync] RefreshVisualsForGuid: " + ex.Message)); } } public static void RefreshAllVisuals() { try { PlayerCosmeticsSwitcher[] array = Object.FindObjectsByType<PlayerCosmeticsSwitcher>((FindObjectsSortMode)0); PlayerCosmeticsSwitcher[] array2 = array; foreach (PlayerCosmeticsSwitcher val in array2) { val.SetSkinColor(val.CurrentSkinColorIndex); } Plugin.Log.LogInfo((object)$"[Sync] Refreshed visuals for {array.Length} player(s)"); } catch (Exception ex) { Plugin.Log.LogError((object)("[Sync] RefreshAllVisuals: " + ex.Message)); } } private static void RefreshScoreboards() { try { MethodInfo methodInfo = AccessTools.Method(typeof(Scoreboard), "MarkDirty", (Type[])null, (Type[])null); if (!(methodInfo == null)) { Scoreboard[] array = Object.FindObjectsByType<Scoreboard>((FindObjectsSortMode)0); foreach (Scoreboard obj in array) { methodInfo.Invoke(obj, null); } } } catch (Exception ex) { Plugin.Log.LogError((object)("[Sync] RefreshScoreboards: " + ex.Message)); } } } public static class HittableHelper { private static readonly BindingFlags Pub = BindingFlags.Instance | BindingFlags.Public; public static ulong GetTargetGuid(object hittable) { try { object obj = hittable.GetType().GetProperty("AsEntity", Pub)?.GetValue(hittable); if (obj == null) { return 0uL; } if (!(bool)(obj.GetType().GetProperty("IsPlayer", Pub)?.GetValue(obj) ?? ((object)false))) { return 0uL; } object obj2 = obj.GetType().GetProperty("PlayerInfo", Pub)?.GetValue(obj); if (obj2 == null) { return 0uL; } return GetGuidFromPlayerInfo(obj2); } catch { return 0uL; } } public static ulong GetGuidFromPlayerInfo(object playerInfo) { try { object obj = playerInfo.GetType().GetProperty("PlayerId", Pub)?.GetValue(playerInfo); if (obj == null) { return 0uL; } return (ulong)(obj.GetType().GetProperty("Guid", Pub)?.GetValue(obj) ?? ((object)0uL)); } catch { return 0uL; } } public static ulong GetGuidViaPlayerInfoProp(object obj) { try { object obj2 = obj.GetType().GetProperty("PlayerInfo", Pub)?.GetValue(obj); if (obj2 == null) { return 0uL; } return GetGuidFromPlayerInfo(obj2); } catch { return 0uL; } } public static bool CheckAndBlockFriendlyFire(ulong targetGuid, ulong shooterGuid, string source) { if (targetGuid == 0L || shooterGuid == 0L) { return false; } if (targetGuid == shooterGuid) { return false; } int team = Plugin.GetTeam(targetGuid); int team2 = Plugin.GetTeam(shooterGuid); bool flag = Plugin.SameTeam(shooterGuid, targetGuid); string text = (flag ? "TEAMMATE" : "ENEMY"); Plugin.Log.LogInfo((object)$"[FF/{source}] Shooter={shooterGuid}(Team {team2}) → Target={targetGuid}(Team {team}) | Relation={text} | FriendlyFire={Plugin.FriendlyFireEnabled}"); if (!Plugin.FriendlyFireEnabled && flag) { Plugin.Log.LogInfo((object)("[FF/" + source + "] \ud83d\udee1\ufe0f BLOCKED — friendly fire is OFF and target is teammate")); return true; } if (flag) { Plugin.Log.LogInfo((object)("[FF/" + source + "] ✅ ALLOWED — friendly fire is ON")); } else { Plugin.Log.LogInfo((object)("[FF/" + source + "] ✅ ALLOWED — target is enemy")); } return false; } } [HarmonyPatch] public class HittableHitWithItemPatch { [HarmonyTargetMethod] private static MethodBase TargetMethod() { return AccessTools.Method(AccessTools.TypeByName("Hittable"), "HitWithItem", (Type[])null, (Type[])null); } [HarmonyPrefix] private static bool Prefix(object __instance, object itemUser) { if (!Plugin.Enabled) { return true; } try { ulong targetGuid = HittableHelper.GetTargetGuid(__instance); if (targetGuid == 0L) { return true; } if (itemUser == null) { return true; } ulong guidViaPlayerInfoProp = HittableHelper.GetGuidViaPlayerInfoProp(itemUser); return !HittableHelper.CheckAndBlockFriendlyFire(targetGuid, guidViaPlayerInfoProp, "Item"); } catch (Exception ex) { Plugin.Log.LogError((object)("HitWithItemPatch: " + ex.Message)); } return true; } } [HarmonyPatch] public class HittableGolfSwingPatch { [HarmonyTargetMethod] private static MethodBase TargetMethod() { return AccessTools.Method(AccessTools.TypeByName("Hittable"), "HitWithGolfSwing", (Type[])null, (Type[])null); } [HarmonyPrefix] private static bool Prefix(object __instance, object hitter) { if (!Plugin.Enabled) { return true; } try { ulong targetGuid = HittableHelper.GetTargetGuid(__instance); if (targetGuid == 0L) { return true; } if (hitter == null) { return true; } ulong guidViaPlayerInfoProp = HittableHelper.GetGuidViaPlayerInfoProp(hitter); return !HittableHelper.CheckAndBlockFriendlyFire(targetGuid, guidViaPlayerInfoProp, "GolfSwing"); } catch (Exception ex) { Plugin.Log.LogError((object)("HittableGolfSwingPatch: " + ex.Message)); } return true; } } [HarmonyPatch] public class HittableSwingProjectilePatch { [HarmonyTargetMethod] private static MethodBase TargetMethod() { return AccessTools.Method(AccessTools.TypeByName("Hittable"), "HitWithSwingProjectile", (Type[])null, (Type[])null); } [HarmonyPrefix] private static bool Prefix(object __instance, object responsiblePlayer) { if (!Plugin.Enabled) { return true; } try { ulong targetGuid = HittableHelper.GetTargetGuid(__instance); if (targetGuid == 0L) { return true; } if (responsiblePlayer == null) { return true; } ulong guidViaPlayerInfoProp = HittableHelper.GetGuidViaPlayerInfoProp(responsiblePlayer); return !HittableHelper.CheckAndBlockFriendlyFire(targetGuid, guidViaPlayerInfoProp, "SwingProjectile"); } catch (Exception ex) { Plugin.Log.LogError((object)("HittableSwingProjectilePatch: " + ex.Message)); } return true; } } [HarmonyPatch] public class HittableDivePatch { [HarmonyTargetMethod] private static MethodBase TargetMethod() { return AccessTools.Method(AccessTools.TypeByName("Hittable"), "HitWithDive", (Type[])null, (Type[])null); } [HarmonyPrefix] private static bool Prefix(object __instance, object hitter) { if (!Plugin.Enabled) { return true; } try { ulong targetGuid = HittableHelper.GetTargetGuid(__instance); if (targetGuid == 0L) { return true; } if (hitter == null) { return true; } ulong guidViaPlayerInfoProp = HittableHelper.GetGuidViaPlayerInfoProp(hitter); return !HittableHelper.CheckAndBlockFriendlyFire(targetGuid, guidViaPlayerInfoProp, "Dive"); } catch (Exception ex) { Plugin.Log.LogError((object)("HittableDivePatch: " + ex.Message)); } return true; } } [HarmonyPatch] public class HittableRocketBackBlastPatch { [HarmonyTargetMethod] private static MethodBase TargetMethod() { return AccessTools.Method(AccessTools.TypeByName("Hittable"), "HitWithRocketLauncherBackBlast", (Type[])null, (Type[])null); } [HarmonyPrefix] private static bool Prefix(object __instance, object rocketLauncherUser) { if (!Plugin.Enabled) { return true; } try { ulong targetGuid = HittableHelper.GetTargetGuid(__instance); if (targetGuid == 0L) { return true; } if (rocketLauncherUser == null) { return true; } ulong guidViaPlayerInfoProp = HittableHelper.GetGuidViaPlayerInfoProp(rocketLauncherUser); return !HittableHelper.CheckAndBlockFriendlyFire(targetGuid, guidViaPlayerInfoProp, "RocketBackBlast"); } catch (Exception ex) { Plugin.Log.LogError((object)("HittableRocketBackBlastPatch: " + ex.Message)); } return true; } } [HarmonyPatch] public class TeamScorePatch { [HarmonyTargetMethod] private static MethodBase TargetMethod() { return AccessTools.Method(AccessTools.TypeByName("CourseManager"), "InformPlayerScoredInternal", (Type[])null, (Type[])null); } [HarmonyPostfix] [HarmonyPriority(0)] private static void Postfix(object playerAsGolfer) { if (!Plugin.Enabled || !Plugin.RoundsMode || Plugin.TeamCount <= 1) { return; } try { if (NetworkServer.active && !SingletonBehaviour<DrivingRangeManager>.HasInstance) { ulong guidViaPlayerInfoProp = HittableHelper.GetGuidViaPlayerInfoProp(playerAsGolfer); if (guidViaPlayerInfoProp != 0L) { RoundsTracker.CountFinisher(Plugin.GetTeam(guidViaPlayerInfoProp)); } } } catch (Exception ex) { Plugin.Log.LogError((object)("TeamScorePatch: " + ex.Message)); } } } [HarmonyPatch] public class RoundsHoleEndPatch { [HarmonyTargetMethod] private static MethodBase TargetMethod() { return AccessTools.Method(AccessTools.TypeByName("CourseManager"), "OnMatchStateChanged", (Type[])null, (Type[])null); } [HarmonyPostfix] private static void Postfix(MatchState currentState) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Invalid comparison between Unknown and I4 if (!Plugin.Enabled || !Plugin.RoundsMode || Plugin.TeamCount <= 1) { return; } try { if (NetworkServer.active && !SingletonBehaviour<DrivingRangeManager>.HasInstance && (int)currentState == 6) { RoundsTracker.AwardRound(); } } catch (Exception ex) { Plugin.Log.LogError((object)("RoundsHoleEndPatch: " + ex.Message)); } } } public class PracticeScoreSnapshot { public int Index; public ulong Guid; public int CourseScore; public int MatchScore; } [HarmonyPatch] public class PracticeNoScorePatch { [HarmonyTargetMethod] private static MethodBase TargetMethod() { return AccessTools.Method(AccessTools.TypeByName("CourseManager"), "InformPlayerScoredInternal", (Type[])null, (Type[])null); } [HarmonyPrefix] [HarmonyPriority(800)] private static bool Prefix(object playerAsGolfer, out PracticeScoreSnapshot? __state) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) __state = null; if (!Plugin.Enabled || !NetworkServer.active || !TeamStandings.InPractice) { return true; } try { ulong guidViaPlayerInfoProp = HittableHelper.GetGuidViaPlayerInfoProp(playerAsGolfer); SyncList<PlayerState> playerStates = CourseManager.PlayerStates; if (playerStates != null) { for (int i = 0; i < playerStates.Count; i++) { if (playerStates[i].playerGuid == guidViaPlayerInfoProp) { __state = new PracticeScoreSnapshot { Index = i, Guid = guidViaPlayerInfoProp, CourseScore = playerStates[i].courseScore, MatchScore = playerStates[i].matchScore }; break; } } } Plugin.Log.LogInfo((object)$"\ud83c\udfaf Practice goal not counted (Team Mode active, player {guidViaPlayerInfoProp})"); } catch (Exception ex) { Plugin.Log.LogError((object)("PracticeNoScorePatch: " + ex.Message)); } return false; } [HarmonyPostfix] [HarmonyPriority(0)] private static void Postfix(PracticeScoreSnapshot? __state) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) if (__state == null) { return; } try { SyncList<PlayerState> playerStates = CourseManager.PlayerStates; if (playerStates != null && __state.Index < playerStates.Count) { PlayerState val = playerStates[__state.Index]; if (val.playerGuid == __state.Guid && (val.courseScore != __state.CourseScore || val.matchScore != __state.MatchScore)) { val.courseScore = __state.CourseScore; val.matchScore = __state.MatchScore; playerStates[__state.Index] = val; } } } catch (Exception ex) { Plugin.Log.LogError((object)("PracticeNoScorePatch.Postfix: " + ex.Message)); } } } [HarmonyPatch] public class NameTagColorPatch { [HarmonyTargetMethod] private static MethodBase TargetMethod() { return AccessTools.Method(AccessTools.TypeByName("NameTagUi"), "LateUpdate", (Type[])null, (Type[])null) ?? AccessTools.Method(AccessTools.TypeByName("NameTagUi"), "Update", (Type[])null, (Type[])null); } [HarmonyPostfix] private static void Postfix(object __instance) { //IL_00c4: Unknown result type (might be due to invalid IL or missing references) if (!Plugin.Enabled) { return; } try { BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; object obj = __instance.GetType().GetField("playerInfo", bindingAttr)?.GetValue(__instance); if (obj == null) { return; } object obj2 = obj.GetType().GetProperty("PlayerId", BindingFlags.Instance | BindingFlags.Public)?.GetValue(obj); if (obj2 != null) { ulong guid = (ulong)(obj2.GetType().GetProperty("Guid", BindingFlags.Instance | BindingFlags.Public)?.GetValue(obj2) ?? ((object)0uL)); object? obj3 = __instance.GetType().GetField("tag", bindingAttr)?.GetValue(__instance); TMP_Text val = (TMP_Text)((obj3 is TMP_Text) ? obj3 : null); if ((Object)(object)val != (Object)null) { ((Graphic)val).color = Plugin.TeamColors[Plugin.GetTeam(guid)]; } } } catch { } } } [HarmonyPatch] public class PlayerSkinColorPatch { [HarmonyTargetMethod] private static MethodBase TargetMethod() { return AccessTools.Method(AccessTools.TypeByName("PlayerCosmeticsSwitcher"), "ApplyCurrentSkinColorToMaterial", (Type[])null, (Type[])null); } [HarmonyPostfix] private static void Postfix(object __instance, Material material) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) if (!Plugin.Enabled) { return; } try { BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; object obj = __instance.GetType().GetField("playerInfo", bindingAttr)?.GetValue(__instance); if (obj != null) { ulong guidFromPlayerInfo = HittableHelper.GetGuidFromPlayerInfo(obj); material.SetColor("_Color", Plugin.TeamColors[Plugin.GetTeam(guidFromPlayerInfo)]); } } catch (Exception ex) { Plugin.Log.LogError((object)("SkinColorPatch: " + ex.Message)); } } } [HarmonyPatch] public class RegisterPlayerPatch { [HarmonyTargetMethod] private static MethodBase TargetMethod() { return AccessTools.Method(AccessTools.TypeByName("GameManager"), "RegisterPlayer", (Type[])null, (Type[])null); } [HarmonyPostfix] private static void Postfix(PlayerInfo playerInfo) { TeamModeUi.RebuildPlayerDropdowns(); if ((Object)(object)playerInfo != (Object)null && ((NetworkBehaviour)playerInfo).isLocalPlayer) { TeamSyncManager.RequestState(); } } } [HarmonyPatch] public class NetworkStartServerPatch { [HarmonyTargetMethod] private static MethodBase TargetMethod() { return AccessTools.Method(AccessTools.TypeByName("BNetworkManager"), "OnStartServer", (Type[])null, (Type[])null); } [HarmonyPostfix] private static void Postfix() { TeamSyncManager.OnServerStarted(); } } [HarmonyPatch] public class NetworkStartClientPatch { [HarmonyTargetMethod] private static MethodBase TargetMethod() { return AccessTools.Method(AccessTools.TypeByName("BNetworkManager"), "OnStartClient", (Type[])null, (Type[])null); } [HarmonyPostfix] private static void Postfix() { TeamSyncManager.OnClientStarted(); } } [HarmonyPatch] public class NetworkStopClientPatch { [HarmonyTargetMethod] private static MethodBase TargetMethod() { return AccessTools.Method(AccessTools.TypeByName("BNetworkManager"), "OnStopClient", (Type[])null, (Type[])null); } [HarmonyPostfix] private static void Postfix() { TeamSyncManager.OnClientStopped(); } } public static class ScoreboardTeamData { public static Dictionary<GameObject, ulong> EntryGuids = new Dictionary<GameObject, ulong>(); public static Dictionary<GameObject, int> EntryScores = new Dictionary<GameObject, int>(); public static Dictionary<int, int> TeamRounds = new Dictionary<int, int>(); public static Dictionary<int, int> HoleFinishers = new Dictionary<int, int>(); public static bool HoleAwarded; } public static class RoundsTracker { public static int Cap() { Dictionary<int, int> dictionary = new Dictionary<int, int>(); foreach (var connectedPlayer in TeamModeUi.GetConnectedPlayers()) { ulong item = connectedPlayer.guid; int team = Plugin.GetTeam(item); dictionary[team] = ((!dictionary.TryGetValue(team, out var value)) ? 1 : (value + 1)); } int num = 0; foreach (int value2 in dictionary.Values) { if (num == 0 || value2 < num) { num = value2; } } if (num <= 1) { return 1; } int num2 = (num + 1) / 2; if (num % 2 == 0) { num2++; } return num2; } private static int Counted(int team, int cap) { int value; return Math.Min(ScoreboardTeamData.HoleFinishers.TryGetValue(team, out value) ? value : 0, cap); } public static void NewHole() { ScoreboardTeamData.HoleFinishers.Clear(); ScoreboardTeamData.HoleAwarded = false; } public static void CountFinisher(int team) { Dictionary<int, int> holeFinishers = ScoreboardTeamData.HoleFinishers; holeFinishers[team] = (holeFinishers.TryGetValue(team, out var value) ? value : 0) + 1; int num = Cap(); Plugin.Log.LogInfo((object)$"\ud83c\udfc1 Team {Plugin.TeamNames[team]}: {holeFinishers[team]} finisher(s) this hole (cap {num})"); if (Plugin.EarlyHoleEnd && Counted(team, num) >= num) { EndHoleNow(); } } private static void EndHoleNow() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Invalid comparison between Unknown and I4 if ((int)CourseManager.MatchState == 4) { CourseManager instance = SingletonNetworkBehaviour<CourseManager>.Instance; FieldInfo fieldInfo = AccessTools.Field(typeof(CourseManager), "countdownRemainingTime"); if (!((Object)(object)instance == (Object)null) && !(fieldInfo == null)) { fieldInfo.SetValue(instance, 0f); Plugin.Log.LogInfo((object)"⏱\ufe0f Majority reached → the hole ends now"); } } } public static void AwardRound() { if (ScoreboardTeamData.HoleAwarded) { return; } ScoreboardTeamData.HoleAwarded = true; int cap = Cap(); int num = 0; foreach (int key in ScoreboardTeamData.HoleFinishers.Keys) { num = Math.Max(num, Counted(key, cap)); } if (num <= 0) { Plugin.Log.LogInfo((object)"\ud83c\udfc1 Hole ended with no finisher → no round awarded"); return; } Dictionary<int, int> teamRounds = ScoreboardTeamData.TeamRounds; foreach (int item in new List<int>(ScoreboardTeamData.HoleFinishers.Keys)) { if (Counted(item, cap) == num) { teamRounds[item] = (teamRounds.TryGetValue(item, out var value) ? value : 0) + 1; Plugin.Log.LogInfo((object)$"\ud83c\udfc6 Round won by team {Plugin.TeamNames[item]} → {teamRounds[item]} round(s)"); } } TeamSyncManager.BroadcastScores(); } } public class TeamStanding { public int Team; public int Rank; public int Points; public int Rounds; public readonly List<(ulong guid, string name, int score)> Players = new List<(ulong, string, int)>(); } public static class TeamStandings { public static bool InPractice => SingletonBehaviour<DrivingRangeManager>.HasInstance; public static int RoundsOf(int team) { if (InPractice || !ScoreboardTeamData.TeamRounds.TryGetValue(team, out var value)) { return 0; } return value; } public static List<int> Sort(Dictionary<int, int> teamPoints, out Dictionary<int, int> teamRank) { List<int> list = new List<int>(teamPoints.Keys); list.Sort(delegate(int a, int b) { if (Plugin.RoundsMode) { int num3 = RoundsOf(b).CompareTo(RoundsOf(a)); if (num3 != 0) { return num3; } } int num4 = teamPoints[b].CompareTo(teamPoints[a]); return (num4 == 0) ? a.CompareTo(b) : num4; }); Dictionary<int, int> dictionary = new Dictionary<int, int>(); for (int num = 0; num < list.Count; num++) { int num2 = list[num]; dictionary[num2] = ((num > 0 && SameStanding(list[num - 1], num2)) ? dictionary[list[num - 1]] : (num + 1)); } teamRank = dictionary; return list; bool SameStanding(int x, int y) { if (teamPoints[x] == teamPoints[y]) { if (Plugin.RoundsMode) { return RoundsOf(x) == RoundsOf(y); } return true; } return false; } } public static List<TeamStanding> Compute() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: 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) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) Dictionary<int, TeamStanding> dictionary = new Dictionary<int, TeamStanding>(); SyncList<PlayerState> playerStates = CourseManager.PlayerStates; if (playerStates != null) { Enumerator<PlayerState> enumerator = playerStates.GetEnumerator(); try { while (enumerator.MoveNext()) { PlayerState current = enumerator.Current; if (current.isConnected && !current.isInSpectatorMode) { int team = Plugin.GetTeam(current.playerGuid); if (!dictionary.TryGetValue(team, out var value)) { TeamStanding obj = new TeamStanding { Team = team }; value = obj; dictionary[team] = obj; } value.Points += current.courseScore; value.Players.Add((current.playerGuid, CourseManager.GetPlayerName(current.playerGuid), current.courseScore)); } } } finally { ((IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose(); } } Dictionary<int, int> dictionary2 = new Dictionary<int, int>(); foreach (KeyValuePair<int, TeamStanding> item in dictionary) { dictionary2[item.Key] = item.Value.Points; } List<TeamStanding> list = new List<TeamStanding>(); Dictionary<int, int> teamRank; foreach (int item2 in Sort(dictionary2, out teamRank)) { TeamStanding teamStanding = dictionary[item2]; teamStanding.Rank = teamRank[item2]; teamStanding.Rounds = RoundsOf(item2); teamStanding.Players.Sort(((ulong guid, string name, int score) a, (ulong guid, string name, int score) b) => b.score.CompareTo(a.score)); list.Add(teamStanding); } return list; } } public static class TeamPodium { private static string _lastSummary = ""; public static bool Visible { get; private set; } public static List<TeamStanding> Standings { get; private set; } = new List<TeamStanding>(); public static void Refresh() { NextMatchCountdown val = null; try { val = ShouldShow(); } catch (Exception ex) { Plugin.Log.LogError((object)("TeamPodium.ShouldShow: " + ex.Message)); } if ((Object)(object)val == (Object)null) { if (Visible) { Visible = false; Standings = new List<TeamStanding>(); _lastSummary = ""; TeamPodiumView.Destroy(); Plugin.Log.LogInfo((object)"\ud83c\udfc5 PODIUM hidden"); } return; } try { int networkdisplayedTime = val.NetworkdisplayedTime; if (!Visible || networkdisplayedTime < 0 || networkdisplayedTime > 1) { Standings = TeamStandings.Compute(); string text = Describe(Standings); if (text != _lastSummary) { _lastSummary = text; Plugin.Log.LogInfo((object)("\ud83c\udfc5 PODIUM: " + text)); TeamPodiumView.Build(Standings); } } Visible = true; TeamPodiumView.Sync(); } catch (Exception ex2) { Plugin.Log.LogError((object)("TeamPodium.Refresh: " + ex2.Message)); } } private static NextMatchCountdown? ShouldShow() { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Invalid comparison between Unknown and I4 if (!Plugin.Enabled || Plugin.TeamCount <= 1) { return null; } if (TeamStandings.InPractice) { return null; } if (!SingletonNetworkBehaviour<NextMatchCountdown>.HasInstance) { return null; } NextMatchCountdown instance = SingletonNetworkBehaviour<NextMatchCountdown>.Instance; if (!instance.NetworkisVisible || !instance.NetworkisCourseFinished) { return null; } if ((int)CourseManager.MatchState != 6) { return null; } return instance; } private static string Describe(List<TeamStanding> standings) { List<string> list = new List<string>(); foreach (TeamStanding standing in standings) { List<string> list2 = new List<string>(); foreach (var player in standing.Players) { string item = player.name; int item2 = player.score; list2.Add($"{item}:{item2}"); } list.Add(string.Format("#{0} {1} {2}pts {3}rounds [{4}]", standing.Rank, Plugin.TeamNames[standing.Team], standing.Points, standing.Rounds, string.Join(",", list2))); } return string.Join(" | ", list); } } public static class TeamPodiumView { internal sealed class GameStyle { public Sprite? Sprite; public Type SpriteType; public float SpritePixels = 1f; public Color Panel = FallbackPanel; public TMP_FontAsset? Font; public Color Text = FallbackText; } private const float DesignW = 1800f; private const float DesignH = 880f; private static readonly Color FallbackPanel = new Color(0.98f, 0.96f, 0.91f); internal static readonly Color FallbackText = new Color(0.17f, 0.15f, 0.13f); private static GameObject? _root; private static List<TeamStanding> _standings = new List<TeamStanding>(); private static Rect _builtWindow; private static Type? _scoreboardType; private static Object? _scoreboard; private static Sprite? _circle; public static bool Exists => (Object)(object)_root != (Object)null; internal static Object? ScoreboardObject { get { if (!FindScoreboard()) { return null; } return _scoreboard; } } public static void Destroy() { if ((Object)(object)_root != (Object)null) { Object.Destroy((Object)(object)_root); } _root = null; } public static void Build(List<TeamStanding> standings) { Destroy(); _standings = standings; try { BuildInternal(standings); } catch (Exception arg) { Plugin.Log.LogError((object)$"TeamPodiumView.Build: {arg}"); Destroy(); } } public static void Sync() { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) if (Exists) { Rect val = CurrentWindow(); if (Mathf.Abs(((Rect)(ref val)).x - ((Rect)(ref _builtWindow)).x) > 1.5f || Mathf.Abs(((Rect)(ref val)).y - ((Rect)(ref _builtWindow)).y) > 1.5f || Mathf.Abs(((Rect)(ref val)).width - ((Rect)(ref _builtWindow)).width) > 1.5f || Mathf.Abs(((Rect)(ref val)).height - ((Rect)(ref _builtWindow)).height) > 1.5f) { Build(_standings); } } } internal static float Luminance(Color c) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0011: 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) return 0.299f * c.r + 0.587f * c.g + 0.114f * c.b; } private static bool FindScoreboard() { if (_scoreboard != (Object)null) { return true; } if ((object)_scoreboardType == null) { _scoreboardType = AccessTools.TypeByName("Scoreboard"); } if (_scoreboardType == null) { return false; } _scoreboard = Object.FindAnyObjectByType(_scoreboardType, (FindObjectsInactive)1); return _scoreboard != (Object)null; } private static Rect CurrentWindow() { //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) try { if (FindScoreboard()) { object? obj = AccessTools.Field(_scoreboardType, "fullBackground")?.GetValue(_scoreboard); Image val = (Image)((obj is Image) ? obj : null); if ((Object)(object)val != (Object)null && ((Behaviour)val).isActiveAndEnabled) { Vector3[] array = (Vector3[])(object)new Vector3[4]; ((Graphic)val).rectTransform.GetWorldCorners(array); Canvas val2 = (((Object)(object)((Graphic)val).canvas != (Object)null) ? ((Graphic)val).canvas.rootCanvas : null); Camera val3 = (((Object)(object)val2 != (Object)null && (int)val2.renderMode != 0) ? val2.worldCamera : null); Vector2 val4 = RectTransformUtility.WorldToScreenPoint(val3, array[0]); Vector2 val5 = RectTransformUtility.WorldToScreenPoint(val3, array[2]); Rect result = Rect.MinMaxRect(Mathf.Min(val4.x, val5.x), Mathf.Min(val4.y, val5.y), Mathf.Max(val4.x, val5.x), Mathf.Max(val4.y, val5.y)); if (((Rect)(ref result)).width > 200f && ((Rect)(ref result)).height > 200f) { return result; } } } } catch { } return Rect.MinMaxRect((float)Screen.width * 0.03f, (float)Screen.height * 0.09f, (float)Screen.width * 0.97f, (float)Screen.height * 0.87f); } private static float CanvasScale() { float num = Mathf.Max(1f, (float)Screen.width); float num2 = Mathf.Max(1f, (float)Screen.height); return Mathf.Pow(2f, Mathf.Lerp(Mathf.Log(num / 1920f, 2f), Mathf.Log(num2 / 1080f, 2f), 0.5f)); } internal static GameStyle ReadGameStyle() { //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: 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_01e6: 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_013f: 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_014f: Unknown result type (might be due to invalid IL or missing references) //IL_015e: 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_016c: Unknown result type (might be due to invalid IL or missing references) //IL_0178: 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_0212: Unknown result type (might be due to invalid IL or missing references) GameStyle gameStyle = new GameStyle(); try { if (!FindScoreboard()) { return gameStyle; } Type scoreboardType = _scoreboardType; Object scoreboard = _scoreboard; object? obj = AccessTools.Field(scoreboardType, "fullBackground")?.GetValue(scoreboard); Image val = (Image)((obj is Image) ? obj : null); if (val != null && (Object)(object)val.sprite != (Object)null) { gameStyle.Sprite = val.sprite; gameStyle.SpriteType = val.type; gameStyle.SpritePixels = val.pixelsPerUnitMultiplier; Color color = ((Graphic)val).color; if (color.a > 0.5f && Luminance(color) > 0.6f) { gameStyle.Panel = new Color(color.r, color.g, color.b, 1f); } } string[] array = new string[5] { "holeName", "parInfo", "courseProgress", "lobbyNameLabel", "localPlayerScore" }; foreach (string text in array) { object? obj2 = AccessTools.Field(scoreboardType, text)?.GetValue(scoreboard); TMP_Text val2 = (TMP_Text)((obj2 is TMP_Text) ? obj2 : null); if (val2 != null && (Object)(object)val2.font != (Object)null) { gameStyle.Font = val2.font; Color color2 = ((Graphic)val2).color; if (color2.a > 0.5f && Luminance(color2) < 0.45f) { gameStyle.Text = new Color(color2.r, color2.g, color2.b, 1f); } break; } } ManualLogSource log = Plugin.Log; Sprite? sprite = gameStyle.Sprite; string text2 = string.Format("\ud83c\udfa8 UI style: sprite={0} type={1} ", ((sprite != null) ? ((Object)sprite).name : null) ?? "none", gameStyle.SpriteType); object[] obj3 = new object[4] { gameStyle.SpritePixels, gameStyle.Panel, null, null }; TMP_FontAsset? font = gameStyle.Font; obj3[2] = ((font != null) ? ((Object)font).name : null) ?? "default"; obj3[3] = gameStyle.Text; log.LogInfo((object)(text2 + string.Format("pixels={0} panel={1} font={2} text={3}", obj3))); } catch (Exception ex) { Plugin.Log.LogError((object)("TeamPodiumView.ReadGameStyle: " + ex.Message)); } return gameStyle; } internal static void Skin(Image image, GameStyle style, Color color, float pixelScale) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) ((Graphic)image).color = color; ((Graphic)image).raycastTarget = false; if (!((Object)(object)style.Sprite == (Object)null)) { image.sprite = style.Sprite; image.type = style.SpriteType; image.pixelsPerUnitMultiplier = style.SpritePixels * pixelScale; } } internal static RectTransform NewRect(string name, Transform parent, float x, float y, float w, float h, out GameObject go) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) go = new GameObject(name, new Type[1] { typeof(RectTransform) }); RectTransform val = (RectTransform)go.transform; ((Transform)val).SetParent(parent, false); Vector2 anchorMin = (val.anchorMax = Vector2.zero); val.anchorMin = anchorMin; val.pivot = Vector2.zero; val.anchoredPosition = new Vector2(x, y); val.sizeDelta = new Vector2(w, h); return val; } internal static Image NewImage(Transform parent, GameStyle style, string name, float x, float y, float w, float h, Color color, float pixelScale, bool rounded = true) { //IL_002a: 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) NewRect(name, parent, x, y, w, h, out GameObject go); Image val = go.AddComponent<Image>(); if (rounded) { Skin(val, style, color, pixelScale); } else { ((Graphic)val).color = color; ((Graphic)val).raycastTarget = false; } return val; } private static Sprite Circle() { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_circle != (Object)null) { return _circle; } Texture2D val = new Texture2D(128, 128, (TextureFormat)4, false) { filterMode = (FilterMode)1, wrapMode = (TextureWrapMode)1, hideFlags = (HideFlags)61 }; Color32[] array = (Color32[])(object)new Color32[16384]; float num = 64f; for (int i = 0; i < 128; i++) { for (int j = 0; j < 128; j++) { float num2 = (float)j + 0.5f - num; float num3 = (float)i + 0.5f - num; float num4 = Mathf.Clamp01(num - Mathf.Sqrt(num2 * num2 + num3 * num3)); array[i * 128 + j] = new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, (byte)(num4 * 255f)); } } val.SetPixels32(array); val.Apply(); _circle = Sprite.Create(val, new Rect(0f, 0f, 128f, 128f), new Vector2(0.5f, 0.5f), 100f); ((Object)_circle).hideFlags = (HideFlags)61; return _circle; } private static Image NewCircle(Transform parent, string name, float x, float y, float size, Color color) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) Image val = NewImage(parent, null, name, x, y, size, size, color, 1f, rounded: false); val.sprite = Circle(); return val; } internal static TextMeshProUGUI NewText(Transform parent, GameStyle style, float x, float y, float w, float h, string text, float size, Color color, TextAlignmentOptions alignment, bool ellipsis = false) { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) NewRect("Text", parent, x, y, w, h, out GameObject go); TextMeshProUGUI val = go.AddComponent<TextMeshProUGUI>(); if ((Object)(object)style.Font != (Object)null) { ((TMP_Text)val).font = style.Font; } ((TMP_Text)val).text = text; ((TMP_Text)val).fontSize = size; ((Graphic)val).color = color; ((TMP_Text)val).alignment = alignment; ((TMP_Text)val).fontStyle = (FontStyles)0; ((TMP_Text)val).enableAutoSizing = false; ((TMP_Text)val).enableWordWrapping = false; ((TMP_Text)val).overflowMode = (TextOverflowModes)(ellipsis ? 1 : 0); ((Graphic)val).raycastTarget = false; return val; } private static void BuildInternal(List<TeamStanding> standings) { //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Expected O, but got Unknown //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Expected O, but got Unknown //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Expected O, but got Unknown //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0168: 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_017c: 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_0193: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_0215: 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_021e: 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_0226: 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_0245: Unknown result type (might be due to invalid IL or missing references) //IL_025a: Unknown result type (might be due to invalid IL or missing references) //IL_0290: Unknown result type (might be due to invalid IL or missing references) //IL_0346: Unknown result type (might be due to invalid IL or missing references) //IL_034b: Unknown result type (might be due to invalid IL or missing references) //IL_03a4: Unknown result type (might be due to invalid IL or missing references) //IL_03ab: Unknown result type (might be due to invalid IL or missing references) //IL_03b2: Unknown result type (might be due to invalid IL or missing references) //IL_03be: Unknown result type (might be due to invalid IL or missing references) //IL_03fa: Unknown result type (might be due to invalid IL or missing references) //IL_040f: Unknown result type (might be due to invalid IL or missing references) //IL_0408: Unknown result type (might be due to invalid IL or missing references) //IL_049a: Unknown result type (might be due to invalid IL or missing references) //IL_04e4: Unknown result type (might be due to invalid IL or missing references) //IL_04eb: Unknown result type (might be due to invalid IL or missing references) //IL_04f2: Unknown result type (might be due to invalid IL or missing references) //IL_04fe: Unknown result type (might be due to invalid IL or missing references) //IL_0554: Unknown result type (might be due to invalid IL or missing references) //IL_0556: Unknown result type (might be due to invalid IL or missing references) //IL_0560: Unknown result type (might be due to invalid IL or missing references) //IL_05fa: Unknown result type (might be due to invalid IL or missing references) List<TeamStanding> list = new List<TeamStanding>(); foreach (TeamStanding standing in standings) { if (standing.Rank <= 3) { list.Add(standing); } } if (list.Count == 0) { return; } GameStyle gameStyle = ReadGameStyle(); _root = new GameObject("TM_Podium", new Type[1] { typeof(RectTransform) }); Object.DontDestroyOnLoad((Object)(object)_root); Canvas val = _root.AddComponent<Canvas>(); val.renderMode = (RenderMode)0; val.sortingOrder = 1000; CanvasScaler val2 = _root.AddComponent<CanvasScaler>(); val2.uiScaleMode = (ScaleMode)1; val2.referenceResolution = new Vector2(1920f, 1080f); val2.screenMatchMode = (ScreenMatchMode)0; val2.matchWidthOrHeight = 0.5f; Rect val3 = (_builtWindow = CurrentWindow()); GameObject val4 = new GameObject("Panel", new Type[1] { typeof(RectTransform) }); RectTransform val5 = (RectTransform)val4.transform; ((Transform)val5).SetParent(_root.transform, false); val5.anchorMin = new Vector2(((Rect)(ref val3)).xMin / (float)Screen.width, ((Rect)(ref val3)).yMin / (float)Screen.height); val5.anchorMax = new Vector2(((Rect)(ref val3)).xMax / (float)Screen.width, ((Rect)(ref val3)).yMax / (float)Screen.height); Vector2 offsetMin = (val5.offsetMax = Vector2.zero); val5.offsetMin = offsetMin; Skin(val4.AddComponent<Image>(), gameStyle, gameStyle.Panel, 1f); float num = CanvasScale(); float num2 = Mathf.Min(((Rect)(ref val3)).width / num / 1800f, ((Rect)(ref val3)).height / num / 880f); RectTransform component = new GameObject("Content", new Type[1] { typeof(RectTransform) }).GetComponent<RectTransform>(); ((Transform)component).SetParent((Transform)(object)val5, false); Vector2 val6 = default(Vector2); ((Vector2)(ref val6))..ctor(0.5f, 0.5f); component.pivot = val6; offsetMin = (component.anchorMax = val6); component.anchorMin = offsetMin; component.anchoredPosition = Vector2.zero; component.sizeDelta = new Vector2(1800f, 880f); ((Transform)component).localScale = new Vector3(num2, num2, 1f); NewText((Transform)(object)component, gameStyle, 0f, 750f, 1800f, 110f, Lang.Get("Classement final", "Final standings"), 62f, gameStyle.Text, (TextAlignmentOptions)514); int count = list.Count; TeamStanding[] array = new TeamStanding[count]; for (int i = 0; i < count; i++) { int num3 = count / 2 + ((i != 0) ? ((i + 1) / 2 * ((i % 2 != 1) ? 1 : (-1))) : 0); if (num3 >= 0 && num3 < count) { array[num3] = list[i]; } } float num4 = Mathf.Min(560f, 1720f / (float)count); float num5 = (1800f - num4 * (float)count) / 2f; for (int j = 0; j < count; j++) { TeamStanding teamStanding = array[j]; if (teamStanding != null) { Color val8 = Plugin.TeamColors[teamStanding.Team]; float w = num4 - 40f; float x = num5 + num4 * (float)j + 20f; float num6 = ((teamStanding.Rank == 1) ? 240f : ((teamStanding.Rank == 2) ? 170f : 120f)); Image val9 = NewImage((Transform)(object)component, gameStyle, "Step", x, 44f, w, num6, new Color(val8.r, val8.g, val8.b, 1f), 2f); NewText(((Component)val9).transform, gameStyle, 0f, 0f, w, num6, teamStanding.Rank.ToString(), num6 * 0.62f, (Luminance(val8) > 0.6f) ? FallbackText : Color.white, (TextAlignmentOptions)514); int count2 = teamStanding.Players.Count; float num7 = Mathf.Clamp((320f - 10f * (float)(count2 - 1)) / (float)Mathf.Max(1, count2), 40f, 80f); float num8 = num7 * (float)count2 + 10f * (float)Mathf.Max(0, count2 - 1); float num9 = 44f + num6 + 16f; for (int k = 0; k < count2; k++) { BuildCard((Transform)(object)component, gameStyle, teamStanding.Players[k], val8, x, num9 + num8 - num7 - (float)k * (num7 + 10f), w, num7); } Image val10 = NewImage((Transform)(object)component, gameStyle, "Header", x, num9 + num8 + 14f, w, 104f, new Color(val8.r, val8.g, val8.b, 0.3f), 2f); NewText(((Component)val10).transform, gameStyle, 0f, 52f, w, 48f, Lang.Get("Équipe", "Team") + " " + Plugin.TeamNames[teamStanding.Team], 38f, Color.Lerp(val8, Color.black, 0.45f), (TextAlignmentOptions)514); string text = (Plugin.RoundsMode ? string.Format("{0} {1}", teamStanding.Rounds, Lang.Get((teamStanding.Rounds > 1) ? "manches" : "manche", (teamStanding.Rounds > 1) ? "rounds" : "round")) : $"{teamStanding.Points} pts"); NewText(((Component)val10).transform, gameStyle, 0f, 4f, w, 52f, text, 46f, gameStyle.Text, (TextAlignmentOptions)514); } } } private static void BuildCard(Transform parent, GameStyle style, (ulong guid, string name, int score) player, Color team, float x, float y, float w, float h) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: 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_018b: Unknown result type (might be due to invalid IL or missing references) Image val = NewImage(parent, style, "Card", x, y, w, h, new Color(0.91f, 0.89f, 0.83f, 1f), 3f); float num = h - 16f; Image val2 = NewCircle(((Component)val).transform, "AvatarFrame", 12f, 8f, num, team); Image val3 = NewCircle(((Component)val2).transform, "AvatarMask", 3f, 3f, num - 6f, Color.white); ((Component)val3).gameObject.AddComponent<Mask>().showMaskGraphic = false; Sprite val4 = null; try { val4 = PlayerIconManager.GetPlayerIcon(player.guid, (IconSize)1); } catch { } Image val5 = NewImage(((Component)val3).transform, style, "Avatar", 0f, 0f, num - 6f, num - 6f, (Color)(((Object)(object)val4 != (Object)null) ? Color.white : new Color(0.6f, 0.6f, 0.6f)), 1f, rounded: false); if ((Object)(object)val4 != (Object)null) { val5.sprite = val4; } float num2 = 12f + num + 14f; NewText(((Component)val).transform, style, num2, 0f, w - num2 - 104f, h, player.name, h * 0.42f, style.Text, (TextAlignmentOptions)4097, ellipsis: true); NewText(((Component)val).transform, style, w - 104f, 0f, 92f, h, player.score.ToString(), h * 0.46f, style.Text, (TextAlignmentOptions)4100); } } [HarmonyPatch] public class DrivingRangeScoreResetPatch { [HarmonyTargetMethod] private static MethodBase TargetMethod() { return AccessTools.Method(AccessTools.TypeByName("DrivingRangeManager"), "Awake", (Type[])null, (Type[])null); } [HarmonyPostfix] private static void Postfix() { ScoreboardTeamData.TeamRounds.Clear(); RoundsTracker.NewHole(); Plugin.Log.LogInfo((object)"\ud83c\udfaf Terrain d'entraînement → manches d'équipe remises à zéro"); TeamSyncManager.BroadcastScores(); } } [HarmonyPatch] public class ScoreboardEntryPatch { [HarmonyTargetMethod] private static MethodBase TargetMethod() { return AccessTools.Method(AccessTools.TypeByName("ScoreboardEntry"), "PopulateWith", (Type[])null, (Type[])null); } [HarmonyPostfix] private static void Postfix(object __instance, object playerState) { //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: 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_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) try { BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; ulong num = (ulong)(playerState.GetType().GetField("playerGuid", BindingFlags.Instance | BindingFlags.Public)?.GetValue(playerState) ?? ((object)0uL)); object obj = ((__instance is Component) ? __instance : null); GameObject val = ((obj != null) ? ((Component)obj).gameObject : null); int value = (int)(playerState.GetType().GetField("courseScore", BindingFlags.Instance | BindingFlags.Public)?.GetValue(playerState) ?? ((object)0)); if ((Object)(object)val != (Object)null) { ScoreboardTeamData.EntryGuids[val] = num; ScoreboardTeamData.EntryScores[val] = value; } if (Plugin.Enabled) { int team = Plugin.GetTeam(num); object? obj2 = __instance.GetType().GetField("name", bindingAttr)?.GetValue(__instance); TMP_Text val2 = (TMP_Text)((obj2 is TMP_Text) ? obj2 : null); if (!((Object)(object)val2 == (Object)null)) { Color val3 = Color.Lerp(Plugin.TeamColors[team], Color.black, (team == 3) ? 0.4f : 0.15f); val2.text = "<color=#" + ColorUtility.ToHtmlStringRGB(val3) + ">" + val2.text + "</color>"; } } } catch (Exception ex) { Plugin.Log.LogError((object)("ScoreboardEntryPatch: " + ex.Message)); } } } [HarmonyPatch] public class ScoreboardRefreshPatch { private static readonly List<GameObject> _teamHeaders = new List<GameObject>(); [HarmonyTargetMethod] private static MethodBase TargetMethod() { return AccessTools.Method(AccessTools.TypeByName("Scoreboard"), "Refresh", (Type[])null, (Type[])null); } [HarmonyPostfix] private static void Postfix(object __instance) { //IL_0279: Unknown result type (might be due to invalid IL or missing references) //IL_027e: Unknown result type (might be due to invalid IL or missing references) //IL_0335: Unknown result type (might be due to invalid IL or missing references) //IL_037a: Unknown result type (might be due to invalid IL or missing references) foreach (GameObject teamHeader in _teamHeaders) { if ((Object)(object)teamHeader != (Object)null) { Object.Destroy((Object)(object)teamHeader); } } _teamHeaders.Clear(); ModeLabels.UpdateScoreboardTitle((Component?)((__instance is Component) ? __instance : null)); if (!Plugin.Enabled) { return; } try { BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; object? obj = __instance.GetType().GetField("entryParent", bindingFlags)?.GetValue(__instance); Transform val = (Transform)((obj is Transform) ? obj : null); if ((Object)(object)val == (Object)null) { return; } List<GameObject> list = new List<GameObject>(); foreach (KeyValuePair<GameObject, ulong> entryGuid in ScoreboardTeamData.EntryGuids) { if ((Object)(object)entryGuid.Key == (Object)null) { list.Add(entryGuid.Key); } } foreach (GameObject item2 in list) { ScoreboardTeamData.EntryGuids.Remove(item2); ScoreboardTeamData.EntryScores.Remove(item2); } bool inPractice = TeamStandings.InPractice; Dictionary<int, int> dictionary = new Dictionary<int, int>(); Dictionary<int, List<(GameObject, int)>> dictionary2 = new Dictionary<int, List<(GameObject, int)>>(); for (int i = 0; i < val.childCount; i++) { GameObject gameObject = ((Component)val.GetChild(i)).gameObject; if (gameObject.activeSelf && ScoreboardTeamData.EntryGuids.TryGetValue(gameObject, out var value)) { int team = Plugin.GetTeam(value); int value2; int num = (ScoreboardTeamData.EntryScores.TryGetValue(gameObject, out value2) ? value2 : 0); dictionary[team] = (dictionary.TryGetValue(team, out var value3) ? value3 : 0) + ((!inPractice) ? num : 0); if (!dictionary2.ContainsKey(team)) { dictionary2[team] = new List<(GameObject, int)>(); } dictionary2[team].Add((gameObject, num)); } } Dictionary<int, int> teamRank; List<int> list2 = TeamStandings.Sort(dictionary, out teamRank); int num2 = 0; foreach (int item3 in list2) { if (!dictionary2.ContainsKey(item3) || dictionary2[item3].Count == 0) { continue; } List<(GameObject, int)> list3 = dictionary2[item3]; list3.Sort(((GameObject go, int score) a, (GameObject go, int score) b) => b.score.CompareTo(a.score)); Color teamColor = Plugin.TeamColors[item3]; string teamName = Plugin.TeamNames[item3]; int num3; string label; if (Plugin.RoundsMode) { num3 = RoundsOf(item3); label = string.Format("{0} {1}", num3, Lang.Get((num3 > 1) ? "manches" : "manche", (num3 > 1) ? "rounds" : "round")); } else { num3 = dictionary[item3]; label = $"{num3} pts"; } GameObject val2 = Object.Instantiate<GameObject>(list3[0].Item1, val); ((Object)val2).name = $"TM_TeamHeader_{item3}"; _teamHeaders.Add(val2); SetupTeamHeader(val2, teamName, label, num3, teamColor, bindingFlags); val2.transform.SetSiblingIndex(num2); num2++; foreach (var item4 in list3) { GameObject item = item4.Item1; item.transform.SetSiblingIndex(num2); TryColorEntryBackground(item, teamColor); SetEntryRank(item, teamRank[item3], bindingFlags); num2++; } } } catch (Exception ex) { Plugin.Log.LogError((object)("ScoreboardRefreshPatch: " + ex.Message)); } static int RoundsOf(int t) { return TeamStandings.RoundsOf(t); } } private static void SetupTeamHeader(GameObject header, string teamName, string label, int totalScore, Color teamColor, BindingFlags flags) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) try { Image[] componentsInChildren = header.GetComponentsInChildren<Image>(true); if (componentsInChildren.Length != 0) { ((Graphic)componentsInChildren[0]).color = new Color(teamColor.r, teamColor.g, teamColor.b, 0.35f); } for (int i = 1; i < componentsInChildren.Length; i++) { ((Graphic)componentsInChildren[i]).color = Color.clear; } TMP_Text[] componentsInChildren2 = header.GetComponentsInChildren<TMP_Text>(true); foreach (TMP_Text val in componentsInChildren2) { val.text = ""; } Component component = header.GetComponent(AccessTools.TypeByName("ScoreboardEntry")); if (!((Object)(object)component == (Object)null)) { object? obj = ((object)component).GetType().GetField("name", flags)?.GetValue(component); TMP_Text val2 = (TMP_Text)((obj is TMP_Text) ? obj : null); if ((Object)(object)val2 != (Object)null) { val2.text = "<b><color=#" + ColorUtility.ToHtmlStringRGB(teamColor) + ">" + Lang.Get("Équipe", "Team") + " " + teamName + " — " + label + "</color></b>"; val2.fontSize *= 1.1f; } object? obj2 = ((object)component).GetType().GetField("matchScore", flags)?.GetValue(component); TMP_Text val3 = (TMP_Text)((obj2 is TMP_Text) ? obj2 : null); if ((Object)(object)val3 != (Object)null) { val3.text = totalScore.ToString(); } } } catch { } } private static void SetEntryRank(GameObject go, int rank, BindingFlags flags) { try { Component component = go.GetComponent(AccessTools.TypeByName("ScoreboardEntry")); object? obj = ((object)component)?.GetType().GetField("ranking", flags)?.GetValue(component); TMP_Text val = (TMP_Text)((obj is TMP_Text) ? obj : null); if ((Object)(object)val != (Object)null) { val.text = rank.ToString(); } } catch { } } private static void TryColorEntryBackground(GameObject go, Color teamColor) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) try { Image[] componentsInChildren = go.GetComponentsInChildren<Image>(true); if (componentsInChildren.Length != 0) { Color val = default(Color); ((Color)(ref val))..ctor(teamColor.r, teamColor.g, teamColor.b, 0.15f); ((Graphic)componentsInChildren[0]).color = Color.Lerp(((Graphic)componentsInChildren[0]).color, val, 0.4f); } } catch { } } } [HarmonyPatch] public class TeamModeMenuPatch { [HarmonyTargetMethod] private static MethodBase TargetMethod() { return AccessTools.Method(AccessTools.TypeByName("MatchSetupRules"), "Initialize", (Type[])null, (Type[])null); } [HarmonyPostfix] private static void Postfix(object __instance) { RoundsTracker.NewHole(); Plugin.Log.LogInfo((object)"\ud83d\uddfa\ufe0f New hole → finishers reset"); try { BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; object? obj = __instance.GetType().GetField("countdown", bindingAttr)?.GetValue(__instance); Component val = (Component)((obj is Component) ? obj : null); if ((Object)(object)val == (Object)null) { return; } Transform parent = val.transform.parent.parent.parent; for (int i = 0; i < parent.childCount; i++) { if (((Object)parent.GetChild(i)).name == "Team Mode Header") { return; } } GameObject gameObject = ((Component)val.transform.parent.GetChild(0)).gameObject; object? obj2 = __instance.GetType().GetField("knockouts", bindingAttr)?.GetValue(__instance); Component val2 = (Component)((obj2 is Component) ? obj2 : null); Transform val3 = null; Transform val4 = null; for (int j = 0; j < parent.childCount; j++) { Transform child = parent.GetChild(j); if (((Object)child).name == "Battle") { val3 = child; } if (((Object)child).name == "Battle Rules") { val4 = child; } } if (!((Object)(object)val3 == (Object)null) && !((Object)(object)val4 == (Object)null)) { GameObject val5 = Object.Instantiate<GameObject>(((Component)val3).gameObject, parent); ((Object)val5).name = "Team Mode Header"; LocalizeStringEvent[] componentsInChildren = val5.GetComponentsInChildren<LocalizeStringEvent>(true); foreach (LocalizeStringEvent val6 in componentsInChildren) { Object.Destroy((Object)(object)val6); } TMP_Text componentInChildren = val5.GetComponentInChildren<TMP_Text>(true); if ((Object)(object)componentInChildren != (Object)null) { componentInChildren.text = EnhancedMode.Label; } GameObject val7 = Object.Instantiate<GameObject>(((Component)val4).gameObject, parent); ((Object)val7).name = "Team Mode Rules"; for (int num = val7.transform.childCount - 1; num >= 0; num--) { Object.Destroy((Object)(object)((Component)val7.transform.GetChild(num)).gameObject); } TeamModeUi.SetSection(val5, val7); TeamModeUi.Build(gameObject, (val2 != null) ? val2.gameObject : null, val7.transform); EnhancedMode.Refresh(); Plugin.Log.LogInfo((object)"✓ Team Mode UI built!"); } } catch (Exception ex) { Plugin.Log.LogError((object)("TeamModeMenuPatch: " + ex.Message + "\n" + ex.StackTrace)); } } } public static class EnhancedMode { public const int Index = 2; public static int Programmatic; public static string Label => Lang.Get("Mode Équipes Amélioré", "Improved Team Mode"); private static MatchSetupMenu? Menu { get { if (!SingletonNetworkBehaviour<MatchSetupMenu>.HasInstance) { return null; } return SingletonNetworkBehaviour<MatchSetupMenu>.Instance; } } public static TMP_Dropdown? ModeDropdown { get { if (!((Object)(object)Menu?.gameModeDropdown != (Object)null)) { return null; } return Menu.gameModeDropdown.Dropdown; } } public static string DropdownLabel => Lang.Get("Équipes Améliorées", "Improved Teams"); private static void EnsureOption(TMP_Dropdown dropdown) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown List<OptionData> options = dropdown.options; if (options.Count == 2) { options.Add(new OptionData(DropdownLabel)); dropdown.options = options; } else if (options.Count > 2 && options[2].text != DropdownLabel) { options[2].text = DropdownLabel; dropdown.RefreshShownValue(); } } public static void Refresh() { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Expected I4, but got Unknown try { MatchSetupMenu menu = Menu; TMP_Dropdown modeDropdown = ModeDropdown; if (!((Object)(object)menu == (Object)null) && !((Object)(object)modeDropdown == (Object)null)) { EnsureOption(modeDropdown); int num = ((Plugin.EnabledSetting && (int)menu.gameMode == 0) ? 2 : ((int)menu.gameMode)); if (modeDropdown.value != num) { modeDropdown.SetValueWithoutNotify(num); } modeDropdown.RefreshShownValue(); } } catch (Exception ex) { Plugin.Log.LogError((object)("EnhancedMode.Refresh: " + ex.Message)); } } public static bool OnHostPicked(MatchSetupMenu menu, int value) { //IL_0049: Unknown result type (might be due to invalid IL or missing references) bool flag = value == 2; bool flag2 = Plugin.EnabledSetting != flag; Plugin.EnabledSetting = flag; Plugin.Log.LogInfo((object)("[TeamMode] Game mode menu → " + (flag ? "Enhanced teams (Team Mode ON)" : $"game mode {value} (Team Mode OFF)"))); if (flag && (int)menu.gameMode != 0) { menu.NetworkgameMode = (GameMode)0; } if (flag2) { if (flag) { TeamModeUi.RebuildPlayerDropdowns(); } if (NetworkServer.active) { TeamSyncManager.BroadcastFullState(); } } TeamModeUi.UpdateSection(); CustomScoringBridge.Update(); return !flag; } public static void OnGameModeChanged(MatchSetupMenu menu, GameMode current) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Invalid comparison between Unknown and I4 if (((NetworkBehaviour)menu).isServer && (int)current == 1 && Plugin.EnabledSetting) { Plugin.EnabledSetting = false; Plugin.Log.LogInfo((object)"[TeamMode] Native Teams mode selected → Team Mode OFF"); if (NetworkServer.active) { TeamSyncManager.BroadcastFullState(); } TeamModeUi.UpdateSection(); CustomScoringBridge.Update(); } Refresh(); } } public static class CustomScoringBridge { private static bool? _savedEnabled; private static bool _looked; private static Type? _type; private static Type? CustomScoringType() { if (_looked) { return _type; } _looked = true; try { foreach (PluginInfo value in Chainloader.PluginInfos.Values) { Type type = ((object)value.Instance)?.GetType(); if (type != null && type.FullName == "Custom_Scoring.Plugin") { _type = type; break; } } } catch (Exception ex) { Plugin.Log.LogWarning((object)("CustomScoringBridge: plugin list unavailable (" + ex.Message + ")")); } Plugin.Log.LogInfo((object)((_type != null) ? "[TeamMode] Custom_Scoring found: its menu section is hidden in Rounds mode" : "[TeamMode] Custom_Scoring not installed: nothing to hide")); return _type; } public static void Update() { Type type = CustomScoringType(); if (type == null) { return; } try { bool flag = Plugin.EnabledSetting && Plugin.RoundsMode; SetSectionVisible(!flag); FieldInfo fieldInfo = AccessTools.Field(type, "Enabled"); if (fieldInfo == null) { return; } bool flag2 = (bool)fieldInfo.GetValue(null); if (flag) { bool valueOrDefault = _savedEnabled == true; if (!_savedEnabled.HasValue) { valueOrDefault = flag2; _savedEnabled = valueOrDefault; } if (flag2) { fieldInfo.SetValue(null, false); AccessTools.Method(type, "ApplyPlacement", (Type[])null, (Type[])null)?.Invoke(null, null); Plugin.Log.LogInfo((object)"[TeamMode] Rounds mode → Custom Scoring hidden and switched off"); } } else if (_savedEnabled.HasValue) { bool value = _savedEnabled.Value; _savedEnabled = null; if (flag2 != value) { fieldInfo.SetValue(null, value); AccessTools.Method(type, "ApplyPlacement", (Type[])null, (Type[])null)?.Invoke(null, null); Plugin.Log.LogInfo((object)("[TeamMode] Left Rounds mode → Custom Scoring back (" + (value ? "on" : "off") + ")")); } } } catch (Exception ex) { Plugin.Log.LogError((object)("CustomScoringBridge: " + ex.Message)); } } private static void SetSectionVisible(bool visible) { Transform rulesContent = TeamModeUi.RulesContent; if ((Object)(object)rulesContent == (Object)null) { return; } for (int i = 0; i < rulesContent.childCount; i++) { Transform child = rulesContent.GetChild(i); if ((((Object)child).name == "Custom Scoring Header" || ((Object)child).name == "Custom Scoring Rules") && ((Component)child).gameObject.activeSelf != visible) { ((Component)child).gameObject.SetActive(visible); } } } } public static class ModeLabels { private static string Ffa => UI.MATCHSETUP_Option_Mode_FFA; public static void UpdateScoreboardTitle(Component? scoreboard) { if ((Object)(object)scoreboard == (Object)null) { return; } try { string ffa = Ffa; string label = EnhancedMode.Label; string text = (Plugin.Enabled ? label : ffa); TMP_Text[] componentsInChildren = scoreboard.GetComponentsInChildren<TMP_Text>(true); foreach (TMP_Text val in componentsInChildren) { if ((val.text == ffa || val.text == label) && val.text != text) { val.text = text; } } } catch (Exception ex) { Plugin.Log.LogError((object)("ModeLabels.UpdateScoreboardTitle: " + ex.Message)); } } public static void Tick() { Object? scoreboardObject = TeamPodiumView.ScoreboardObject; UpdateScoreboardTitle((Component?)(object)((scoreboardObject is Component) ? scoreboardObject : null)); } public static void UpdatePauseLabel(TMP_Text? label) { if ((Object)(object)label == (Object)null || !Plugin.Enabled) { return; } try { string ffa = Ffa; if (label.text.Contains(ffa)) { label.text = label.text.Replace(ffa, EnhancedMode.Label); } } catch (Exception ex) { Plugin.Log.LogError((object)("ModeLabels.UpdatePauseLabel: " + ex.Message)); } } } [HarmonyPatch] public class PauseMenuModeLabelPatch { [HarmonyTargetMethod] private static MethodBase TargetMethod() { return AccessTools.Method(AccessTools.TypeByName("PauseMenu"), "UpdateGameInfoLabels", (Type[])null, (Type[])null); } [HarmonyPostfix] private static void Postfix(PauseMenu __instance) { ModeLabels.UpdatePauseLabel(__instance.gamemodeLabel); } } [HarmonyPatch] public class GameModeDropdownPatch { [HarmonyTargetMethod] private static MethodBase TargetMethod() { return AccessTools.Method(AccessTools.TypeByName("DropdownOption"), "OnValueChanged", (Type[])null, (Type[])null); } [HarmonyPrefix] private static bool Prefix(DropdownOption __instance) { try { if (EnhancedMode.Programmatic > 0) { return true; } if (!SingletonNetworkBehaviour<MatchSetupMenu>.HasInstance) { return true; } MatchSetupMenu instance = SingletonNetworkBehaviour<MatchSetupMenu>.Instance; if ((Object)(object)instance.gameModeDropdown != (Object)(object)__instance || !((NetworkBehaviour)instance).isServer) { return true; } return EnhancedMode.OnHostPicked(instance, __instance.value); } catch (Exception ex) { Plugin.Log.LogError((object)("GameModeDropdownPatch: " + ex.Message)); } return true; } } [HarmonyPatch] public class DropdownSetValuePatch { [HarmonyTargetMethod] private static MethodBase TargetMethod() { return AccessTools.Method(AccessTools.TypeByName("DropdownOption"), "SetValue", (Type[])null, (Type[])null); } [HarmonyPrefix] private static void Prefix() { EnhancedMode.Programmatic++; } [HarmonyFinalizer] private static void Finalizer() { EnhancedMode.Programmatic--; if (EnhancedMode.Programmatic <= 0) { EnhancedMode.Programmatic = 0; EnhancedMode.Refresh(); } } } [HarmonyPatch] public class GameModeOptionsPatch { [HarmonyTargetMethod] private static MethodBase TargetMethod() { return AccessTools.Method(AccessTools.TypeByName("LocalizeDropdown"), "RefreshOptions", (Type[])null, (Type[])null); } [HarmonyPostfix] private static void Postfix(LocalizeDropdown __instance) { TMP_Dropdown modeDropdown = EnhancedMode.ModeDropdown; if ((Object)(object)modeDropdown != (Object)null && (Object)(object)((Component)__instance).gameObject == (Object)(object)((Component)modeDropdown).gameObject) { EnhancedMode.Refresh(); } } } [HarmonyPatch] public class GameModeChangedPatch { [HarmonyTargetMethod] private static MethodBase TargetMethod() { return AccessTools.Method(AccessTools.TypeByName("MatchSetupMenu"), "OnGameModeChanged", (Type[])null, (Type[])null); } [HarmonyPostfix] private static void Postfix(MatchSetupMenu __instance, GameMode currentMode) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) EnhancedMode.OnGameModeChanged(__instance, currentMode); } } [HarmonyPatch] public class GameModeMenuOpenPatch { [HarmonyTargetMethod] private static MethodBase TargetMethod() { return AccessTools.Method(AccessTools.TypeByName("MatchSetupMenu"), "SetEnabled", (Type[])null, (Type[])null); } [HarmonyPostfix] private static void Postfix() { EnhancedMode.Refresh(); } } public static class TeamModeUi { private static GameObject? _sliderTemplate; private static GameObject? _dropdownTemplate; private static Transform? _container; private static GameObject? _earlyEndRow; private static GameObject? _header; private static GameObject? _rules; private static readonly List<Selectable> _controls = new List<Selectable>(); public static Transform? RulesContent { get { if (!((Object)(object)_container != (Object)null)) { return null; } return _container.parent; } } public static void SetSection(GameObject header, GameObject rules) { _header = header; _rules = rules; } public static void Build(GameObject sliderTemplate, GameObject? dropdownTemplate, Transform container) { _sliderTemplate = sliderTemplate; _dropdownTemplate = dropdownTemplate; _container = container; _controls.Clear(); _earlyEndRow = null; if ((Object)(object)dropdownTemplate != (Object)null) { AddChoice(dropdownTemplate, container, Lang.Get("Score d'équipe", "Team score"), new List<string> { Lang.Get("Points", "Points"), Lang.Get("Manches", "Rounds") }, Plugin.RoundsMode ? 1 : 0, delegate(int v) { Plugin.RoundsMode = v == 1; if ((Object)(object)_earlyEndRow != (Object)null) { _earlyEndRow.SetActive(Plugin.RoundsMode); } CustomScoringBridge.Update(); Plugin.Log.LogInfo((object)("[TeamMode] Team score → " + (Plugin.RoundsMode ? "Rounds" : "Individual + sum"))); if (NetworkServer.active) { Plugin.Log.LogInfo((object)"[Sync/Host] Score mode changed → broadcasting full state"); TeamSyncManager.BroadcastFullState(); } }); _earlyEndRow = AddToggle(dropdownTemplate, container, Lang.Get("Fin du trou anticipée", "End hole early"), Plugin.EarlyHoleEnd, delegate(bool v) { Plugin.EarlyHoleEnd = v; Plugin.Log.LogInfo((object)("[TeamMode] End hole early → " + (v ? "ON" : "OFF"))); }); _earlyEndRow.SetActive(Plugin.RoundsMode); AddToggle(dropdownTemplate, container, Lang.Get("Tir ami", "Friendly Fire"), Plugin.FriendlyFireEnabled, delegate(bool v) { Plugin.FriendlyFireEnabled = v; Plugin.Log.LogInfo((object)("[FriendlyFire] " + (v ? "ENABLED ✅ — teammates can hurt each other" : "DISABLED ❌ — teammates are protected"))); if (NetworkServer.active) { Plugin.Log.LogInfo((object)"[Sync/Host] FriendlyFire toggled → broadcasting full state"); TeamSyncManager.BroadcastFullState(); } }); } AddSlider(sliderTemplate, container, Lang.Get("Équipes", "Teams"), Plugin.TeamCount, 1, 4, 1, delegate(int v) { Plugin.TeamCount = v; Plugin.Log.LogInfo((object)$"\ud83c\udff7\ufe0f Team count → {v}"); RebuildPlayerDropdowns(); if (NetworkServer.active) { Plugin.Log.LogInfo((object)"[Sync/Host] TeamCount changed → broadcasting full state"); TeamSyncManager.BroadcastFullState(); } }); RebuildPlayerDropdowns(); UpdateSection(); } public static void UpdateSection() { _controls.RemoveAll((Selectable c) => (Object)(object)c == (Object)null); foreach (Selectable control in _controls) { control.interactable = true; } bool enabledSetting = Plugin.EnabledSetting; if ((Object)(object)_header != (Object)null) { _header.SetActive(enabledSetting); } if ((Object)(object)_rules != (Object)null) { _rules.SetActive(enabledSetting); } } public static void RebuildPlayerDropdowns() { if ((Object)(object)_dropdownTemplate == (Object)null || (Object)(object)_container == (Object)null) { return; } for (int num = _container.childCount - 1; num >= 0; num--) { Transform child = _container.GetChild(num); if (((Object)child).name.StartsWith("TM_Player_")) { Object.Destroy((Object)(object)((Component)child).gameObject); } } List<(ulong, string)> connectedPlayers = GetConnectedPlayers(); Plugin.Log.LogInfo((object)$"\ud83d\udc65 {connectedPlayers.Count} player(s) found for Team Mode"); foreach (var item3 in connectedPlayers) { ulong item = item3.Item1; string item2 = item3.Item2; ulong capturedGuid = item; string capturedName = item2; int team = Plugin.GetTeam(item); AddPlayerDropdown(_dropdownTemplate, _container, item2, team, capturedGuid, delegate(int v) { Plugin.PlayerTeams[capturedGuid] = v; Plugin.Log.LogInfo((object)("\ud83d\udc64 " + capturedName + " → Team " + Plugin.TeamNames[v])); if (NetworkServer.active) { Plugin.Log.LogInfo((object)$"[Sync/Host] Assignment changed → broadcasting guid={capturedGuid} team={Plugin.TeamNames[v]}"); TeamSyncManager.BroadcastAssignment(capturedGuid, v); } }); } UpdateSection(); } public static List<(ulong guid, string name)> GetConnectedPlayers() { List<(ulong, string)> list = new List<(ulong, string)>(); try { Type type = AccessTools.TypeByName("GameManager"); object obj = type?.GetProperty("LocalPlayerInfo", BindingFlags.Static | BindingFlags.Public | BindingFlags.FlattenHierarchy)?.GetValue(null); if (obj != null) { object obj2 = obj.GetType().GetProperty("PlayerId", BindingFlags.Instance | BindingFlags.Public)?.GetValue(obj); if (obj2 != null) { ulong item = (ulong)(obj2.GetType().GetProperty("Guid", BindingFlags.Instance | BindingFlags.Public)?.GetValue(obj2) ?? ((object)0uL)); string item2 = (string)(obj2.GetType().GetProperty("PlayerName", BindingFlags.Instance | BindingFlags.Public)?.GetValue(obj2) ?? "Local"); list.Add((item, item2)); } } object obj3 = type?.GetProperty("RemotePlayerPerConnectionId", BindingFlags.Static | BindingFlags.Public | BindingFlags.FlattenHierarchy)?.GetValue(null); if (obj3 != null) { object obj4 = obj3.GetType().GetProperty("Values")?.GetValue(obj3); if (obj4 is IEnumerable enumerable) { foreach (object item5 in enumerable) { object obj5 = item5.GetType().GetProperty("PlayerId", BindingFlags.Instance | BindingFlags.Public)?.GetValue(item5); if (obj5 != null) { ulong item3 = (ulong)(obj5.GetType().GetProperty("Guid", BindingFlags.Instance | BindingFlags.Public)?.GetValue(obj5) ?? ((object)0uL)); string item4 = (string)(obj5.GetType().GetProperty("PlayerName", BindingFlags.Instance | BindingFlags.Public)?.GetValue(obj5) ?? "Remote"); list.Add((item3, item4)); } } } } } catch (Exception ex) { Plugin.Log.LogError((object)("GetConnectedPlayers: " + ex.Message)); } return list; } private static void FullOpacity(GameObject row) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown