using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Mirror;
using TMPro;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.UI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("SBG_Teams")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+32ef81f0f533046f0a86bb7579ad5dc270254836")]
[assembly: AssemblyProduct("SBG Teams Mod")]
[assembly: AssemblyTitle("SBG_Teams")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace SBGTeams
{
internal class CallRPC : NetworkBehaviour
{
private struct RpcCallMessage : NetworkMessage
{
public string actionId;
}
private struct RpcCallMessageWithParam : NetworkMessage
{
public string actionId;
public string param;
}
private struct CmdCallMessage : NetworkMessage
{
public string actionId;
}
private struct CmdCallMessageWithParam : NetworkMessage
{
public string actionId;
public string param;
}
public static CallRPC Instance = null;
private static Dictionary<string, Action> clientActions = new Dictionary<string, Action>();
private static Dictionary<string, Action<string>> clientActionsWithParam = new Dictionary<string, Action<string>>();
private static Dictionary<string, Action> serverActions = new Dictionary<string, Action>();
private static Dictionary<string, Action<string>> serverActionsWithParam = new Dictionary<string, Action<string>>();
private static Dictionary<string, Action<NetworkConnectionToClient, string>> serverActionsWithConn = new Dictionary<string, Action<NetworkConnectionToClient, string>>();
public static Dictionary<ulong, NetworkConnectionToClient> ModdedClients = new Dictionary<ulong, NetworkConnectionToClient>();
public static event Action OnSpawned;
private void Awake()
{
Instance = this;
}
public override void OnStartClient()
{
CallRPC.OnSpawned?.Invoke();
}
public override void OnStartServer()
{
CallRPC.OnSpawned?.Invoke();
}
[Server]
public static void RegisterModdedClient(ulong id, NetworkConnectionToClient conn)
{
ModdedClients[id] = conn;
Plugin.Logger.LogInfo((object)$"Registered modded client: {id}");
}
[Server]
public static void UnregisterModdedClient(ulong id)
{
if (ModdedClients.Remove(id))
{
Plugin.Logger.LogInfo((object)$"Unregistered modded client: {id}");
}
}
[Server]
public static bool IsModdedClient(ulong id)
{
return ModdedClients.ContainsKey(id);
}
[Server]
public static void ClearModdedClients()
{
ModdedClients.Clear();
}
public static void Register()
{
RegisterRpc();
CallRPCHelper.RegisterClass();
}
public static void RegisterClientAction(string id, Action action)
{
clientActions[id] = action;
}
public static void RegisterClientAction(string id, Action<string> action)
{
clientActionsWithParam[id] = action;
}
public static void RegisterServerAction(string id, Action action)
{
serverActions[id] = action;
}
public static void RegisterServerAction(string id, Action<NetworkConnectionToClient, string> action)
{
serverActionsWithConn[id] = action;
}
public static void RegisterServerAction(string id, Action<string> action)
{
serverActionsWithParam[id] = action;
}
private static void RegisterRpc()
{
Writer<RpcCallMessage>.write = delegate(NetworkWriter writer, RpcCallMessage msg)
{
NetworkWriterExtensions.WriteString(writer, msg.actionId);
};
Reader<RpcCallMessage>.read = delegate(NetworkReader reader)
{
RpcCallMessage result4 = default(RpcCallMessage);
result4.actionId = NetworkReaderExtensions.ReadString(reader);
return result4;
};
NetworkClient.RegisterHandler<RpcCallMessage>((Action<RpcCallMessage>)OnReceiveCall, true);
Writer<RpcCallMessageWithParam>.write = delegate(NetworkWriter writer, RpcCallMessageWithParam msg)
{
NetworkWriterExtensions.WriteString(writer, msg.actionId);
NetworkWriterExtensions.WriteString(writer, msg.param);
};
Reader<RpcCallMessageWithParam>.read = delegate(NetworkReader reader)
{
RpcCallMessageWithParam result3 = default(RpcCallMessageWithParam);
result3.actionId = NetworkReaderExtensions.ReadString(reader);
result3.param = NetworkReaderExtensions.ReadString(reader);
return result3;
};
NetworkClient.RegisterHandler<RpcCallMessageWithParam>((Action<RpcCallMessageWithParam>)OnReceiveCallWithParam, true);
Writer<CmdCallMessage>.write = delegate(NetworkWriter writer, CmdCallMessage msg)
{
NetworkWriterExtensions.WriteString(writer, msg.actionId);
};
Reader<CmdCallMessage>.read = delegate(NetworkReader reader)
{
CmdCallMessage result2 = default(CmdCallMessage);
result2.actionId = NetworkReaderExtensions.ReadString(reader);
return result2;
};
NetworkServer.RegisterHandler<CmdCallMessage>((Action<NetworkConnectionToClient, CmdCallMessage>)OnReceiveCommand, true);
Writer<CmdCallMessageWithParam>.write = delegate(NetworkWriter writer, CmdCallMessageWithParam msg)
{
NetworkWriterExtensions.WriteString(writer, msg.actionId);
NetworkWriterExtensions.WriteString(writer, msg.param);
};
Reader<CmdCallMessageWithParam>.read = delegate(NetworkReader reader)
{
CmdCallMessageWithParam result = default(CmdCallMessageWithParam);
result.actionId = NetworkReaderExtensions.ReadString(reader);
result.param = NetworkReaderExtensions.ReadString(reader);
return result;
};
NetworkServer.RegisterHandler<CmdCallMessageWithParam>((Action<NetworkConnectionToClient, CmdCallMessageWithParam>)OnReceiveCommandWithParam, true);
}
[Server]
public void RpcCallToModdedClients(string actionId)
{
RpcCallMessage rpcCallMessage = default(RpcCallMessage);
rpcCallMessage.actionId = actionId;
RpcCallMessage rpcCallMessage2 = rpcCallMessage;
foreach (NetworkConnectionToClient value in ModdedClients.Values)
{
if (value != null && ((NetworkConnection)value).isReady)
{
((NetworkConnection)value).Send<RpcCallMessage>(rpcCallMessage2, 0);
}
}
}
[Server]
public void RpcCallToModdedClients(string actionId, string param)
{
RpcCallMessageWithParam rpcCallMessageWithParam = default(RpcCallMessageWithParam);
rpcCallMessageWithParam.actionId = actionId;
rpcCallMessageWithParam.param = param;
RpcCallMessageWithParam rpcCallMessageWithParam2 = rpcCallMessageWithParam;
foreach (NetworkConnectionToClient value in ModdedClients.Values)
{
if (value != null && ((NetworkConnection)value).isReady)
{
((NetworkConnection)value).Send<RpcCallMessageWithParam>(rpcCallMessageWithParam2, 0);
}
}
}
[Server]
public void RpcCallToClients(string actionId, IEnumerable<NetworkConnectionToClient> targets)
{
RpcCallMessage rpcCallMessage = default(RpcCallMessage);
rpcCallMessage.actionId = actionId;
RpcCallMessage rpcCallMessage2 = rpcCallMessage;
foreach (NetworkConnectionToClient target in targets)
{
if (target != null && ((NetworkConnection)target).isReady)
{
((NetworkConnection)target).Send<RpcCallMessage>(rpcCallMessage2, 0);
}
}
}
[Server]
public void RpcCallToClients(string actionId, string param, IEnumerable<NetworkConnectionToClient> targets)
{
RpcCallMessageWithParam rpcCallMessageWithParam = default(RpcCallMessageWithParam);
rpcCallMessageWithParam.actionId = actionId;
rpcCallMessageWithParam.param = param;
RpcCallMessageWithParam rpcCallMessageWithParam2 = rpcCallMessageWithParam;
foreach (NetworkConnectionToClient target in targets)
{
if (target != null && ((NetworkConnection)target).isReady)
{
((NetworkConnection)target).Send<RpcCallMessageWithParam>(rpcCallMessageWithParam2, 0);
}
}
}
[Server]
public void RpcCallToClient(string actionId, NetworkConnectionToClient target)
{
if (target != null && ((NetworkConnection)target).isReady)
{
((NetworkConnection)target).Send<RpcCallMessage>(new RpcCallMessage
{
actionId = actionId
}, 0);
}
}
[Server]
public void RpcCallToClient(string actionId, string param, NetworkConnectionToClient target)
{
if (target != null && ((NetworkConnection)target).isReady)
{
((NetworkConnection)target).Send<RpcCallMessageWithParam>(new RpcCallMessageWithParam
{
actionId = actionId,
param = param
}, 0);
}
}
private static void OnReceiveCall(RpcCallMessage msg)
{
if (clientActions.TryGetValue(msg.actionId, out var value))
{
value();
}
else
{
Debug.LogWarning((object)("No action registered for id: " + msg.actionId));
}
}
private static void OnReceiveCallWithParam(RpcCallMessageWithParam msg)
{
if (clientActionsWithParam.TryGetValue(msg.actionId, out var value))
{
value(msg.param);
}
else
{
Debug.LogWarning((object)("No parameterized action registered for id: " + msg.actionId));
}
}
public void CmdCallToServer(string actionId)
{
CmdCallMessage cmdCallMessage = default(CmdCallMessage);
cmdCallMessage.actionId = actionId;
NetworkClient.Send<CmdCallMessage>(cmdCallMessage, 0);
}
public void CmdCallToServer(string actionId, string param)
{
CmdCallMessageWithParam cmdCallMessageWithParam = default(CmdCallMessageWithParam);
cmdCallMessageWithParam.actionId = actionId;
cmdCallMessageWithParam.param = param;
NetworkClient.Send<CmdCallMessageWithParam>(cmdCallMessageWithParam, 0);
}
private static void OnReceiveCommand(NetworkConnectionToClient conn, CmdCallMessage msg)
{
if (serverActions.TryGetValue(msg.actionId, out var value))
{
value();
}
else
{
Debug.LogWarning((object)("No server action registered for id: " + msg.actionId));
}
}
private static void OnReceiveCommandWithParam(NetworkConnectionToClient conn, CmdCallMessageWithParam msg)
{
Action<string> value2;
if (serverActionsWithConn.TryGetValue(msg.actionId, out var value))
{
value(conn, msg.param);
}
else if (serverActionsWithParam.TryGetValue(msg.actionId, out value2))
{
value2(msg.param);
}
else
{
Debug.LogWarning((object)("No server action registered for id: " + msg.actionId));
}
}
}
internal class CallRPCHelper
{
[HarmonyPatch(typeof(BNetworkManager), "OnStartServer")]
public class ServerStartNetworkManagerPatch
{
private static void Postfix(BNetworkManager __instance)
{
Plugin.Logger.LogInfo((object)"starting as server");
JoinSetup();
}
}
[HarmonyPatch(typeof(BNetworkManager), "OnStartClient")]
public class ClientStartNetworkManagerPatch
{
private static void Postfix(BNetworkManager __instance)
{
if (!NetworkServer.active)
{
Plugin.Logger.LogInfo((object)"starting as client");
JoinSetup();
}
}
}
[CompilerGenerated]
private static class <>O
{
public static SpawnHandlerDelegate <0>__SpawnCallRpc;
public static UnSpawnDelegate <1>__UnspawnCallRpc;
public static Action <2>__OnCallRPCReady;
}
[CompilerGenerated]
private sealed class <DelayedHandshake>d__4 : IEnumerator<object>, IDisposable, IEnumerator
{
private int <>1__state;
private object <>2__current;
private ulong <localId>5__1;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <DelayedHandshake>d__4(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<>1__state = -2;
}
private bool MoveNext()
{
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
break;
case 1:
<>1__state = -1;
break;
}
if (!Object.op_Implicit((Object)(object)GameManager.LocalPlayerId))
{
<>2__current = null;
<>1__state = 1;
return true;
}
<localId>5__1 = GetLocalPlayerId();
if (NetworkServer.active)
{
CallRPC.RegisterModdedClient(<localId>5__1, (NetworkConnectionToClient)(object)NetworkServer.localConnection);
Plugin.Logger.LogInfo((object)$"Registered host as modded client: {<localId>5__1}");
}
else
{
Plugin.Logger.LogInfo((object)$"Sending mod handshake as: {<localId>5__1}");
CallRPC.Instance.CmdCallToServer("modHandshake", <localId>5__1.ToString());
}
return false;
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
private static readonly uint callRpcUint = 876542u;
public static void RegisterClass()
{
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
//IL_005c: Unknown result type (might be due to invalid IL or missing references)
//IL_0061: Unknown result type (might be due to invalid IL or missing references)
//IL_0067: Expected O, but got Unknown
//IL_0077: 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_0082: Expected O, but got Unknown
if (NetworkServer.active && (Object)(object)CallRPC.Instance == (Object)null)
{
GameObject val = SpawnCallRpc(default(SpawnMessage));
val.SetActive(true);
Object.DontDestroyOnLoad((Object)(object)val);
NetworkServer.Spawn(val, callRpcUint, (NetworkConnectionToClient)null);
}
uint num = callRpcUint;
object obj = <>O.<0>__SpawnCallRpc;
if (obj == null)
{
SpawnHandlerDelegate val2 = SpawnCallRpc;
<>O.<0>__SpawnCallRpc = val2;
obj = (object)val2;
}
object obj2 = <>O.<1>__UnspawnCallRpc;
if (obj2 == null)
{
UnSpawnDelegate val3 = UnspawnCallRpc;
<>O.<1>__UnspawnCallRpc = val3;
obj2 = (object)val3;
}
NetworkClient.RegisterSpawnHandler(num, (SpawnHandlerDelegate)obj, (UnSpawnDelegate)obj2);
CallRPC.RegisterServerAction("modHandshake", delegate(NetworkConnectionToClient conn, string param)
{
ulong num2 = ulong.Parse(param);
CallRPC.RegisterModdedClient(num2, conn);
Plugin.Logger.LogInfo((object)$"Registered modded client: {num2} (conn {conn.connectionId})");
});
}
private static GameObject SpawnCallRpc(SpawnMessage msg)
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Expected O, but got Unknown
GameObject val = new GameObject("callRPCObject");
val.SetActive(false);
NetworkIdentity val2 = val.AddComponent<NetworkIdentity>();
val.AddComponent<CallRPC>();
Object.DontDestroyOnLoad((Object)(object)val);
return val;
}
private static ulong GetLocalPlayerId()
{
if (Object.op_Implicit((Object)(object)GameManager.LocalPlayerId))
{
return GameManager.LocalPlayerInfo.PlayerId.Guid;
}
return 0uL;
}
[IteratorStateMachine(typeof(<DelayedHandshake>d__4))]
private static IEnumerator DelayedHandshake()
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <DelayedHandshake>d__4(0);
}
private static void UnspawnCallRpc(GameObject spawned)
{
Object.Destroy((Object)(object)spawned);
}
private static void JoinSetup()
{
if (!((Object)(object)CallRPC.Instance != (Object)null))
{
CallRPC.Register();
CallRPC.OnSpawned += OnCallRPCReady;
}
}
private static void OnCallRPCReady()
{
((Component)CallRPC.Instance).gameObject.AddComponent<TestUsingCallRPC>();
((MonoBehaviour)CallRPC.Instance).StartCoroutine(DelayedHandshake());
CallRPC.OnSpawned -= OnCallRPCReady;
}
}
[BepInPlugin("SBG_Teams", "SBG Teams Mod", "1.0.0")]
public class Plugin : BaseUnityPlugin
{
internal static ManualLogSource Logger;
private void Awake()
{
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: Expected O, but got Unknown
Logger = ((BaseUnityPlugin)this).Logger;
Harmony val = new Harmony("com.robb.teams");
val.PatchAll();
Logger.LogInfo((object)"Plugin SBG_Teams is loaded!");
}
}
public struct TeamData
{
public string teamName;
public ulong leader;
public List<ulong> members;
public uint ballNetId;
public int maxMembers;
public Color teamColor;
}
[Serializable]
public struct AllTeamsData
{
public TeamData[] teams;
}
public class Team
{
public string name;
private ulong leaderGuid;
private List<ulong> memberGuids;
private GolfBall teamBall;
public Color color;
public int maxMembers;
public ulong LeaderGuid => leaderGuid;
public List<ulong> MemberGuids => memberGuids;
public GolfBall TeamBall => teamBall;
public PlayerGolfer Leader => SteamGuidToPlayerGolfer(leaderGuid);
public List<PlayerGolfer> Members => (from g in memberGuids.Select(SteamGuidToPlayerGolfer)
where (Object)(object)g != (Object)null
select g).ToList();
public Team(string name, int teamSize, Color color)
{
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
this.name = name;
memberGuids = new List<ulong>();
maxMembers = teamSize;
this.color = color;
}
public Team(string name, List<ulong> members, int teamSize, Color color)
{
//IL_0075: Unknown result type (might be due to invalid IL or missing references)
//IL_0077: Unknown result type (might be due to invalid IL or missing references)
this.name = name;
memberGuids = new List<ulong>();
foreach (ulong member in members)
{
memberGuids.Add(member);
}
leaderGuid = memberGuids.FirstOrDefault();
teamBall = null;
maxMembers = teamSize;
this.color = color;
}
public Team(string name, List<PlayerGolfer> members, int teamSize, Color color)
{
//IL_0089: Unknown result type (might be due to invalid IL or missing references)
//IL_008b: Unknown result type (might be due to invalid IL or missing references)
this.name = name;
memberGuids = new List<ulong>();
foreach (PlayerGolfer member in members)
{
memberGuids.Add(member.PlayerInfo.PlayerId.Guid);
}
leaderGuid = memberGuids.FirstOrDefault();
teamBall = FindTeamBall();
maxMembers = teamSize;
this.color = color;
}
public void SetFromData(TeamData data)
{
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
//IL_003d: Unknown result type (might be due to invalid IL or missing references)
name = data.teamName;
leaderGuid = data.leader;
memberGuids = new List<ulong>(data.members);
maxMembers = data.maxMembers;
color = data.teamColor;
if (data.ballNetId != 0 && NetworkClient.spawned.TryGetValue(data.ballNetId, out var value))
{
teamBall = ((Component)value).GetComponent<GolfBall>();
}
else
{
teamBall = null;
}
}
public static ulong PlayerGolferToSteamGuid(PlayerGolfer golfer)
{
return golfer.PlayerInfo.PlayerId.Guid;
}
public static PlayerGolfer SteamGuidToPlayerGolfer(ulong guid)
{
if (!Object.op_Implicit((Object)(object)SingletonBehaviour<GameManager>.Instance))
{
return null;
}
if ((Object)(object)GameManager.LocalPlayerInfo == (Object)null)
{
Plugin.Logger.LogError((object)"SteamGuidToPlayerGolfer: LocalPlayerInfo is null");
return null;
}
if (GameManager.LocalPlayerInfo.PlayerId.Guid == guid)
{
return GameManager.LocalPlayerAsGolfer;
}
PlayerInfo val = default(PlayerInfo);
if (!GameManager.TryFindPlayerByGuid(guid, ref val))
{
return null;
}
return val.AsGolfer;
}
public void AddTeamMember(ulong guid)
{
memberGuids.Add(guid);
SetTeamLeader();
if (!Object.op_Implicit((Object)(object)teamBall))
{
SetTeamBall();
}
}
public void RemoveTeamMember(ulong guid)
{
//IL_003f: Unknown result type (might be due to invalid IL or missing references)
//IL_0044: Unknown result type (might be due to invalid IL or missing references)
memberGuids.Remove(guid);
if (leaderGuid == guid)
{
leaderGuid = 0uL;
return;
}
SetTeamLeader();
teamBall = Leader.ServerSpawnBall(((Component)Leader).transform.position, Quaternion.identity);
Leader.CmdReturnBallToPlayerFromConsole();
}
public void SetTeamLeader()
{
if ((Object)(object)Leader == (Object)null)
{
leaderGuid = memberGuids.FirstOrDefault();
}
}
public void SetTeamBall()
{
DeleteTeamatesBalls();
if (memberGuids.Count != 0)
{
teamBall = FindTeamBall();
}
}
private GolfBall FindTeamBall()
{
if (!Object.op_Implicit((Object)(object)Leader.NetworkownBall))
{
foreach (PlayerGolfer member in Members)
{
if (Object.op_Implicit((Object)(object)member.NetworkownBall))
{
return member.NetworkownBall;
}
}
return null;
}
return Leader.NetworkownBall;
}
public void DeleteTeamatesBalls()
{
if (!Object.op_Implicit((Object)(object)teamBall))
{
return;
}
foreach (PlayerGolfer member in Members)
{
if (!((Object)(object)((Component)member.NetworkownBall).GetComponent<GolfBall>() == (Object)(object)teamBall))
{
NetworkServer.Destroy(((Component)member.NetworkownBall).gameObject);
member.NetworkownBall = teamBall;
}
}
}
}
[HarmonyPatch(typeof(CourseManager), "StartCourse")]
internal static class StartCoursePatch
{
private static void Postfix()
{
if (!Object.op_Implicit((Object)(object)UIManager.Instance))
{
((Component)TeamManager.Instance).gameObject.AddComponent<UIManager>();
}
if (!NetworkServer.active)
{
return;
}
if (Object.op_Implicit((Object)(object)TeamManager.Instance) && (Object)(object)CallRPC.Instance != (Object)null)
{
if (TeamManager.gamemodeActive)
{
TeamManager.Instance.AssignRemainingPlayersToRandomTeam();
TeamManager.Instance.CleanTeams();
TeamManager.Instance.SyncTeamsToClients();
}
}
else
{
Plugin.Logger.LogError((object)$"Not ready - TeamManager: {(Object)(object)TeamManager.Instance != (Object)null}, CallRPC: {(Object)(object)CallRPC.Instance != (Object)null}");
}
}
}
[HarmonyPatch(typeof(CourseManager), "BeginHoleOverviewAndTeeOffCountdown")]
internal static class CourseManagerBeginHolePatch
{
private static void Postfix(CourseManager __instance)
{
if (Object.op_Implicit((Object)(object)UIManager.Instance))
{
UIManager.Instance.SetupGamemodeUI();
UIManager.Instance.UpdatePlayerInfoColors();
}
if (NetworkServer.active && CourseManager.CurrentHoleCourseIndex != -1)
{
if (!Object.op_Implicit((Object)(object)TeamManager.Instance))
{
Plugin.Logger.LogError((object)"CourseManagerBeginHolePatch: no team manager");
}
else if (TeamManager.gamemodeActive)
{
TeamManager.Instance.CleanTeams();
TeamManager.Instance.GetTeamsReadyForHole();
TeamManager.Instance.RPCSendClientsGamemodeData();
}
}
}
}
public struct ChangeTeamData
{
public ulong playerGuid;
public string teamName;
}
public class TeamManager : MonoBehaviour
{
private readonly List<Team> teams = new List<Team>();
public static int teamDefaultMaxSize = 2;
public static TeamManager Instance;
public static bool gamemodeActive = false;
public List<Team> Teams => teams;
private void Awake()
{
//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
//IL_0118: Unknown result type (might be due to invalid IL or missing references)
Instance = this;
gamemodeActive = false;
TeamMemberManager.Initialize();
CallRPC.RegisterClientAction("SyncTeamData", OnReceiveTeamData);
CallRPC.RegisterClientAction("OnReceiveClientGamemodeActive", OnReceiveClientGamemodeActive);
CallRPC.RegisterServerAction("OnClientRequestedTeamData", OnClientRequestedTeamData);
CallRPC.RegisterServerAction("OnClientRequestedGamemodeData", OnClientRequestedGamemodeData);
CallRPC.RegisterServerAction("HandleClientRequestedChangeTeam", HandleClientRequestedChangeTeam);
if (!NetworkServer.active)
{
RequestTeamDataFromServer();
RequestGamemodeDataFromServer();
}
else
{
Instance.Teams.Add(new Team("Black", 2, Color.black));
Instance.Teams.Add(new Team("Green", 2, Color.green));
Instance.Teams.Add(new Team("Blue", 2, Color.blue));
Instance.Teams.Add(new Team("Red", 2, Color.red));
}
if (!Object.op_Implicit((Object)(object)UIManager.Instance))
{
((Component)Instance).gameObject.AddComponent<UIManager>();
}
}
public string SerializeTeams()
{
//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
List<string> list = new List<string>();
foreach (Team team in teams)
{
string name = team.name;
string text = team.LeaderGuid.ToString();
string text2 = string.Join(",", team.MemberGuids.Select((ulong g) => g.ToString()));
string text3 = (((Object)(object)team.TeamBall != (Object)null) ? ((NetworkBehaviour)team.TeamBall).netId.ToString() : "0");
string text4 = team.maxMembers.ToString();
string text5 = ColorUtility.ToHtmlStringRGB(team.color);
list.Add(text + ":" + text2 + ":" + text3 + ":" + text4 + ":" + name + ":" + text5);
}
return string.Join(";", list);
}
private void OnReceiveTeamData(string data)
{
//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
if (NetworkServer.active || string.IsNullOrEmpty(data))
{
return;
}
teams.Clear();
string[] array = data.Split(new char[1] { ';' });
string[] array2 = array;
Color val = default(Color);
foreach (string text in array2)
{
if (string.IsNullOrEmpty(text))
{
continue;
}
string[] array3 = text.Split(new char[1] { ':' });
ulong result = 0uL;
if (!string.IsNullOrEmpty(array3[0]))
{
ulong.TryParse(array3[0], out result);
}
List<ulong> members = new List<ulong>();
if (!string.IsNullOrEmpty(array3[1]))
{
members = (from s in array3[1].Split(new char[1] { ',' })
where !string.IsNullOrEmpty(s)
select ulong.Parse(s)).ToList();
}
uint.TryParse(array3[2], out var result2);
int.TryParse(array3[3], out var result3);
string text2 = array3[4];
string text3 = "#" + array3[5];
if (!ColorUtility.TryParseHtmlString(text3, ref val))
{
Plugin.Logger.LogError((object)("Couldn't parse color from: " + array3[5]));
((Color)(ref val))..ctor(Random.value, Random.value, Random.value);
}
TeamData teamData = default(TeamData);
teamData.teamName = text2;
teamData.leader = result;
teamData.members = members;
teamData.ballNetId = result2;
teamData.maxMembers = result3;
teamData.teamColor = val;
TeamData fromData = teamData;
Team team = new Team(text2, result3, val);
team.SetFromData(fromData);
teams.Add(team);
}
}
public string SerializeChangeTeams(ulong guid, string teamName)
{
return $"{guid}:{teamName}";
}
private void HandleClientRequestedChangeTeam(string data)
{
if (NetworkServer.active && !string.IsNullOrEmpty(data))
{
string[] array = data.Split(new char[1] { ':' });
ulong playerGuid = ulong.Parse(array[0]);
string teamName = array[1];
ChangeTeamData changeTeamData = default(ChangeTeamData);
changeTeamData.playerGuid = playerGuid;
changeTeamData.teamName = teamName;
ChangeTeamData changeTeamData2 = changeTeamData;
ChangePlayerTeam(changeTeamData2.playerGuid, changeTeamData2.teamName);
SyncTeamsToClients();
}
}
private void OnClientRequestedTeamData()
{
Instance.CleanTeams();
SyncTeamsToClients();
}
private void OnClientRequestedGamemodeData()
{
SendClientsGamemodeData();
}
private void SendClientsGamemodeData()
{
CallRPC.Instance.RpcCallToModdedClients("OnReceiveClientGamemodeActive", gamemodeActive.ToString());
}
public void RPCSendClientsGamemodeData()
{
SendClientsGamemodeData();
}
public void RequestGamemodeDataFromServer()
{
if ((Object)(object)CallRPC.Instance != (Object)null)
{
CallRPC.Instance.CmdCallToServer("OnClientRequestedGamemodeData");
}
}
public void RequestTeamDataFromServer()
{
if ((Object)(object)CallRPC.Instance != (Object)null)
{
CallRPC.Instance.CmdCallToServer("OnClientRequestedTeamData");
}
}
private void OnReceiveClientGamemodeActive(string value)
{
if (!NetworkServer.active)
{
bool flag = (gamemodeActive = ((value == "True") ? true : false));
if (Object.op_Implicit((Object)(object)UIManager.Instance))
{
Plugin.Logger.LogInfo((object)"UI manager instance exists");
UIManager.Instance.UpdateGamemodeUI(flag);
UIManager.Instance.ToggleHideReorderableLists(flag);
}
else
{
Plugin.Logger.LogError((object)"UI manager instance does not exist");
}
}
}
public void SyncTeamsToClients()
{
if (!NetworkServer.active)
{
return;
}
if ((Object)(object)CallRPC.Instance == (Object)null)
{
Plugin.Logger.LogError((object)"SyncTeamsToClients: CallRPC.Instance is null!");
return;
}
string text = SerializeTeams();
if (text == null)
{
Plugin.Logger.LogError((object)"SyncTeamsToClients: json is null!");
return;
}
CallRPC.Instance.RpcCallToModdedClients("SyncTeamData", text);
Plugin.Logger.LogInfo((object)("SyncTeamsToClients: sent successfully " + text));
}
private void CMDRequestChangeTeam(string ChangeTeamData)
{
CallRPC.Instance.CmdCallToServer("HandleClientRequestedChangeTeam", ChangeTeamData);
}
public void CMDRequestChangeTeam(ulong guid, string teamName)
{
string changeTeamData = SerializeChangeTeams(guid, teamName);
CMDRequestChangeTeam(changeTeamData);
}
public void AssignRemainingPlayersToRandomTeam()
{
//IL_00f7: 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_00fe: Unknown result type (might be due to invalid IL or missing references)
Dictionary<ulong, int> connectionIdPerPlayerGuid = BNetworkManager.singleton.connectionIdPerPlayerGuid;
List<ulong> list = new List<ulong>(connectionIdPerPlayerGuid.Keys);
List<PlayerState> list2 = new List<PlayerState>();
CourseManager.GetConnectedPlayerStates(list2);
IEnumerable<ulong> source = list2.Select((PlayerState state) => state.playerGuid);
foreach (ulong guid in list)
{
if (GetPlayerTeam(guid) != null)
{
continue;
}
if (!CallRPC.IsModdedClient(guid))
{
if (!CourseManager.IsPlayerSpectator(Team.SteamGuidToPlayerGolfer(guid)))
{
CourseManager.SetPlayerSpectator(Team.SteamGuidToPlayerGolfer(guid), true);
}
}
else if (source.Contains(guid))
{
PlayerState val = list2.Find((PlayerState state) => state.playerGuid == guid);
if (!val.isSpectator)
{
AddPlayerToAvailableTeam(guid);
}
}
}
}
public void MakeRandomTeams(int teamSize)
{
//IL_0117: Unknown result type (might be due to invalid IL or missing references)
if (!NetworkServer.active)
{
return;
}
Dictionary<ulong, int> connectionIdPerPlayerGuid = BNetworkManager.singleton.connectionIdPerPlayerGuid;
List<ulong> list = new List<ulong>(connectionIdPerPlayerGuid.Keys);
int num = (int)Math.Ceiling((float)connectionIdPerPlayerGuid.Count / (float)teamSize);
teams.Clear();
for (int i = 0; i < num; i++)
{
List<PlayerGolfer> list2 = new List<PlayerGolfer>();
int num2 = i * teamSize;
int num3 = Math.Min(num2 + teamSize, list.Count);
for (int j = num2; j < num3; j++)
{
ulong guid = list[j];
PlayerGolfer val = Team.SteamGuidToPlayerGolfer(guid);
if ((Object)(object)val != (Object)null)
{
list2.Add(val);
}
}
if (list2.Count > 0)
{
Plugin.Logger.LogInfo((object)$"MakeTeams: creating team {i} with {list2.Count} members");
Team item = new Team($"Team {i + 1}", list2, teamDefaultMaxSize, new Color(Random.value, Random.value, Random.value));
teams.Add(item);
}
}
SyncTeamsToClients();
}
public void GetTeamsReadyForHole()
{
if (!NetworkServer.active)
{
return;
}
foreach (Team team in teams)
{
team.SetTeamLeader();
team.SetTeamBall();
}
SyncTeamsToClients();
TeamMemberManager.SpawnPlayerTags();
}
public void ChangePlayerTeam(ulong guid, string teamName)
{
if (GetPlayerTeam(guid) != null)
{
if (GetPlayerTeam(guid).name == teamName)
{
return;
}
RemovePlayerFromTeam(guid);
}
Team teamByTeamName = GetTeamByTeamName(teamName);
teamByTeamName.AddTeamMember(guid);
CleanTeams();
}
public void CleanTeams()
{
foreach (Team team in teams)
{
if ((Object)(object)team.Leader == (Object)null)
{
team.SetTeamLeader();
}
team.SetTeamBall();
}
}
public bool BallBelongsToPlayer(PlayerGolfer player, GolfBall ball)
{
foreach (Team team in teams)
{
if (team.Members.Contains(player))
{
return (Object)(object)team.TeamBall == (Object)(object)ball;
}
}
return false;
}
public Team GetPlayerTeam(ulong member)
{
foreach (Team team in teams)
{
if (team.MemberGuids.Contains(member))
{
return team;
}
}
return null;
}
public Team GetPlayerTeam(PlayerGolfer member)
{
return GetPlayerTeam(member.PlayerInfo.PlayerId.Guid);
}
public Team GetTeamByTeamName(string name)
{
foreach (Team team in teams)
{
if (team.name == name)
{
return team;
}
}
return null;
}
public GolfBall GetPlayerTeamBall(PlayerGolfer player)
{
return GetPlayerTeam(player)?.TeamBall;
}
public static List<T> ShuffleList<T>(List<T> list)
{
for (int num = list.Count - 1; num > 0; num--)
{
int index = Random.Range(0, num + 1);
T value = list[num];
list[num] = list[index];
list[index] = value;
}
return list;
}
public void AddPlayerToAvailableTeam(ulong player)
{
//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
int num = 0;
foreach (Team item2 in ShuffleList(teams))
{
num = item2.maxMembers;
if (item2.Members.Count < item2.maxMembers)
{
item2.AddTeamMember(player);
return;
}
}
Plugin.Logger.LogInfo((object)"couldn't find team, making one");
List<ulong> list = new List<ulong>();
list.Add(player);
Team item = new Team($"{player % 1000}'s team", list, teamDefaultMaxSize, new Color(Random.value, Random.value, Random.value));
teams.Add(item);
}
public void RemovePlayerFromTeam(ulong player)
{
GetPlayerTeam(player)?.RemoveTeamMember(player);
}
private void LogTeams()
{
int num = 0;
foreach (Team team in teams)
{
num++;
PlayerGolfer leader = team.Leader;
Plugin.Logger.LogInfo((object)string.Format("LogTeams: Team {0} - Leader: {1}", num, ((Object)(object)leader != (Object)null) ? ((Object)leader).name : "not resolved yet"));
foreach (ulong memberGuid in team.MemberGuids)
{
PlayerGolfer val = Team.SteamGuidToPlayerGolfer(memberGuid);
Plugin.Logger.LogInfo((object)$"LogTeams: {(((Object)(object)val != (Object)null) ? ((Object)val).name : memberGuid.ToString())} on team {num}");
}
}
}
}
[HarmonyPatch(typeof(CourseManager), "RegisterMatchParticipant")]
internal static class RegisterPlayerPatch
{
private static bool Prefix(CourseManager __instance, PlayerGolfer participant)
{
if (!Object.op_Implicit((Object)(object)TeamManager.Instance))
{
return true;
}
if (!TeamManager.gamemodeActive)
{
return true;
}
if (TeamManager.Instance.GetPlayerTeam(participant) == null)
{
CourseManager.SetPlayerSpectator(participant, true);
return false;
}
return true;
}
}
[HarmonyPatch(typeof(CourseManager), "DeregisterPlayer")]
internal static class DeregisterPlayerPatch
{
private static void Prefix(CourseManager __instance, NetworkConnectionToClient connection)
{
if (Object.op_Implicit((Object)(object)TeamManager.Instance) && TeamManager.gamemodeActive)
{
ulong player = default(ulong);
if (!BNetworkManager.singleton.ServerTryGetPlayerGuidFromConnection(connection, ref player))
{
Debug.LogError((object)$"Failed to get player GUID for connecion {connection.connectionId} while registering them", (Object)(object)((Component)__instance).gameObject);
return;
}
TeamManager.Instance.RemovePlayerFromTeam(player);
TeamManager.Instance.SyncTeamsToClients();
}
}
}
internal class TeamManagerObjectSetupHelper
{
[HarmonyPatch(typeof(BNetworkManager), "OnStartServer")]
public class ServerStartNetworkManagerPatch
{
private static void Postfix(BNetworkManager __instance)
{
if (NetworkServer.active)
{
Plugin.Logger.LogInfo((object)"server creating team manager");
RegisterClass();
}
}
}
[HarmonyPatch(typeof(BNetworkManager), "OnStartClient")]
public class ClientStartNetworkManagerPatch
{
private static void Postfix(BNetworkManager __instance)
{
if (!NetworkServer.active)
{
Plugin.Logger.LogInfo((object)"client creating team manager");
RegisterClass();
}
}
}
[CompilerGenerated]
private static class <>O
{
public static SpawnHandlerDelegate <0>__SpawnTeamManager;
public static UnSpawnDelegate <1>__UnspawnTeamManager;
}
private static readonly uint teamManagerUint = 876532u;
public static void RegisterClass()
{
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
//IL_005c: Unknown result type (might be due to invalid IL or missing references)
//IL_0061: Unknown result type (might be due to invalid IL or missing references)
//IL_0067: Expected O, but got Unknown
//IL_0077: 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_0082: Expected O, but got Unknown
if (NetworkServer.active && (Object)(object)TeamManager.Instance == (Object)null)
{
GameObject val = SpawnTeamManager(default(SpawnMessage));
val.SetActive(true);
Object.DontDestroyOnLoad((Object)(object)val);
NetworkServer.Spawn(val, teamManagerUint, (NetworkConnectionToClient)null);
}
uint num = teamManagerUint;
object obj = <>O.<0>__SpawnTeamManager;
if (obj == null)
{
SpawnHandlerDelegate val2 = SpawnTeamManager;
<>O.<0>__SpawnTeamManager = val2;
obj = (object)val2;
}
object obj2 = <>O.<1>__UnspawnTeamManager;
if (obj2 == null)
{
UnSpawnDelegate val3 = UnspawnTeamManager;
<>O.<1>__UnspawnTeamManager = val3;
obj2 = (object)val3;
}
NetworkClient.RegisterSpawnHandler(num, (SpawnHandlerDelegate)obj, (UnSpawnDelegate)obj2);
}
private static GameObject SpawnTeamManager(SpawnMessage msg)
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Expected O, but got Unknown
GameObject val = new GameObject("teamManagerObject");
val.SetActive(false);
NetworkIdentity val2 = val.AddComponent<NetworkIdentity>();
val.AddComponent<TeamManager>();
Object.DontDestroyOnLoad((Object)(object)val);
return val;
}
private static void UnspawnTeamManager(GameObject spawned)
{
Object.Destroy((Object)(object)spawned);
}
}
public static class TeamMemberManager
{
public static void Initialize()
{
CallRPC.RegisterClientAction("SpawnTeamBallIcon", SpawnTeamBallIcon);
CallRPC.RegisterClientAction("UpdateBallNameTag", UpdateBallNameTag);
}
public static void AddStrokesToTeam(PlayerGolfer hitter, bool suppressPopup)
{
Team playerTeam = TeamManager.Instance.GetPlayerTeam(hitter);
foreach (PlayerGolfer member in playerTeam.Members)
{
if (!((Object)(object)hitter == (Object)(object)member))
{
CourseManager.AddPenaltyStroke(member, suppressPopup);
}
}
}
public static void SpawnPlayerTags()
{
CallRPC.Instance.RpcCallToModdedClients("SpawnTeamBallIcon");
CallRPC.Instance.RpcCallToModdedClients("UpdateBallNameTag");
}
private static void SpawnTeamBallIcon()
{
PlayerGolfer component = ((Component)((Component)GameManager.LocalPlayerAsGolfer).transform).GetComponent<PlayerGolfer>();
GolfBall playerTeamBall = TeamManager.Instance.GetPlayerTeamBall(component);
WorldspaceIconUi unusedIcon = WorldspaceIconManager.GetUnusedIcon();
WorldspaceIconUiSettings ballIconSettings = WorldspaceIconManager.BallIconSettings;
unusedIcon.Initialize(ballIconSettings, ((Component)playerTeamBall).transform, ((Component)component).transform, WorldspaceIconManager.BallIcon);
}
private static void UpdateBallNameTag()
{
foreach (Team team in TeamManager.Instance.Teams)
{
}
}
}
[HarmonyPatch(typeof(PlayerGolfer), "CanHitCollider")]
public class CanHitColliderPatch
{
private static bool Prefix(PlayerGolfer __instance, ref bool __result, Collider collider, out Hittable hittable)
{
if (!ComponentExtensions.TryGetComponentInParent<Hittable>((Component)(object)collider, ref hittable, false))
{
return true;
}
if (!Object.op_Implicit((Object)(object)TeamManager.Instance))
{
return true;
}
if (!TeamManager.gamemodeActive)
{
return true;
}
if (TeamManager.Instance.GetPlayerTeam(__instance.PlayerInfo.PlayerId.Guid) == null)
{
return true;
}
if (MatchSetupRules.GetValueAsBool((Rule)10))
{
return true;
}
if (hittable.AsEntity.IsGolfBall)
{
__result = TeamManager.Instance.BallBelongsToPlayer(__instance, hittable.AsEntity.AsGolfBall);
return false;
}
return true;
}
}
[HarmonyPatch(typeof(Hittable), "IsHittableBySwing")]
public class IsHittableBySwingPatch
{
private static bool Prefix(Hittable __instance, ref bool __result, PlayerGolfer hitter)
{
if (!Object.op_Implicit((Object)(object)TeamManager.Instance))
{
return true;
}
if (!TeamManager.gamemodeActive)
{
return true;
}
if (TeamManager.Instance.GetPlayerTeam(hitter.PlayerInfo.PlayerId.Guid) == null)
{
return true;
}
if (MatchSetupRules.GetValueAsBool((Rule)10))
{
return true;
}
if (__instance.AsEntity.IsGolfBall)
{
__result = TeamManager.Instance.BallBelongsToPlayer(hitter, __instance.AsEntity.AsGolfBall);
return false;
}
return true;
}
}
[HarmonyPatch(typeof(GolfBall), "UpdateNotAllowedVisuals")]
public class PatchUpdateNotAllowedVisuals
{
private static FieldInfo isDisplayingField = typeof(GolfBall).GetField("isDisplayingNotAllowedVisuals", BindingFlags.Instance | BindingFlags.NonPublic);
private static FieldInfo meshRenderersField = typeof(GolfBall).GetField("meshRenderers", BindingFlags.Instance | BindingFlags.NonPublic);
private static FieldInfo originalMaterialsField = typeof(GolfBall).GetField("meshRendererOriginalMaterials", BindingFlags.Instance | BindingFlags.NonPublic);
private static void Postfix(GolfBall __instance)
{
if (!Object.op_Implicit((Object)(object)TeamManager.Instance) || !TeamManager.gamemodeActive)
{
return;
}
PlayerGolfer component = ((Component)((Component)GameManager.LocalPlayerAsGolfer).transform).GetComponent<PlayerGolfer>();
Team playerTeam = TeamManager.Instance.GetPlayerTeam(component.PlayerInfo.PlayerId.Guid);
if (playerTeam == null || (Object)(object)playerTeam.TeamBall != (Object)(object)__instance)
{
return;
}
isDisplayingField.SetValue(__instance, false);
List<MeshRenderer> list = (List<MeshRenderer>)meshRenderersField.GetValue(__instance);
List<Material> list2 = (List<Material>)originalMaterialsField.GetValue(__instance);
for (int i = 0; i < list.Count; i++)
{
if ((Object)(object)list[i] != (Object)null)
{
((Renderer)list[i]).sharedMaterial = list2[i];
}
}
}
}
[HarmonyPatch(typeof(Hittable), "HitWithGolfSwing")]
public static class HitWithGolfSwingPatch
{
private static void Postfix(Hittable __instance, PlayerGolfer hitter)
{
if (Object.op_Implicit((Object)(object)TeamManager.Instance) && TeamManager.gamemodeActive && TeamManager.Instance.GetPlayerTeam(hitter) != null && __instance.AsEntity.IsGolfBall && !((Object)(object)__instance.AsEntity.AsGolfBall == (Object)(object)hitter.NetworkownBall) && !((Object)(object)__instance.AsEntity.AsGolfBall != (Object)(object)TeamManager.Instance.GetPlayerTeamBall(hitter)))
{
HoleProgressBarUi.IncrementStrokes();
MethodInfo method = typeof(PlayerGolfer).GetMethod("OnPlayerHitOwnBall", BindingFlags.Instance | BindingFlags.NonPublic);
method.Invoke(hitter, null);
if (!((NetworkBehaviour)hitter).isServer)
{
MethodInfo method2 = typeof(PlayerGolfer).GetMethod("CmdInformHitOwnBall", BindingFlags.Instance | BindingFlags.NonPublic);
method2.Invoke(hitter, null);
}
}
}
}
[HarmonyPatch(typeof(CourseManager), "OnServerPlayerHitOwnBall")]
public static class OnServerPlayerHitOwnBallPatch
{
private static void Postfix(CourseManager __instance, PlayerGolfer hitter)
{
if (Object.op_Implicit((Object)(object)TeamManager.Instance) && TeamManager.gamemodeActive && TeamManager.Instance.GetPlayerTeam(hitter) != null)
{
TeamMemberManager.AddStrokesToTeam(hitter, suppressPopup: false);
}
}
}
[HarmonyPatch(typeof(GolfBall), "ServerReturnToBounds")]
public static class ServerReturnToBoundsPatch
{
private static void Postfix(GolfBall __instance)
{
if (Object.op_Implicit((Object)(object)TeamManager.Instance) && TeamManager.gamemodeActive)
{
PlayerGolfer networkowner = __instance.Networkowner;
if (TeamManager.Instance.GetPlayerTeam(networkowner) != null)
{
TeamMemberManager.AddStrokesToTeam(networkowner, suppressPopup: true);
}
}
}
}
[HarmonyPatch(typeof(GolfBall), "OnEnteredHole")]
public static class EnteredHolePatch
{
private static void Postfix(GolfBall __instance, GolfHole hole)
{
if (!Object.op_Implicit((Object)(object)TeamManager.Instance) || !TeamManager.gamemodeActive)
{
return;
}
PlayerGolfer networkowner = __instance.Networkowner;
if (TeamManager.Instance.GetPlayerTeam(networkowner) == null)
{
return;
}
Team playerTeam = TeamManager.Instance.GetPlayerTeam(networkowner);
foreach (PlayerGolfer member in playerTeam.Members)
{
if (!((Object)(object)networkowner == (Object)(object)member))
{
member.InformScored(hole);
}
}
}
}
[HarmonyPatch(typeof(CourseManager), "InformPlayerScoredInternal")]
public static class InformPlayerScoredPatch
{
private static FieldInfo matchScoredPlayersField = typeof(CourseManager).GetField("matchScoredPlayers", BindingFlags.Instance | BindingFlags.NonPublic);
private static void Prefix(CourseManager __instance, PlayerGolfer playerAsGolfer, GolfHole hole)
{
if (!Object.op_Implicit((Object)(object)TeamManager.Instance) || !TeamManager.gamemodeActive || TeamManager.Instance.GetPlayerTeam(playerAsGolfer) == null)
{
return;
}
Team playerTeam = TeamManager.Instance.GetPlayerTeam(playerAsGolfer);
List<PlayerGolfer> list = (List<PlayerGolfer>)matchScoredPlayersField.GetValue(SingletonNetworkBehaviour<CourseManager>.Instance);
for (int i = 0; i < playerTeam.Members.Count; i++)
{
PlayerGolfer item = playerTeam.Members[i];
if (list.Contains(item))
{
list.Remove(item);
}
}
}
}
internal class TestUsingCallRPC : NetworkBehaviour
{
private void Awake()
{
CallRPC.RegisterClientAction("SayHello", SayHello);
}
private void SayHello()
{
Debug.Log((object)("Hello " + ((Object)((Component)GameManager.LocalPlayerAsGolfer).transform).name + "!"));
}
private void RPCSayHello()
{
CallRPC.Instance.RpcCallToModdedClients("SayHello");
}
private void Update()
{
}
}
[HarmonyPatch(typeof(MenuOpenInteraction), "LocalPlayerInteract")]
internal static class LocalPlayerInteract
{
private static void Postfix(MenuOpenInteraction __instance)
{
if (((Object)__instance).name != "Station")
{
return;
}
if (!Object.op_Implicit((Object)(object)UIManager.Instance))
{
((Component)TeamManager.Instance).gameObject.AddComponent<UIManager>();
}
if (Object.op_Implicit((Object)(object)TeamManager.Instance))
{
UIManager.Instance.SetupGamemodeUI();
UIManager.Instance.UpdateGamemodeUI(TeamManager.gamemodeActive);
if (TeamManager.gamemodeActive && NetworkServer.active)
{
UIManager.Instance.UpdateTeamReorderableLists();
UIManager.Instance.ToggleHideReorderableLists(TeamManager.gamemodeActive);
}
}
}
}
[HarmonyPatch(typeof(PauseMenu), "OpenMatchSetup")]
internal static class MatchSetupMenuStartPatch
{
private static void Postfix(PauseMenu __instance)
{
if (!Object.op_Implicit((Object)(object)UIManager.Instance))
{
((Component)TeamManager.Instance).gameObject.AddComponent<UIManager>();
}
if (Object.op_Implicit((Object)(object)TeamManager.Instance))
{
UIManager.Instance.SetupGamemodeUI();
UIManager.Instance.UpdateGamemodeUI(TeamManager.gamemodeActive);
if (TeamManager.gamemodeActive && NetworkServer.active)
{
UIManager.Instance.UpdateTeamReorderableLists();
UIManager.Instance.ToggleHideReorderableLists(TeamManager.gamemodeActive);
}
}
}
}
[HarmonyPatch(typeof(Toggle), "InternalToggle")]
internal static class ControllerSelectableSubmitPatch
{
private static bool Prefix(ControllerSelectable __instance)
{
if (!(((Object)__instance).name == "Item 0: Free-for-all") && !(((Object)__instance).name == "Item 1: Teams"))
{
return true;
}
if (Object.op_Implicit((Object)(object)SingletonBehaviour<GameManager>.Instance) && CourseManager.CurrentHoleCourseIndex == -1)
{
return true;
}
return false;
}
private static void Postfix(ControllerSelectable __instance)
{
if (!NetworkServer.active || !Object.op_Implicit((Object)(object)TeamManager.Instance) || (!(((Object)__instance).name == "Item 0: Free-for-all") && !(((Object)__instance).name == "Item 1: Teams")) || CourseManager.CurrentHoleCourseIndex != -1)
{
return;
}
if (((Object)__instance).name == "Item 0: Free-for-all")
{
TeamManager.gamemodeActive = false;
}
else if (((Object)__instance).name == "Item 1: Teams")
{
if (!Object.op_Implicit((Object)(object)UIManager.Instance))
{
Plugin.Logger.LogError((object)"manager instance not found");
}
TeamManager.gamemodeActive = true;
UIManager.Instance.UpdateTeamReorderableLists();
}
TeamManager.Instance.RPCSendClientsGamemodeData();
UIManager.Instance.ToggleHideReorderableLists(TeamManager.gamemodeActive);
}
}
[HarmonyPatch(typeof(ReorderableListElement), "Update")]
internal class ReorderableListScrollPatch
{
private static void Postfix(ReorderableListElement __instance, bool ___pointerDown)
{
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
if (!___pointerDown)
{
return;
}
float y = ((InputControl<Vector2>)(object)Mouse.current.scroll).ReadValue().y;
if (y != 0f)
{
ReorderableList currentParent = __instance.CurrentParent;
ScrollRect val = ((currentParent != null) ? ((Component)currentParent).GetComponentInParent<ScrollRect>() : null);
if ((Object)(object)val != (Object)null)
{
val.verticalNormalizedPosition += y * 0.1f;
val.verticalNormalizedPosition = Mathf.Clamp01(val.verticalNormalizedPosition);
}
}
}
}
[HarmonyPatch(typeof(Scoreboard), "Refresh")]
internal class ScoreboardRefreshPatch
{
private static void Postfix(Scoreboard __instance)
{
if (Object.op_Implicit((Object)(object)TeamManager.Instance) && Object.op_Implicit((Object)(object)UIManager.Instance) && TeamManager.gamemodeActive)
{
UIManager.Instance.UpdatePlayerInfoColors();
}
}
}
internal class UIManager : MonoBehaviour
{
public static UIManager Instance;
public Dictionary<string, ReorderableList> teamLists = new Dictionary<string, ReorderableList>();
private void Awake()
{
Instance = this;
}
private void Start()
{
SetupGamemodeUI();
UpdateGamemodeUI(TeamManager.gamemodeActive);
}
private TMP_Dropdown getDropdown()
{
MatchSetupMenu val = Object.FindFirstObjectByType<MatchSetupMenu>();
if ((Object)(object)val == (Object)null)
{
Plugin.Logger.LogError((object)"couldn't find menu");
return null;
}
Transform child = ((Component)val).transform.GetChild(0).GetChild(1).GetChild(2)
.GetChild(0)
.GetChild(2)
.GetChild(0)
.GetChild(0)
.GetChild(2)
.GetChild(0);
return ((Component)child).GetComponent<TMP_Dropdown>();
}
private void DestroyOldLists()
{
for (int i = 0; i < teamLists.Count; i++)
{
if (!((Object)(object)teamLists.Values.ElementAt(i) == (Object)null))
{
ReorderableList val = teamLists.Values.ElementAt(i);
Transform child = ((Component)val).transform.parent.GetChild(((Component)val).transform.GetSiblingIndex() - 1);
Object.Destroy((Object)(object)((Component)val).gameObject);
Object.Destroy((Object)(object)((Component)child).gameObject);
}
}
teamLists.Clear();
}
public void MoveTeammatesOnUI()
{
ReorderableList playersList = SingletonNetworkBehaviour<MatchSetupMenu>.Instance.playersList;
ReorderableListElement[] componentsInChildren = ((Component)playersList).GetComponentsInChildren<ReorderableListElement>();
ReorderableListElement[] array = componentsInChildren;
PlayerInfo val2 = default(PlayerInfo);
foreach (ReorderableListElement val in array)
{
if (GameManager.TryFindPlayerByGuid(((Component)val).GetComponent<MatchSetupPlayer>().Guid, ref val2))
{
Team playerTeam = TeamManager.Instance.GetPlayerTeam(val2.PlayerId.Guid);
if (playerTeam == null)
{
Plugin.Logger.LogError((object)"Couldn't find team for player");
continue;
}
ReorderableList val3 = teamLists[playerTeam.name];
val.AssignTo(val3);
}
}
}
public void ToggleHideReorderableLists(bool isActive)
{
foreach (KeyValuePair<string, ReorderableList> teamList in teamLists)
{
if (!((Object)(object)teamList.Value == (Object)null) && !((Object)(object)((Component)teamList.Value).gameObject == (Object)null))
{
Transform child = ((Component)teamList.Value).transform.parent.GetChild(((Component)teamList.Value).transform.GetSiblingIndex() - 1);
((Component)teamList.Value).gameObject.SetActive(isActive);
((Component)child).gameObject.SetActive(isActive);
((TMP_Text)((Component)child).GetComponent<TextMeshProUGUI>()).text = teamList.Key;
}
}
}
public void UpdateTeamReorderableLists()
{
DestroyOldLists();
ReorderableList playersList = SingletonNetworkBehaviour<MatchSetupMenu>.Instance.playersList;
GameObject gameObject = ((Component)((Component)((Component)playersList).transform.parent).GetComponentInChildren<TextMeshProUGUI>()).gameObject;
foreach (Team team in TeamManager.Instance.Teams)
{
CreateTeamLabel(gameObject, playersList, team);
ReorderableList teamUI = CreateTeamList(gameObject, playersList, team);
ChangeListHeightByMemberCount(teamUI, team.MemberGuids.Count);
}
if (TeamManager.gamemodeActive)
{
MoveTeammatesOnUI();
}
}
private ReorderableList CreateTeamList(GameObject UITeamLabel, ReorderableList playerList, Team team)
{
ReorderableList val = Object.Instantiate<ReorderableList>(playerList, ((Component)playerList).transform.parent);
ReorderableListElement[] componentsInChildren = ((Component)((Component)val).transform).GetComponentsInChildren<ReorderableListElement>();
for (int i = 0; i < componentsInChildren.Length; i++)
{
Object.Destroy((Object)(object)((Component)componentsInChildren[i]).gameObject);
}
((Component)val).transform.SetSiblingIndex(3);
((Object)val).name = team.name;
ReorderableList list = ((Component)val).GetComponent<ReorderableList>();
teamLists[team.name] = list;
list.OnElementMoved += delegate(ReorderableListElement element)
{
HandlePlayerMoved(list, element);
};
return val;
}
private void CreateTeamLabel(GameObject UITeamLabel, ReorderableList playerList, Team team)
{
//IL_0034: Unknown result type (might be due to invalid IL or missing references)
GameObject val = Object.Instantiate<GameObject>(UITeamLabel, ((Component)playerList).transform.parent);
((Object)val).name = team.name;
val.transform.SetSiblingIndex(2);
((Graphic)val.GetComponent<TextMeshProUGUI>()).color = team.color;
((TMP_Text)val.GetComponent<TextMeshProUGUI>()).text = team.name;
}
private void ChangeListHeightByMemberCount(ReorderableList teamUI, int members)
{
((Component)teamUI).GetComponent<LayoutElement>().flexibleHeight = 1f;
float preferredHeight = 50f * Math.Max(1f, (float)Math.Ceiling((float)members / 2f));
((Component)teamUI).GetComponent<LayoutElement>().preferredHeight = preferredHeight;
}
private void HandlePlayerMoved(ReorderableList list, ReorderableListElement playerElement)
{
PlayerInfo val = default(PlayerInfo);
if (CourseManager.CurrentHoleCourseIndex == -1 && GameManager.TryFindPlayerByGuid(((Component)playerElement).GetComponent<MatchSetupPlayer>().Guid, ref val))
{
bool flag = val.PlayerId.Guid == GameManager.LocalPlayerInfo.PlayerId.Guid;
string name = ((Object)((Component)playerElement).transform.parent).name;
if (NetworkServer.active)
{
TeamManager.Instance.ChangePlayerTeam(val.PlayerId.Guid, name);
TeamManager.Instance.SyncTeamsToClients();
}
else if (!flag)
{
}
}
}
public static string StripTMPTags(string text)
{
return Regex.Replace(text, "<.*?>", "");
}
public void UpdatePlayerInfoColors()
{
//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
List<ScoreboardEntry> scoreboardEntries = Object.FindObjectsByType<ScoreboardEntry>((FindObjectsSortMode)1).ToList();
Dictionary<string, TextMeshProUGUI> playersScoreboardNames = GetPlayersScoreboardNames(scoreboardEntries);
FieldInfo field = typeof(PlayerId).GetField("nameTag", BindingFlags.Instance | BindingFlags.NonPublic);
FieldInfo field2 = typeof(ScoreboardEntry).GetField("name", BindingFlags.Instance | BindingFlags.NonPublic);
foreach (Team team in TeamManager.Instance.Teams)
{
foreach (PlayerGolfer member in team.Members)
{
if (field != null)
{
object? value = field.GetValue(member.PlayerInfo.PlayerId);
NameTagUi val = (NameTagUi)((value is NameTagUi) ? value : null);
if ((Object)(object)val != (Object)null)
{
((Graphic)((Component)val).GetComponent<TextMeshProUGUI>()).color = team.color;
}
}
if (playersScoreboardNames.ContainsKey(((Object)member).name))
{
((Graphic)playersScoreboardNames[((Object)member).name]).color = team.color;
}
}
}
}
private Dictionary<string, TextMeshProUGUI> GetPlayersScoreboardNames(List<ScoreboardEntry> scoreboardEntries)
{
Dictionary<string, TextMeshProUGUI> dictionary = new Dictionary<string, TextMeshProUGUI>();
foreach (ScoreboardEntry scoreboardEntry in scoreboardEntries)
{
TextMeshProUGUI component = ((Component)((Component)scoreboardEntry).transform.GetChild(2).GetChild(3)).GetComponent<TextMeshProUGUI>();
if (Object.op_Implicit((Object)(object)component))
{
dictionary[StripTMPTags(((TMP_Text)component).text)] = component;
}
}
return dictionary;
}
private void UpdateDropdownOptions(TMP_Dropdown tmp_dropdown)
{
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: Expected O, but got Unknown
List<OptionData> list = new List<OptionData>();
list.Add(new OptionData("Teams"));
tmp_dropdown.AddOptions(list);
tmp_dropdown.RefreshShownValue();
}
public void SetupGamemodeUI()
{
try
{
TMP_Dropdown dropdown = getDropdown();
if (dropdown.options.Count < 2)
{
UpdateDropdownOptions(dropdown);
}
}
catch (Exception arg)
{
Plugin.Logger.LogError((object)$"Couldn't set up the ui: {arg}");
}
}
public void UpdateGamemodeUI(bool teamsActive)
{
TMP_Dropdown dropdown = getDropdown();
if ((Object)(object)dropdown == (Object)null)
{
Plugin.Logger.LogError((object)"couldn't find dropdown");
return;
}
string text = (teamsActive ? "Teams" : "Free-for-all");
dropdown.SetValueWithoutNotify(teamsActive ? 1 : 0);
dropdown.RefreshShownValue();
}
public static bool RemovePlayerFromTeam(ReorderableListElement playerElement)
{
PlayerInfo val = default(PlayerInfo);
if (!GameManager.TryFindPlayerByGuid(((Component)playerElement).GetComponent<MatchSetupPlayer>().Guid, ref val))
{
return true;
}
bool flag = val.PlayerId.Guid == GameManager.LocalPlayerInfo.PlayerId.Guid;
if (NetworkServer.active)
{
TeamManager.Instance.RemovePlayerFromTeam(val.PlayerId.Guid);
TeamManager.Instance.CleanTeams();
TeamManager.Instance.SyncTeamsToClients();
}
else if (!flag)
{
}
return true;
}
}
[HarmonyPatch(typeof(MatchSetupMenu), "OnPlayerMovedToPlayers")]
public static class PlayerMovedToPlayersPatch
{
private static bool Prefix(MatchSetupMenu __instance, ReorderableListElement playerElement)
{
if (!Object.op_Implicit((Object)(object)TeamManager.Instance))
{
Plugin.Logger.LogError((object)"Couldn't find team manager instance");
return true;
}
if (!TeamManager.gamemodeActive)
{
return true;
}
return UIManager.RemovePlayerFromTeam(playerElement);
}
}
[HarmonyPatch(typeof(MatchSetupMenu), "OnPlayerMovedToSpectate")]
public static class PlayerMovedToSpectatorPatch
{
private static bool Prefix(MatchSetupMenu __instance, ReorderableListElement playerElement)
{
if (!Object.op_Implicit((Object)(object)TeamManager.Instance))
{
Plugin.Logger.LogError((object)"Couldn't find team manager instance");
return true;
}
if (!TeamManager.gamemodeActive)
{
return true;
}
return UIManager.RemovePlayerFromTeam(playerElement);
}
}
public static class MyPluginInfo
{
public const string PLUGIN_GUID = "SBG_Teams";
public const string PLUGIN_NAME = "SBG Teams Mod";
public const string PLUGIN_VERSION = "1.0.0";
}
}