Decompiled source of amt Football Mod v5.0.0

BRC_Football.dll

Decompiled 3 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using BombRushMP.Common.Networking;
using BombRushMP.Plugin;
using TMPro;
using UnityEngine;
using UnityEngine.SceneManagement;
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: AssemblyTitle("BRC_Football")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("BRC_Football")]
[assembly: AssemblyCopyright("Copyright ©  2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("0423d7ec-56a7-41eb-9a1f-30a3e4604fdc")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
public static class ACNBridge
{
	private const string PACKET_ID = "com.chimp.brcfootball";

	public static Action<string, string, ushort> OnEvent;

	public static Action<string, byte[], ushort> OnBinary;

	public static ushort LocalId => ClientController.Instance?.LocalID ?? 0;

	public static void Init()
	{
		ClientController.RegisterCustomPacketHandler("com.chimp.brcfootball", (Action<ushort, byte[]>)OnCustomPacket);
		ClientController.PlayerDisconnected = (Action<ushort>)Delegate.Combine(ClientController.PlayerDisconnected, new Action<ushort>(OnPlayerDisconnected));
		Debug.Log((object)"[ACNBridge] Initialized");
	}

	public static void Shutdown()
	{
		ClientController.UnregisterCustomPacketHandler("com.chimp.brcfootball");
		ClientController.PlayerDisconnected = (Action<ushort>)Delegate.Remove(ClientController.PlayerDisconnected, new Action<ushort>(OnPlayerDisconnected));
	}

	public static void AnnouncePresence()
	{
		Broadcast("BRCHello", LocalId.ToString());
		Debug.Log((object)"[ACNBridge] Announced presence.");
	}

	public static void AnnounceLeaving()
	{
		Broadcast("BRCBye", LocalId.ToString());
		Debug.Log((object)"[ACNBridge] Announced leaving.");
	}

	private static ushort GetLowestKnownId()
	{
		ushort num = LocalId;
		foreach (ushort player in FootballNet.Players)
		{
			if (player < num)
			{
				num = player;
			}
		}
		return num;
	}

	private static void OnPlayerDisconnected(ushort playerId)
	{
		if (FootballNet.Players.Contains(playerId))
		{
			ushort lowestKnownId = GetLowestKnownId();
			bool flag = playerId == lowestKnownId;
			FootballNet.Players.Remove(playerId);
			if (FootballNet.TemporaryHostId == playerId)
			{
				FootballNet.TemporaryHostId = 0;
			}
			FootballNet.RecalculateHost();
			Debug.Log((object)$"[ACNBridge] Player {playerId} force-disconnected. WasHost={flag} NowHost={FootballNet.IsHost}");
			if (flag && FootballNet.IsHost)
			{
				BRC_Football.Instance?.OnBecomeHost();
			}
			else if (flag && !FootballNet.IsHost)
			{
				BRC_Football.Instance?.OnBecomeClient();
			}
		}
	}

	private static void OnCustomPacket(ushort sender, byte[] data)
	{
		if (sender == LocalId)
		{
			return;
		}
		using MemoryStream input = new MemoryStream(data);
		using BinaryReader binaryReader = new BinaryReader(input);
		ushort count = binaryReader.ReadUInt16();
		string arg = new string(binaryReader.ReadChars(count));
		if (binaryReader.ReadBoolean())
		{
			int count2 = binaryReader.ReadInt32();
			byte[] arg2 = binaryReader.ReadBytes(count2);
			OnBinary?.Invoke(arg, arg2, sender);
		}
		else
		{
			string arg3 = binaryReader.ReadString();
			OnEvent?.Invoke(arg, arg3, sender);
		}
	}

	public static void Broadcast(string name, string payload)
	{
		ClientController instance = ClientController.Instance;
		if (!((Object)(object)instance == (Object)null))
		{
			instance.BroadcastCustomPacket(Encode(name, payload), "com.chimp.brcfootball", (SendModes)2);
		}
	}

	public static void BroadcastBinary(string name, byte[] payload)
	{
		ClientController instance = ClientController.Instance;
		if (!((Object)(object)instance == (Object)null))
		{
			instance.BroadcastCustomPacket(EncodeBinary(name, payload), "com.chimp.brcfootball", (SendModes)2);
		}
	}

	public static void SendToPlayer(ushort target, string name, string payload)
	{
		ClientController instance = ClientController.Instance;
		if (!((Object)(object)instance == (Object)null))
		{
			instance.SendCustomPacketToPlayer(Encode(name, payload), "com.chimp.brcfootball", target, (SendModes)2);
		}
	}

	private static byte[] Encode(string name, string payload)
	{
		using MemoryStream memoryStream = new MemoryStream();
		using BinaryWriter binaryWriter = new BinaryWriter(memoryStream);
		binaryWriter.Write((ushort)name.Length);
		binaryWriter.Write(name.ToCharArray());
		binaryWriter.Write(value: false);
		binaryWriter.Write(payload);
		return memoryStream.ToArray();
	}

	private static byte[] EncodeBinary(string name, byte[] payload)
	{
		using MemoryStream memoryStream = new MemoryStream();
		using BinaryWriter binaryWriter = new BinaryWriter(memoryStream);
		binaryWriter.Write((ushort)name.Length);
		binaryWriter.Write(name.ToCharArray());
		binaryWriter.Write(value: true);
		binaryWriter.Write(payload.Length);
		binaryWriter.Write(payload);
		return memoryStream.ToArray();
	}

	public static Vector3 GetPlayerPosition(ushort playerId)
	{
		//IL_0012: 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_0056: Unknown result type (might be due to invalid IL or missing references)
		//IL_005b: Unknown result type (might be due to invalid IL or missing references)
		//IL_005e: 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)
		//IL_003c: 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)
		ClientController instance = ClientController.Instance;
		if ((Object)(object)instance == (Object)null)
		{
			return Vector3.zero;
		}
		if (instance.Players.TryGetValue(playerId, out var value))
		{
			return ((Object)(object)value.Player != (Object)null) ? ((Component)value.Player).transform.position : Vector3.zero;
		}
		return Vector3.zero;
	}
}
public class ACNDebugTracer
{
	private const string LOG = "[ACN-TRACE]";

	private static bool hooked;

	public static void Init()
	{
		if (hooked)
		{
			return;
		}
		hooked = true;
		Debug.Log((object)"[ACN-TRACE] Initializing networking tracer...");
		Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
		foreach (Assembly assembly in assemblies)
		{
			if (assembly.GetName().Name.Contains("BombRush"))
			{
				Debug.Log((object)("[ASM] " + assembly.GetName().Name));
			}
		}
		Assembly assembly2 = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly a) => a.GetName().Name.Contains("BombRushMP"));
		if (assembly2 == null)
		{
			Debug.Log((object)"[ACN-TRACE] BombRushMP NOT FOUND");
			return;
		}
		Debug.Log((object)"[ACN-TRACE] BombRushMP Assembly FOUND");
		Type[] types = assembly2.GetTypes();
		foreach (Type type in types)
		{
			if (type.Name.Contains("Network") || type.Name.Contains("Client") || type.Name.Contains("Message") || type.Name.Contains("Lobby"))
			{
				Debug.Log((object)("[NET TYPE] " + type.FullName));
			}
		}
	}
}
[RequireComponent(typeof(Collider))]
public class BallKillTrigger : MonoBehaviour
{
	private void Awake()
	{
		Collider component = ((Component)this).GetComponent<Collider>();
		if (!component.isTrigger)
		{
			component.isTrigger = true;
			Debug.Log((object)"[BallKillTrigger] Collider set to trigger automatically.");
		}
	}

	private void OnTriggerEnter(Collider other)
	{
		if (!((Object)(object)BRC_Football.ball == (Object)null) && (Object)(object)((Component)other).gameObject == (Object)(object)BRC_Football.ball)
		{
			Debug.Log((object)"[FOOTBALL] Ball entered kill zone, requesting reset...");
			BRC_Football.Instance.TryResetBall();
		}
	}

	private void OnTriggerStay(Collider other)
	{
		if (!((Object)(object)BRC_Football.ball == (Object)null) && (Object)(object)((Component)other).gameObject == (Object)(object)BRC_Football.ball)
		{
			BRC_Football.Instance.TryResetBall();
		}
	}
}
public struct BallState
{
	public Vector3 pos;

	public Quaternion rot;

	public Vector3 vel;

	public float time;
}
public static class BallNetCodec
{
	public static BallState lastSent;

	public static void Reset()
	{
		lastSent = default(BallState);
	}

	public static byte[] EncodeDelta(BallState s)
	{
		//IL_0021: 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_0078: Unknown result type (might be due to invalid IL or missing references)
		//IL_0082: 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)
		//IL_004f: 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_00e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_0092: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_0111: Unknown result type (might be due to invalid IL or missing references)
		//IL_0125: Unknown result type (might be due to invalid IL or missing references)
		byte mask = 0;
		byte[] data = new byte[41];
		int offset = 1;
		if (s.pos != lastSent.pos)
		{
			WriteFloat(s.pos.x, 0);
			WriteFloat(s.pos.y, 1);
			WriteFloat(s.pos.z, 2);
		}
		if (s.rot != lastSent.rot)
		{
			WriteFloat(s.rot.x, 3);
			WriteFloat(s.rot.y, 4);
			WriteFloat(s.rot.z, 5);
			WriteFloat(s.rot.w, 6);
		}
		if (s.vel != lastSent.vel)
		{
			WriteFloat(s.vel.x, 7);
			WriteFloat(s.vel.y, 8);
			WriteFloat(s.vel.z, 9);
		}
		data[0] = mask;
		lastSent = s;
		return data;
		void WriteFloat(float f, int bit)
		{
			mask |= (byte)(1 << bit);
			Buffer.BlockCopy(BitConverter.GetBytes(f), 0, data, offset, 4);
			offset += 4;
		}
	}

	public static BallState DecodeDelta(byte[] data, BallState baseState)
	{
		byte b = data[0];
		int offset = 1;
		if (((uint)b & (true ? 1u : 0u)) != 0)
		{
			baseState.pos.x = ReadFloat();
		}
		if ((b & 2u) != 0)
		{
			baseState.pos.y = ReadFloat();
		}
		if ((b & 4u) != 0)
		{
			baseState.pos.z = ReadFloat();
		}
		if ((b & 8u) != 0)
		{
			baseState.rot.x = ReadFloat();
		}
		if ((b & 0x10u) != 0)
		{
			baseState.rot.y = ReadFloat();
		}
		if ((b & 0x20u) != 0)
		{
			baseState.rot.z = ReadFloat();
		}
		if ((b & 0x40u) != 0)
		{
			baseState.rot.w = ReadFloat();
		}
		if ((b & 0x80u) != 0)
		{
			baseState.vel.x = ReadFloat();
		}
		if ((b & 0x100u) != 0)
		{
			baseState.vel.y = ReadFloat();
		}
		if ((b & 0x200u) != 0)
		{
			baseState.vel.z = ReadFloat();
		}
		return baseState;
		float ReadFloat()
		{
			float result = BitConverter.ToSingle(data, offset);
			offset += 4;
			return result;
		}
	}
}
public class BallSyncClient : MonoBehaviour
{
	private struct Snapshot
	{
		public Vector3 pos;

		public Quaternion rot;

		public Vector3 vel;

		public float receivedTime;
	}

	private Rigidbody rb;

	private Queue<Snapshot> buffer = new Queue<Snapshot>();

	private const float INTERP_DELAY = 0.033f;

	private const float HARD_SNAP_THRESHOLD = 8f;

	private const float FAST_CATCHUP_THRESHOLD = 1f;

	private const float MAX_CATCHUP_LERP = 40f;

	private const float MIN_CATCHUP_LERP = 15f;

	private const float VEL_LERP = 20f;

	private const float CLIENT_COLLIDER_RADIUS_MULTIPLIER = 1.35f;

	private SphereCollider ghostTrigger;

	private bool isPredicting = false;

	private Vector3 predictedVel = Vector3.zero;

	private float predictionAge = 0f;

	private const float PREDICTION_BLEND_OUT = 0.25f;

	private float lastKickTime = 0f;

	private const float KICK_COOLDOWN = 0.1f;

	public float Desync { get; private set; }

	private void Awake()
	{
		rb = BRC_Football.ballRb;
		if ((Object)(object)rb == (Object)null)
		{
			Debug.LogError((object)"[BallSyncClient] ballRb is null on Awake.");
		}
		else
		{
			Debug.Log((object)"[BallSyncClient] Initialized.");
		}
		SetupGhostCollider();
	}

	private void SetupGhostCollider()
	{
		if (!((Object)(object)rb == (Object)null))
		{
			SphereCollider component = ((Component)this).GetComponent<SphereCollider>();
			float num = (((Object)(object)component != (Object)null) ? component.radius : 0.3f);
			ghostTrigger = ((Component)this).gameObject.AddComponent<SphereCollider>();
			ghostTrigger.radius = num * 1.35f;
			((Collider)ghostTrigger).isTrigger = true;
			Debug.Log((object)$"[BallSyncClient] Ghost trigger radius={ghostTrigger.radius:F3}");
		}
	}

	public void OnBinary(string name, byte[] data)
	{
		//IL_0054: Unknown result type (might be due to invalid IL or missing references)
		//IL_0059: 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_0066: Unknown result type (might be due to invalid IL or missing references)
		//IL_006e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0073: Unknown result type (might be due to invalid IL or missing references)
		if (!(name != "BRCBallDelta"))
		{
			BallState baseState = ((buffer.Count > 0) ? SnapshotToState(PeekLast()) : default(BallState));
			BallState ballState = BallNetCodec.DecodeDelta(data, baseState);
			buffer.Enqueue(new Snapshot
			{
				pos = ballState.pos,
				rot = ballState.rot,
				vel = ballState.vel,
				receivedTime = Time.time
			});
			while (buffer.Count > 30)
			{
				buffer.Dequeue();
			}
			if (isPredicting)
			{
				isPredicting = false;
				predictionAge = 0f;
			}
		}
	}

	public Vector3 GetTargetPos()
	{
		//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_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_0029: Unknown result type (might be due to invalid IL or missing references)
		if (buffer.Count == 0)
		{
			return Vector3.zero;
		}
		return PeekLast().pos;
	}

	private void FixedUpdate()
	{
		//IL_0210: Unknown result type (might be due to invalid IL or missing references)
		//IL_0217: 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_0223: Unknown result type (might be due to invalid IL or missing references)
		//IL_0228: Unknown result type (might be due to invalid IL or missing references)
		//IL_022b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0230: Unknown result type (might be due to invalid IL or missing references)
		//IL_0233: Unknown result type (might be due to invalid IL or missing references)
		//IL_0238: Unknown result type (might be due to invalid IL or missing references)
		//IL_023b: Unknown result type (might be due to invalid IL or missing references)
		//IL_024e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0268: Unknown result type (might be due to invalid IL or missing references)
		//IL_026e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0273: Unknown result type (might be due to invalid IL or missing references)
		//IL_027a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0281: Unknown result type (might be due to invalid IL or missing references)
		//IL_0286: Unknown result type (might be due to invalid IL or missing references)
		//IL_028b: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01de: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_0119: Unknown result type (might be due to invalid IL or missing references)
		//IL_0120: Unknown result type (might be due to invalid IL or missing references)
		//IL_0127: Unknown result type (might be due to invalid IL or missing references)
		//IL_012c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0131: Unknown result type (might be due to invalid IL or missing references)
		//IL_0134: Unknown result type (might be due to invalid IL or missing references)
		//IL_0139: Unknown result type (might be due to invalid IL or missing references)
		//IL_013c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0141: Unknown result type (might be due to invalid IL or missing references)
		//IL_0144: Unknown result type (might be due to invalid IL or missing references)
		//IL_0157: Unknown result type (might be due to invalid IL or missing references)
		//IL_02db: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d3: Unknown result type (might be due to invalid IL or missing references)
		//IL_035f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0364: Unknown result type (might be due to invalid IL or missing references)
		//IL_036d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0384: Unknown result type (might be due to invalid IL or missing references)
		//IL_0389: Unknown result type (might be due to invalid IL or missing references)
		//IL_0392: Unknown result type (might be due to invalid IL or missing references)
		//IL_03a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_03ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_03ba: Unknown result type (might be due to invalid IL or missing references)
		//IL_0307: Unknown result type (might be due to invalid IL or missing references)
		//IL_0314: Unknown result type (might be due to invalid IL or missing references)
		//IL_0321: Unknown result type (might be due to invalid IL or missing references)
		//IL_0171: Unknown result type (might be due to invalid IL or missing references)
		//IL_0177: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_018a: Unknown result type (might be due to invalid IL or missing references)
		//IL_018f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0194: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)rb == (Object)null || FootballNet.IsHost || buffer.Count < 1)
		{
			return;
		}
		float num = Time.time - 0.033f;
		while (buffer.Count > 2 && buffer.Peek().receivedTime < num)
		{
			buffer.Dequeue();
		}
		Vector3 val;
		Quaternion val2;
		Vector3 val3;
		if (buffer.Count >= 2)
		{
			Snapshot[] array = buffer.ToArray();
			Snapshot snapshot = array[0];
			Snapshot snapshot2 = array[1];
			float num2 = snapshot2.receivedTime - snapshot.receivedTime;
			float num3 = ((num2 > 0f) ? ((num - snapshot.receivedTime) / num2) : 1f);
			if (num3 > 1f)
			{
				float num4 = Mathf.Clamp(num - snapshot2.receivedTime, 0f, 0.2f);
				val = snapshot2.pos + snapshot2.vel * num4;
				val2 = snapshot2.rot;
				val3 = snapshot2.vel;
				if (snapshot2.vel.y > 0.1f || snapshot2.pos.y > 1f)
				{
					val += 0.5f * Physics.gravity * num4 * num4;
				}
			}
			else
			{
				num3 = Mathf.Clamp01(num3);
				val = Vector3.Lerp(snapshot.pos, snapshot2.pos, num3);
				val2 = Quaternion.Slerp(snapshot.rot, snapshot2.rot, num3);
				val3 = Vector3.Lerp(snapshot.vel, snapshot2.vel, num3);
			}
		}
		else
		{
			Snapshot snapshot3 = PeekLast();
			float num5 = Mathf.Clamp(num - snapshot3.receivedTime, 0f, 0.2f);
			val = snapshot3.pos + snapshot3.vel * num5;
			val2 = snapshot3.rot;
			val3 = snapshot3.vel;
			if (snapshot3.vel.y > 0.1f || snapshot3.pos.y > 1f)
			{
				val += 0.5f * Physics.gravity * num5 * num5;
			}
		}
		if (isPredicting)
		{
			predictionAge += Time.fixedDeltaTime;
			float num6 = 1f - Mathf.Clamp01(predictionAge / 0.25f);
			val3 = Vector3.Lerp(val3, predictedVel, num6);
		}
		float num8 = (Desync = Vector3.Distance(rb.position, val));
		if (num8 > 8f)
		{
			rb.position = val;
			rb.rotation = val2;
			rb.velocity = val3;
		}
		else
		{
			float num9 = Mathf.InverseLerp(0f, 1f, num8);
			float num10 = Mathf.Lerp(15f, 40f, num9);
			rb.MovePosition(Vector3.Lerp(rb.position, val, num10 * Time.fixedDeltaTime));
			rb.MoveRotation(Quaternion.Slerp(rb.rotation, val2, num10 * Time.fixedDeltaTime));
			rb.velocity = Vector3.Lerp(rb.velocity, val3, 20f * Time.fixedDeltaTime);
		}
	}

	private void PredictAndSendKick(Vector3 relativeVelocity, float multiplier)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0003: Unknown result type (might be due to invalid IL or missing references)
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_004d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		Vector3 val = relativeVelocity * multiplier;
		if ((Object)(object)rb != (Object)null)
		{
			rb.AddForce(val, (ForceMode)1);
			predictedVel = rb.velocity;
			isPredicting = true;
			predictionAge = 0f;
		}
		SendKick(val);
		lastKickTime = Time.time;
	}

	private void OnCollisionEnter(Collision c)
	{
		//IL_002c: 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_00a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
		if (!FootballNet.IsHost && !(Time.time - lastKickTime < 0.1f))
		{
			Vector3 relativeVelocity = c.relativeVelocity;
			if (!(((Vector3)(ref relativeVelocity)).magnitude < 0.2f) && (((Object)c.gameObject).name.ToLower().Contains("player") || ((Object)c.gameObject).name.ToLower().Contains("character")))
			{
				string name = ((Object)c.gameObject).name;
				relativeVelocity = c.relativeVelocity;
				Debug.Log((object)$"[BallSyncClient] Collision: {name} vel={((Vector3)(ref relativeVelocity)).magnitude:F2}");
				PredictAndSendKick(c.relativeVelocity, 0.25f);
			}
		}
	}

	private void OnTriggerEnter(Collider other)
	{
		//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b6: 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)
		if (FootballNet.IsHost || (Object)(object)rb == (Object)null || Time.time - lastKickTime < 0.1f || (!((Object)((Component)other).gameObject).name.ToLower().Contains("player") && !((Object)((Component)other).gameObject).name.ToLower().Contains("character")))
		{
			return;
		}
		Rigidbody attachedRigidbody = other.attachedRigidbody;
		if (!((Object)(object)attachedRigidbody == (Object)null))
		{
			Vector3 relativeVelocity = attachedRigidbody.velocity - rb.velocity;
			if (!(((Vector3)(ref relativeVelocity)).magnitude < 0.5f))
			{
				Debug.Log((object)$"[BallSyncClient] Ghost trigger: {((Object)((Component)other).gameObject).name} relVel={((Vector3)(ref relativeVelocity)).magnitude:F2}");
				PredictAndSendKick(relativeVelocity, 0.25f);
			}
		}
	}

	public void SendKick(Vector3 force)
	{
		//IL_0009: 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)
		//IL_0033: Unknown result type (might be due to invalid IL or missing references)
		byte[] array = new byte[12];
		Buffer.BlockCopy(BitConverter.GetBytes(force.x), 0, array, 0, 4);
		Buffer.BlockCopy(BitConverter.GetBytes(force.y), 0, array, 4, 4);
		Buffer.BlockCopy(BitConverter.GetBytes(force.z), 0, array, 8, 4);
		ACNBridge.BroadcastBinary("BRCKick", array);
	}

	private Snapshot PeekLast()
	{
		Snapshot result = default(Snapshot);
		foreach (Snapshot item in buffer)
		{
			result = item;
		}
		return result;
	}

	private BallState SnapshotToState(Snapshot s)
	{
		//IL_000c: 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_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0026: 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)
		BallState result = default(BallState);
		result.pos = s.pos;
		result.rot = s.rot;
		result.vel = s.vel;
		return result;
	}
}
public class BallSyncHost : MonoBehaviour
{
	[CompilerGenerated]
	private sealed class <BroadcastNextFrame>d__8 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		public BallSyncHost <>4__this;

		object IEnumerator<object>.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		object IEnumerator.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		[DebuggerHidden]
		public <BroadcastNextFrame>d__8(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;
				<>2__current = null;
				<>1__state = 1;
				return true;
			case 1:
				<>1__state = -1;
				<>4__this.BroadcastState();
				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();
		}
	}

	[CompilerGenerated]
	private sealed class <Loop>d__5 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		public BallSyncHost <>4__this;

		private float <speed>5__1;

		private float <tick>5__2;

		object IEnumerator<object>.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		object IEnumerator.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		[DebuggerHidden]
		public <Loop>d__5(int <>1__state)
		{
			this.<>1__state = <>1__state;
		}

		[DebuggerHidden]
		void IDisposable.Dispose()
		{
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			//IL_004f: 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_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Expected O, but got Unknown
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				break;
			case 1:
				<>1__state = -1;
				if ((Object)(object)<>4__this.rb == (Object)null)
				{
					<>4__this.rb = BRC_Football.ballRb;
				}
				else if (FootballNet.IsHost && !((Object)(object)BRC_Football.Instance == (Object)null) && !BRC_Football.Instance.resetting)
				{
					<>4__this.BroadcastState();
				}
				break;
			}
			float num;
			if (!((Object)(object)<>4__this.rb != (Object)null))
			{
				num = 0f;
			}
			else
			{
				Vector3 velocity = <>4__this.rb.velocity;
				num = ((Vector3)(ref velocity)).magnitude;
			}
			<speed>5__1 = num;
			<tick>5__2 = ((<speed>5__1 > 5f) ? 0.008f : 0.016f);
			<>2__current = (object)new WaitForSeconds(<tick>5__2);
			<>1__state = 1;
			return true;
		}

		bool IEnumerator.MoveNext()
		{
			//ILSpy generated this explicit interface implementation from .override directive in MoveNext
			return this.MoveNext();
		}

		[DebuggerHidden]
		void IEnumerator.Reset()
		{
			throw new NotSupportedException();
		}
	}

	private Rigidbody rb;

	private const float TICK_SLOW = 0.016f;

	private const float TICK_FAST = 0.008f;

	private const float FAST_SPEED_THRESHOLD = 5f;

	private void Awake()
	{
		rb = BRC_Football.ballRb;
		if ((Object)(object)rb == (Object)null)
		{
			Debug.LogError((object)"[BallSyncHost] ballRb is null on Awake.");
		}
		else
		{
			Debug.Log((object)"[BallSyncHost] Initialized.");
		}
		BallNetCodec.Reset();
		((MonoBehaviour)this).StartCoroutine(Loop());
	}

	[IteratorStateMachine(typeof(<Loop>d__5))]
	private IEnumerator Loop()
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <Loop>d__5(0)
		{
			<>4__this = this
		};
	}

	public void BroadcastState()
	{
		//IL_0023: 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_0035: 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_0047: 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 (!((Object)(object)rb == (Object)null))
		{
			BallState ballState = default(BallState);
			ballState.pos = rb.position;
			ballState.rot = rb.rotation;
			ballState.vel = rb.velocity;
			ballState.time = Time.time;
			BallState s = ballState;
			ACNBridge.BroadcastBinary("BRCBallDelta", BallNetCodec.EncodeDelta(s));
		}
	}

	public void ApplyClientKick(Vector3 force)
	{
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)rb == (Object)null))
		{
			rb.AddForce(force, (ForceMode)1);
			BroadcastState();
			((MonoBehaviour)this).StartCoroutine(BroadcastNextFrame());
		}
	}

	[IteratorStateMachine(typeof(<BroadcastNextFrame>d__8))]
	private IEnumerator BroadcastNextFrame()
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <BroadcastNextFrame>d__8(0)
		{
			<>4__this = this
		};
	}

	private void OnCollisionEnter(Collision c)
	{
		//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_009d: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
		if (FootballNet.IsHost && !((Object)(object)rb == (Object)null))
		{
			Vector3 relativeVelocity = c.relativeVelocity;
			if (!(((Vector3)(ref relativeVelocity)).magnitude < 0.2f) && (((Object)c.gameObject).name.ToLower().Contains("player") || ((Object)c.gameObject).name.ToLower().Contains("character")))
			{
				string name = ((Object)c.gameObject).name;
				relativeVelocity = c.relativeVelocity;
				Debug.Log((object)$"[BallSyncHost] Hit by: {name} vel={((Vector3)(ref relativeVelocity)).magnitude:F2}");
				rb.AddForce(c.relativeVelocity * 0.2f, (ForceMode)1);
				BroadcastState();
				((MonoBehaviour)this).StartCoroutine(BroadcastNextFrame());
			}
		}
	}
}
public enum GoalTeam
{
	Red,
	Blue
}
[BepInPlugin("com.chimp.brcfootball", "BRC Football", "3.4.0")]
public class BRC_Football : BaseUnityPlugin
{
	private class GoalUI
	{
		public GameObject root;

		public Image bg;

		public TextMeshProUGUI text;

		public GoalTriggerWatcher watcher;

		public Coroutine flashRoutine;
	}

	[CompilerGenerated]
	private sealed class <BecomeClientRoutine>d__43 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		public BRC_Football <>4__this;

		private BallSyncHost <oldHost>5__1;

		object IEnumerator<object>.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		object IEnumerator.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		[DebuggerHidden]
		public <BecomeClientRoutine>d__43(int <>1__state)
		{
			this.<>1__state = <>1__state;
		}

		[DebuggerHidden]
		void IDisposable.Dispose()
		{
			<oldHost>5__1 = null;
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
			{
				<>1__state = -1;
				GameObject ball = BRC_Football.ball;
				<oldHost>5__1 = ((ball != null) ? ball.GetComponent<BallSyncHost>() : null);
				if ((Object)(object)<oldHost>5__1 != (Object)null)
				{
					Object.Destroy((Object)(object)<oldHost>5__1);
					<>2__current = null;
					<>1__state = 1;
					return true;
				}
				break;
			}
			case 1:
				<>1__state = -1;
				break;
			}
			if ((Object)(object)BRC_Football.ball != (Object)null && (Object)(object)BRC_Football.ball.GetComponent<BallSyncClient>() == (Object)null)
			{
				BRC_Football.ball.AddComponent<BallSyncClient>();
			}
			<>4__this.ApplyHostPhysics();
			ManualLogSource logger = ((BaseUnityPlugin)<>4__this).Logger;
			Rigidbody ballRb = BRC_Football.ballRb;
			logger.LogInfo((object)string.Format("{0} Client takeover complete. useGravity={1}", "[BRC-Football]", (ballRb != null) ? new bool?(ballRb.useGravity) : null));
			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();
		}
	}

	[CompilerGenerated]
	private sealed class <BecomeHostRoutine>d__41 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		public BRC_Football <>4__this;

		private BallSyncClient <oldClient>5__1;

		private BallState <s>5__2;

		object IEnumerator<object>.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		object IEnumerator.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		[DebuggerHidden]
		public <BecomeHostRoutine>d__41(int <>1__state)
		{
			this.<>1__state = <>1__state;
		}

		[DebuggerHidden]
		void IDisposable.Dispose()
		{
			<oldClient>5__1 = null;
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
			{
				<>1__state = -1;
				GameObject ball = BRC_Football.ball;
				<oldClient>5__1 = ((ball != null) ? ball.GetComponent<BallSyncClient>() : null);
				if ((Object)(object)<oldClient>5__1 != (Object)null)
				{
					Object.Destroy((Object)(object)<oldClient>5__1);
					<>2__current = null;
					<>1__state = 1;
					return true;
				}
				break;
			}
			case 1:
				<>1__state = -1;
				break;
			}
			if ((Object)(object)BRC_Football.ball != (Object)null && (Object)(object)BRC_Football.ball.GetComponent<BallSyncHost>() == (Object)null)
			{
				BallNetCodec.Reset();
				BRC_Football.ball.AddComponent<BallSyncHost>();
			}
			<>4__this.ApplyHostPhysics();
			<>4__this.ownershipTransferred = false;
			FootballNet.TemporaryHostId = 0;
			if ((Object)(object)BRC_Football.ballRb != (Object)null)
			{
				<s>5__2 = new BallState
				{
					pos = BRC_Football.ballRb.position,
					rot = BRC_Football.ballRb.rotation,
					vel = BRC_Football.ballRb.velocity,
					time = Time.time
				};
				ACNBridge.BroadcastBinary("BRCBallDelta", BallNetCodec.EncodeDelta(<s>5__2));
			}
			ACNBridge.Broadcast("BRCScore", $"{<>4__this.redScore};{<>4__this.blueScore}");
			ManualLogSource logger = ((BaseUnityPlugin)<>4__this).Logger;
			Rigidbody ballRb = BRC_Football.ballRb;
			logger.LogInfo((object)string.Format("{0} Host takeover complete. useGravity={1}", "[BRC-Football]", (ballRb != null) ? new bool?(ballRb.useGravity) : null));
			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();
		}
	}

	[CompilerGenerated]
	private sealed class <ClientCountdown>d__60 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		public BRC_Football <>4__this;

		private string[] <steps>5__1;

		private string[] <>s__2;

		private int <>s__3;

		private string <step>5__4;

		object IEnumerator<object>.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		object IEnumerator.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		[DebuggerHidden]
		public <ClientCountdown>d__60(int <>1__state)
		{
			this.<>1__state = <>1__state;
		}

		[DebuggerHidden]
		void IDisposable.Dispose()
		{
			<steps>5__1 = null;
			<>s__2 = null;
			<step>5__4 = null;
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Expected O, but got Unknown
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				<steps>5__1 = new string[4] { "3", "2", "1", "GO!" };
				<>s__2 = <steps>5__1;
				<>s__3 = 0;
				break;
			case 1:
				<>1__state = -1;
				<step>5__4 = null;
				<>s__3++;
				break;
			}
			if (<>s__3 < <>s__2.Length)
			{
				<step>5__4 = <>s__2[<>s__3];
				<>4__this.SetScoreUICountdown(<step>5__4);
				<>2__current = (object)new WaitForSeconds((<step>5__4 == "GO!") ? 0.8f : 1f);
				<>1__state = 1;
				return true;
			}
			<>s__2 = null;
			<>4__this.UpdateScoreUI(<>4__this.redScore, <>4__this.blueScore);
			if ((Object)(object)<>4__this.countdownUIRoot != (Object)null)
			{
				<>4__this.countdownUIRoot.SetActive(false);
			}
			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();
		}
	}

	[CompilerGenerated]
	private sealed class <Countdown>d__49 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		public BRC_Football <>4__this;

		private string[] <steps>5__1;

		private string[] <>s__2;

		private int <>s__3;

		private string <step>5__4;

		object IEnumerator<object>.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		object IEnumerator.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		[DebuggerHidden]
		public <Countdown>d__49(int <>1__state)
		{
			this.<>1__state = <>1__state;
		}

		[DebuggerHidden]
		void IDisposable.Dispose()
		{
			<steps>5__1 = null;
			<>s__2 = null;
			<step>5__4 = null;
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Expected O, but got Unknown
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				<>4__this.resetting = true;
				<steps>5__1 = new string[4] { "3", "2", "1", "GO!" };
				<>s__2 = <steps>5__1;
				<>s__3 = 0;
				break;
			case 1:
				<>1__state = -1;
				<step>5__4 = null;
				<>s__3++;
				break;
			}
			if (<>s__3 < <>s__2.Length)
			{
				<step>5__4 = <>s__2[<>s__3];
				<>4__this.SetScoreUICountdown(<step>5__4);
				<>2__current = (object)new WaitForSeconds((<step>5__4 == "GO!") ? 0.8f : 1f);
				<>1__state = 1;
				return true;
			}
			<>s__2 = null;
			<>4__this.UpdateScoreUI(<>4__this.redScore, <>4__this.blueScore);
			if ((Object)(object)<>4__this.countdownUIRoot != (Object)null)
			{
				<>4__this.countdownUIRoot.SetActive(false);
			}
			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();
		}
	}

	[CompilerGenerated]
	private sealed class <FlashGoal>d__57 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		public GoalUI ui;

		public GoalTeam team;

		public BRC_Football <>4__this;

		private Color <flashColor>5__1;

		private Color <original>5__2;

		private float <t>5__3;

		object IEnumerator<object>.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		object IEnumerator.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		[DebuggerHidden]
		public <FlashGoal>d__57(int <>1__state)
		{
			this.<>1__state = <>1__state;
		}

		[DebuggerHidden]
		void IDisposable.Dispose()
		{
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			//IL_003f: 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_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: 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_00aa: 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)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				<flashColor>5__1 = ((team == GoalTeam.Red) ? <>4__this.redColor : <>4__this.blueColor);
				<flashColor>5__1.a = 0.85f;
				<original>5__2 = new Color(0f, 0f, 0f, 0.5f);
				<t>5__3 = 0f;
				break;
			case 1:
				<>1__state = -1;
				break;
			}
			if (<t>5__3 < <>4__this.flashDuration)
			{
				<t>5__3 += Time.deltaTime;
				((Graphic)ui.bg).color = Color.Lerp(<flashColor>5__1, <original>5__2, <t>5__3 / <>4__this.flashDuration);
				<>2__current = null;
				<>1__state = 1;
				return true;
			}
			((Graphic)ui.bg).color = <original>5__2;
			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();
		}
	}

	[CompilerGenerated]
	private sealed class <GoalSequence>d__48 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		public GoalTeam team;

		public int red;

		public int blue;

		public BRC_Football <>4__this;

		private Dictionary<GoalTriggerWatcher, GoalUI>.Enumerator <>s__1;

		private KeyValuePair<GoalTriggerWatcher, GoalUI> <kv>5__2;

		object IEnumerator<object>.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		object IEnumerator.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		[DebuggerHidden]
		public <GoalSequence>d__48(int <>1__state)
		{
			this.<>1__state = <>1__state;
		}

		[DebuggerHidden]
		void IDisposable.Dispose()
		{
			<>s__1 = default(Dictionary<GoalTriggerWatcher, GoalUI>.Enumerator);
			<kv>5__2 = default(KeyValuePair<GoalTriggerWatcher, GoalUI>);
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Expected O, but got Unknown
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				<>4__this.UpdateGoalUIText(red, blue);
				<>4__this.UpdateScoreUI(red, blue);
				<>4__this.FlashGoalUI(team);
				if ((Object)(object)ballRb != (Object)null && FootballNet.IsHost)
				{
					ballRb.isKinematic = true;
					ballRb.detectCollisions = false;
					<>2__current = (object)new WaitForSeconds(0.5f);
					<>1__state = 1;
					return true;
				}
				goto IL_0106;
			case 1:
				<>1__state = -1;
				ball.transform.position = <>4__this.respawn.position;
				ballRb.velocity = Vector3.zero;
				ballRb.angularVelocity = Vector3.zero;
				goto IL_0106;
			case 2:
				{
					<>1__state = -1;
					if ((Object)(object)ballRb != (Object)null && FootballNet.IsHost)
					{
						ballRb.detectCollisions = true;
						ballRb.isKinematic = false;
						ballRb.useGravity = true;
					}
					<>s__1 = <>4__this.goalUIs.GetEnumerator();
					try
					{
						while (<>s__1.MoveNext())
						{
							<kv>5__2 = <>s__1.Current;
							<kv>5__2.Key.Unlock();
							<kv>5__2 = default(KeyValuePair<GoalTriggerWatcher, GoalUI>);
						}
					}
					finally
					{
						((IDisposable)<>s__1).Dispose();
					}
					<>s__1 = default(Dictionary<GoalTriggerWatcher, GoalUI>.Enumerator);
					<>4__this.resetting = false;
					return false;
				}
				IL_0106:
				<>2__current = ((MonoBehaviour)<>4__this).StartCoroutine(<>4__this.Countdown());
				<>1__state = 2;
				return true;
			}
		}

		bool IEnumerator.MoveNext()
		{
			//ILSpy generated this explicit interface implementation from .override directive in MoveNext
			return this.MoveNext();
		}

		[DebuggerHidden]
		void IEnumerator.Reset()
		{
			throw new NotSupportedException();
		}
	}

	[CompilerGenerated]
	private sealed class <HandleGameOver>d__51 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		public GoalTeam winner;

		public int red;

		public int blue;

		public BRC_Football <>4__this;

		private string <winnerName>5__1;

		private Color <winColor>5__2;

		object IEnumerator<object>.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		object IEnumerator.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		[DebuggerHidden]
		public <HandleGameOver>d__51(int <>1__state)
		{
			this.<>1__state = <>1__state;
		}

		[DebuggerHidden]
		void IDisposable.Dispose()
		{
			<winnerName>5__1 = null;
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			//IL_00ce: 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)
			//IL_00d3: 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)
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				<>4__this.UpdateGoalUIText(red, blue);
				<>4__this.UpdateScoreUI(red, blue);
				<>4__this.FlashGoalUI(winner);
				if ((Object)(object)ballRb != (Object)null && FootballNet.IsHost)
				{
					ballRb.isKinematic = true;
					ballRb.detectCollisions = false;
				}
				<winnerName>5__1 = ((winner == GoalTeam.Red) ? "RED" : "BLUE");
				<winColor>5__2 = ((winner == GoalTeam.Red) ? <>4__this.redColor : <>4__this.blueColor);
				<>4__this.SetScoreUIWin(<winnerName>5__1, <winColor>5__2);
				((BaseUnityPlugin)<>4__this).Logger.LogInfo((object)string.Format("{0} Game over! {1} wins.", "[BRC-Football]", winner));
				<>4__this.resetting = true;
				<>2__current = null;
				<>1__state = 1;
				return true;
			case 1:
				<>1__state = -1;
				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();
		}
	}

	[CompilerGenerated]
	private sealed class <Init>d__38 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		public BRC_Football <>4__this;

		private GameObject <resp>5__1;

		private List<Collider> <playerColliders>5__2;

		private SphereCollider <sc>5__3;

		private GameObject[] <>s__4;

		private int <>s__5;

		private GameObject <obj>5__6;

		private Collider[] <>s__7;

		private int <>s__8;

		private Collider <col>5__9;

		private List<Collider>.Enumerator <>s__10;

		private Collider <pc>5__11;

		object IEnumerator<object>.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		object IEnumerator.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		[DebuggerHidden]
		public <Init>d__38(int <>1__state)
		{
			this.<>1__state = <>1__state;
		}

		[DebuggerHidden]
		void IDisposable.Dispose()
		{
			<resp>5__1 = null;
			<playerColliders>5__2 = null;
			<sc>5__3 = null;
			<>s__4 = null;
			<obj>5__6 = null;
			<>s__7 = null;
			<col>5__9 = null;
			<>s__10 = default(List<Collider>.Enumerator);
			<pc>5__11 = null;
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Expected O, but got Unknown
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				((BaseUnityPlugin)<>4__this).Logger.LogInfo((object)"[BRC-Football] Initializing...");
				goto IL_007c;
			case 1:
				<>1__state = -1;
				goto IL_007c;
			case 2:
				{
					<>1__state = -1;
					<resp>5__1 = GameObject.Find("BallRespawn");
					<>4__this.respawn = (((Object)(object)<resp>5__1 != (Object)null) ? <resp>5__1.transform : ball.transform);
					ballRb = ball.GetComponent<Rigidbody>() ?? ball.AddComponent<Rigidbody>();
					ballRb.mass = 0.7f;
					ballRb.collisionDetectionMode = (CollisionDetectionMode)2;
					ballRb.interpolation = (RigidbodyInterpolation)1;
					if (!Object.op_Implicit((Object)(object)ball.GetComponent<Collider>()))
					{
						<sc>5__3 = ball.AddComponent<SphereCollider>();
						<sc>5__3.radius = 0.3f;
						<sc>5__3 = null;
					}
					ball.transform.position = <>4__this.respawn.position + Vector3.up * 2f;
					Physics.SyncTransforms();
					<>4__this.ApplyHostPhysics();
					if (FootballNet.IsHost)
					{
						ball.AddComponent<BallSyncHost>();
					}
					else
					{
						ball.AddComponent<BallSyncClient>();
					}
					<>4__this.CreateGoals();
					<>4__this.CreateScoreUI();
					<>4__this.CreateCountdownUI();
					((Component)<>4__this).gameObject.AddComponent<FootballNetTester>();
					((BaseUnityPlugin)<>4__this).Logger.LogInfo((object)string.Format("{0} Init done. Host={1}", "[BRC-Football]", FootballNet.IsHost));
					ACNBridge.AnnouncePresence();
					<playerColliders>5__2 = new List<Collider>();
					<>s__4 = Object.FindObjectsOfType<GameObject>();
					for (<>s__5 = 0; <>s__5 < <>s__4.Length; <>s__5++)
					{
						<obj>5__6 = <>s__4[<>s__5];
						if (<obj>5__6.CompareTag("Player"))
						{
							<playerColliders>5__2.AddRange(<obj>5__6.GetComponentsInChildren<Collider>());
						}
						<obj>5__6 = null;
					}
					<>s__4 = null;
					((BaseUnityPlugin)<>4__this).Logger.LogInfo((object)string.Format("{0} Found {1} player collider(s).", "[BRC-Football]", <playerColliders>5__2.Count));
					<>s__7 = Object.FindObjectsOfType<Collider>();
					for (<>s__8 = 0; <>s__8 < <>s__7.Length; <>s__8++)
					{
						<col>5__9 = <>s__7[<>s__8];
						if (((Object)<col>5__9).name.StartsWith("footballedges", StringComparison.OrdinalIgnoreCase))
						{
							<>s__10 = <playerColliders>5__2.GetEnumerator();
							try
							{
								while (<>s__10.MoveNext())
								{
									<pc>5__11 = <>s__10.Current;
									Physics.IgnoreCollision(<col>5__9, <pc>5__11, true);
									<pc>5__11 = null;
								}
							}
							finally
							{
								((IDisposable)<>s__10).Dispose();
							}
							<>s__10 = default(List<Collider>.Enumerator);
							((BaseUnityPlugin)<>4__this).Logger.LogInfo((object)("[BRC-Football] Ignoring collision: " + ((Object)<col>5__9).name));
							<col>5__9 = null;
						}
					}
					<>s__7 = null;
					return false;
				}
				IL_007c:
				if ((Object)(object)ball == (Object)null)
				{
					ball = GameObject.Find("Football") ?? GameObject.Find("Football(Clone)");
					<>2__current = null;
					<>1__state = 1;
					return true;
				}
				<>2__current = (object)new WaitForSeconds(2f);
				<>1__state = 2;
				return true;
			}
		}

		bool IEnumerator.MoveNext()
		{
			//ILSpy generated this explicit interface implementation from .override directive in MoveNext
			return this.MoveNext();
		}

		[DebuggerHidden]
		void IEnumerator.Reset()
		{
			throw new NotSupportedException();
		}
	}

	[CompilerGenerated]
	private sealed class <NewGameSequence>d__53 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		public BRC_Football <>4__this;

		private Dictionary<GoalTriggerWatcher, GoalUI>.Enumerator <>s__1;

		private KeyValuePair<GoalTriggerWatcher, GoalUI> <kv>5__2;

		object IEnumerator<object>.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		object IEnumerator.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		[DebuggerHidden]
		public <NewGameSequence>d__53(int <>1__state)
		{
			this.<>1__state = <>1__state;
		}

		[DebuggerHidden]
		void IDisposable.Dispose()
		{
			<>s__1 = default(Dictionary<GoalTriggerWatcher, GoalUI>.Enumerator);
			<kv>5__2 = default(KeyValuePair<GoalTriggerWatcher, GoalUI>);
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				<>4__this.UpdateGoalUIText(0, 0);
				<>4__this.UpdateScoreUI(0, 0);
				<>s__1 = <>4__this.goalUIs.GetEnumerator();
				try
				{
					while (<>s__1.MoveNext())
					{
						<kv>5__2 = <>s__1.Current;
						((Graphic)<kv>5__2.Value.bg).color = new Color(0f, 0f, 0f, 0.5f);
						<kv>5__2.Key.Unlock();
						<kv>5__2 = default(KeyValuePair<GoalTriggerWatcher, GoalUI>);
					}
				}
				finally
				{
					((IDisposable)<>s__1).Dispose();
				}
				<>s__1 = default(Dictionary<GoalTriggerWatcher, GoalUI>.Enumerator);
				<>2__current = ((MonoBehaviour)<>4__this).StartCoroutine(<>4__this.ResetBall());
				<>1__state = 1;
				return true;
			case 1:
				<>1__state = -1;
				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();
		}
	}

	[CompilerGenerated]
	private sealed class <ResetBall>d__55 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		public BRC_Football <>4__this;

		private Exception <e>5__1;

		private Exception <e>5__2;

		private Dictionary<GoalTriggerWatcher, GoalUI>.Enumerator <>s__3;

		private KeyValuePair<GoalTriggerWatcher, GoalUI> <kv>5__4;

		object IEnumerator<object>.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		object IEnumerator.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		[DebuggerHidden]
		public <ResetBall>d__55(int <>1__state)
		{
			this.<>1__state = <>1__state;
		}

		[DebuggerHidden]
		void IDisposable.Dispose()
		{
			<e>5__1 = null;
			<e>5__2 = null;
			<>s__3 = default(Dictionary<GoalTriggerWatcher, GoalUI>.Enumerator);
			<kv>5__4 = default(KeyValuePair<GoalTriggerWatcher, GoalUI>);
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Expected O, but got Unknown
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				<>4__this.resetting = true;
				<>4__this.ownershipTransferred = false;
				FootballNet.TemporaryHostId = 0;
				FootballNet.RecalculateHost();
				try
				{
					if ((Object)(object)ballRb != (Object)null)
					{
						ballRb.isKinematic = true;
						if (FootballNet.IsHost)
						{
							ballRb.detectCollisions = false;
						}
					}
					if (FootballNet.IsHost && (Object)(object)ball != (Object)null && (Object)(object)<>4__this.respawn != (Object)null)
					{
						ball.transform.position = <>4__this.respawn.position + Vector3.up * 1.2f;
						if ((Object)(object)ballRb != (Object)null)
						{
							ballRb.velocity = Vector3.zero;
							ballRb.angularVelocity = Vector3.zero;
						}
					}
				}
				catch (Exception ex)
				{
					<e>5__1 = ex;
					((BaseUnityPlugin)<>4__this).Logger.LogError((object)string.Format("{0} ResetBall error before yield: {1}", "[BRC-Football]", <e>5__1));
					<>4__this.resetting = false;
					return false;
				}
				<>2__current = null;
				<>1__state = 1;
				return true;
			case 1:
				<>1__state = -1;
				Physics.SyncTransforms();
				<>2__current = (object)new WaitForSeconds(0.25f);
				<>1__state = 2;
				return true;
			case 2:
				<>1__state = -1;
				try
				{
					if ((Object)(object)ballRb != (Object)null && FootballNet.IsHost)
					{
						ballRb.detectCollisions = true;
					}
					<>4__this.ApplyHostPhysics();
				}
				catch (Exception ex)
				{
					<e>5__2 = ex;
					((BaseUnityPlugin)<>4__this).Logger.LogError((object)string.Format("{0} ResetBall error after yield: {1}", "[BRC-Football]", <e>5__2));
				}
				finally
				{
					<>4__this.resetting = false;
					<>s__3 = <>4__this.goalUIs.GetEnumerator();
					try
					{
						while (<>s__3.MoveNext())
						{
							<kv>5__4 = <>s__3.Current;
							<kv>5__4.Key.Unlock();
							<kv>5__4 = default(KeyValuePair<GoalTriggerWatcher, GoalUI>);
						}
					}
					finally
					{
						((IDisposable)<>s__3).Dispose();
					}
					<>s__3 = default(Dictionary<GoalTriggerWatcher, GoalUI>.Enumerator);
				}
				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();
		}
	}

	[CompilerGenerated]
	private sealed class <SceneDetectRoutine>d__36 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		public BRC_Football <>4__this;

		private float <elapsed>5__1;

		object IEnumerator<object>.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		object IEnumerator.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		[DebuggerHidden]
		public <SceneDetectRoutine>d__36(int <>1__state)
		{
			this.<>1__state = <>1__state;
		}

		[DebuggerHidden]
		void IDisposable.Dispose()
		{
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Expected O, but got Unknown
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Expected O, but got Unknown
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				<>2__current = (object)new WaitForSeconds(1f);
				<>1__state = 1;
				return true;
			case 1:
				<>1__state = -1;
				<elapsed>5__1 = 0f;
				break;
			case 2:
				<>1__state = -1;
				break;
			}
			if (<elapsed>5__1 < 10f)
			{
				ball = GameObject.Find("Football") ?? GameObject.Find("Football(Clone)");
				if (!((Object)(object)ball != (Object)null))
				{
					<elapsed>5__1 += 0.5f;
					<>2__current = (object)new WaitForSeconds(0.5f);
					<>1__state = 2;
					return true;
				}
			}
			<>4__this.isActiveScene = <>4__this.enableMod.Value && (Object)(object)ball != (Object)null;
			if (!<>4__this.isActiveScene)
			{
				((BaseUnityPlugin)<>4__this).Logger.LogInfo((object)"[BRC-Football] No football found, mod inactive.");
				return false;
			}
			((MonoBehaviour)<>4__this).StartCoroutine(<>4__this.Init());
			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 const string LOG = "[BRC-Football]";

	public static BRC_Football Instance;

	private bool isActiveScene = false;

	public static GameObject ball;

	public static Rigidbody ballRb;

	public Transform respawn;

	private int redScore = 0;

	private int blueScore = 0;

	public bool resetting;

	private bool gameOver = false;

	private GoalTeam winningTeam;

	private ConfigEntry<KeyCode> resetKey;

	private ConfigEntry<bool> enableMod;

	private ConfigEntry<int> scoreLimit;

	public float uiScale = 0.01f;

	public Vector2 uiSize = new Vector2(200f, 50f);

	public float uiHeight = 2.5f;

	public Color redColor = Color.red;

	public Color blueColor = Color.blue;

	public float flashDuration = 1.5f;

	private Dictionary<GoalTriggerWatcher, GoalUI> goalUIs = new Dictionary<GoalTriggerWatcher, GoalUI>();

	private GameObject scoreUIRoot;

	private TextMeshProUGUI scoreUIText;

	private Transform scoreAnchor;

	private GameObject countdownUIRoot;

	private TextMeshProUGUI countdownText;

	private Transform countdownAnchor;

	private TMP_Text debugText;

	private float desync;

	private float lastSyncTime;

	private bool ownershipTransferred = false;

	private Queue<BallState> rewindBuffer = new Queue<BallState>();

	private void Awake()
	{
		Instance = this;
		resetKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Keybinds", "ResetBall", (KeyCode)98, "Reset ball / start new game after win");
		enableMod = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "EnableFootball", true, (ConfigDescription)null);
		scoreLimit = ((BaseUnityPlugin)this).Config.Bind<int>("General", "ScoreLimit", 5, "Goals needed to win");
		FootballNet.Init();
		ACNBridge.Init();
		ACNBridge.OnEvent = (Action<string, string, ushort>)Delegate.Combine(ACNBridge.OnEvent, new Action<string, string, ushort>(OnACNEvent));
		ACNBridge.OnBinary = (Action<string, byte[], ushort>)Delegate.Combine(ACNBridge.OnBinary, new Action<string, byte[], ushort>(OnACNBinary));
		SceneManager.sceneLoaded += OnSceneLoaded;
		((BaseUnityPlugin)this).Logger.LogInfo((object)"[BRC-Football] Loaded");
	}

	private void OnDestroy()
	{
		SceneManager.sceneLoaded -= OnSceneLoaded;
		ACNBridge.OnEvent = (Action<string, string, ushort>)Delegate.Remove(ACNBridge.OnEvent, new Action<string, string, ushort>(OnACNEvent));
		ACNBridge.OnBinary = (Action<string, byte[], ushort>)Delegate.Remove(ACNBridge.OnBinary, new Action<string, byte[], ushort>(OnACNBinary));
		ACNBridge.Shutdown();
		Cleanup();
	}

	private void OnSceneLoaded(Scene s, LoadSceneMode m)
	{
		((BaseUnityPlugin)this).Logger.LogInfo((object)("[BRC-Football] Scene loaded: " + ((Scene)(ref s)).name));
		Cleanup();
		((MonoBehaviour)this).StartCoroutine(SceneDetectRoutine());
	}

	[IteratorStateMachine(typeof(<SceneDetectRoutine>d__36))]
	private IEnumerator SceneDetectRoutine()
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <SceneDetectRoutine>d__36(0)
		{
			<>4__this = this
		};
	}

	private void Cleanup()
	{
		if (isActiveScene)
		{
			ACNBridge.AnnounceLeaving();
		}
		((MonoBehaviour)this).StopAllCoroutines();
		isActiveScene = false;
		resetting = false;
		gameOver = false;
		ownershipTransferred = false;
		rewindBuffer.Clear();
		redScore = 0;
		blueScore = 0;
		desync = 0f;
		lastSyncTime = 0f;
		FootballNet.Players.Clear();
		FootballNet.TemporaryHostId = 0;
		FootballNet.RecalculateHost();
		ballRb = null;
		ball = null;
		foreach (KeyValuePair<GoalTriggerWatcher, GoalUI> goalUI in goalUIs)
		{
			if ((Object)(object)goalUI.Value?.root != (Object)null)
			{
				Object.Destroy((Object)(object)goalUI.Value.root);
			}
		}
		goalUIs.Clear();
		if ((Object)(object)scoreUIRoot != (Object)null)
		{
			Object.Destroy((Object)(object)scoreUIRoot);
		}
		scoreUIRoot = null;
		if ((Object)(object)debugText != (Object)null)
		{
			Transform transform = debugText.transform;
			object obj;
			if (transform == null)
			{
				obj = null;
			}
			else
			{
				Transform parent = transform.parent;
				if (parent == null)
				{
					obj = null;
				}
				else
				{
					Transform parent2 = parent.parent;
					obj = ((parent2 != null) ? ((Component)parent2).gameObject : null);
				}
			}
			if ((Object)obj != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)debugText.transform.parent.parent).gameObject);
			}
		}
		debugText = null;
	}

	[IteratorStateMachine(typeof(<Init>d__38))]
	private IEnumerator Init()
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <Init>d__38(0)
		{
			<>4__this = this
		};
	}

	private void ApplyHostPhysics()
	{
		if (!((Object)(object)ballRb == (Object)null))
		{
			if (FootballNet.IsHost)
			{
				ballRb.isKinematic = false;
				ballRb.useGravity = true;
			}
			else
			{
				ballRb.isKinematic = false;
				ballRb.useGravity = false;
			}
		}
	}

	public void OnBecomeHost()
	{
		((BaseUnityPlugin)this).Logger.LogInfo((object)"[BRC-Football] Became host.");
		desync = 0f;
		((MonoBehaviour)this).StartCoroutine(BecomeHostRoutine());
	}

	[IteratorStateMachine(typeof(<BecomeHostRoutine>d__41))]
	private IEnumerator BecomeHostRoutine()
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <BecomeHostRoutine>d__41(0)
		{
			<>4__this = this
		};
	}

	public void OnBecomeClient()
	{
		((BaseUnityPlugin)this).Logger.LogInfo((object)"[BRC-Football] Became client.");
		((MonoBehaviour)this).StartCoroutine(BecomeClientRoutine());
	}

	[IteratorStateMachine(typeof(<BecomeClientRoutine>d__43))]
	private IEnumerator BecomeClientRoutine()
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <BecomeClientRoutine>d__43(0)
		{
			<>4__this = this
		};
	}

	private void CreateGoals()
	{
		Transform[] array = Object.FindObjectsOfType<Transform>(true);
		Transform[] array2 = array;
		foreach (Transform val in array2)
		{
			if (((Object)val).name.Contains("GoalTrigger"))
			{
				GoalTriggerWatcher goalTriggerWatcher = ((Component)val).GetComponent<GoalTriggerWatcher>() ?? ((Component)val).gameObject.AddComponent<GoalTriggerWatcher>();
				if (((Object)val).name.ToLower().Contains("red"))
				{
					goalTriggerWatcher.team = GoalTeam.Red;
				}
				else if (((Object)val).name.ToLower().Contains("blue"))
				{
					goalTriggerWatcher.team = GoalTeam.Blue;
				}
				goalTriggerWatcher.OnGoal = (Action<GoalTeam>)Delegate.Combine(goalTriggerWatcher.OnGoal, new Action<GoalTeam>(OnGoal));
				goalUIs[goalTriggerWatcher] = CreateGoalUI(goalTriggerWatcher);
			}
		}
		((BaseUnityPlugin)this).Logger.LogInfo((object)string.Format("{0} Found {1} goal triggers.", "[BRC-Football]", goalUIs.Count));
	}

	private GoalUI CreateGoalUI(GoalTriggerWatcher w)
	{
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_0017: Expected O, but got Unknown
		//IL_001d: 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_0055: Unknown result type (might be due to invalid IL or missing references)
		//IL_0065: Unknown result type (might be due to invalid IL or missing references)
		//IL_006b: Expected O, but got Unknown
		//IL_009a: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c3: Expected O, but got Unknown
		//IL_0132: Unknown result type (might be due to invalid IL or missing references)
		//IL_011c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0161: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = new GameObject("GoalUI_" + ((Object)w).name);
		val.transform.localScale = Vector3.one * uiScale;
		Canvas val2 = val.AddComponent<Canvas>();
		val2.renderMode = (RenderMode)2;
		val2.worldCamera = Camera.main;
		val.GetComponent<RectTransform>().sizeDelta = uiSize;
		GameObject val3 = new GameObject("BG");
		val3.transform.SetParent(val.transform, false);
		Image val4 = val3.AddComponent<Image>();
		((Graphic)val4).color = new Color(0f, 0f, 0f, 0.5f);
		val3.GetComponent<RectTransform>().sizeDelta = uiSize;
		GameObject val5 = new GameObject("Text");
		val5.transform.SetParent(val.transform, false);
		TextMeshProUGUI val6 = val5.AddComponent<TextMeshProUGUI>();
		((TMP_Text)val6).alignment = (TextAlignmentOptions)514;
		((TMP_Text)val6).fontSize = 32f;
		((TMP_Text)val6).fontStyle = (FontStyles)1;
		((Graphic)val6).color = ((w.team == GoalTeam.Red) ? new Color(1f, 0.3f, 0.3f) : new Color(0.3f, 0.5f, 1f));
		((TMP_Text)val6).text = ((w.team == GoalTeam.Red) ? "RED  0" : "BLUE  0");
		val5.GetComponent<RectTransform>().sizeDelta = uiSize;
		return new GoalUI
		{
			root = val,
			bg = val4,
			text = val6,
			watcher = w
		};
	}

	private void UpdateGoalUIText(int red, int blue)
	{
		foreach (KeyValuePair<GoalTriggerWatcher, GoalUI> goalUI in goalUIs)
		{
			if (goalUI.Key.team == GoalTeam.Red)
			{
				((TMP_Text)goalUI.Value.text).text = $"RED  {red}";
			}
			else
			{
				((TMP_Text)goalUI.Value.text).text = $"BLUE  {blue}";
			}
		}
	}

	private void OnGoal(GoalTeam team)
	{
		if (FootballNet.IsHost && !gameOver)
		{
			if (team == GoalTeam.Red)
			{
				redScore++;
			}
			else
			{
				blueScore++;
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)string.Format("{0} Goal! {1}. Red={2} Blue={3}", "[BRC-Football]", team, redScore, blueScore));
			if ((team == GoalTeam.Red && redScore >= scoreLimit.Value) || (team == GoalTeam.Blue && blueScore >= scoreLimit.Value))
			{
				gameOver = true;
				winningTeam = team;
				ACNBridge.Broadcast("BRCGameOver", $"{team};{redScore};{blueScore}");
				((MonoBehaviour)this).StartCoroutine(HandleGameOver(team, redScore, blueScore));
			}
			else
			{
				ACNBridge.Broadcast("BRCGoal", $"{team};{redScore};{blueScore}");
				((MonoBehaviour)this).StartCoroutine(GoalSequence(team, redScore, blueScore));
			}
		}
	}

	[IteratorStateMachine(typeof(<GoalSequence>d__48))]
	private IEnumerator GoalSequence(GoalTeam team, int red, int blue)
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <GoalSequence>d__48(0)
		{
			<>4__this = this,
			team = team,
			red = red,
			blue = blue
		};
	}

	[IteratorStateMachine(typeof(<Countdown>d__49))]
	private IEnumerator Countdown()
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <Countdown>d__49(0)
		{
			<>4__this = this
		};
	}

	private void CreateCountdownUI()
	{
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_004c: Expected O, but got Unknown
		//IL_006f: 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_0090: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e9: Expected O, but got Unknown
		//IL_0142: Unknown result type (might be due to invalid IL or missing references)
		//IL_0153: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = GameObject.Find("Countdown");
		if ((Object)(object)val == (Object)null)
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)"[BRC-Football] Countdown anchor not found.");
			return;
		}
		countdownAnchor = val.transform;
		countdownUIRoot = new GameObject("CountdownUI");
		countdownUIRoot.transform.SetParent(countdownAnchor, false);
		countdownUIRoot.transform.localScale = Vector3.one * uiScale;
		countdownUIRoot.transform.localPosition = Vector3.zero;
		Vector2 sizeDelta = default(Vector2);
		((Vector2)(ref sizeDelta))..ctor(300f, 120f);
		Canvas val2 = countdownUIRoot.AddComponent<Canvas>();
		val2.renderMode = (RenderMode)2;
		val2.worldCamera = Camera.main;
		countdownUIRoot.GetComponent<RectTransform>().sizeDelta = sizeDelta;
		GameObject val3 = new GameObject("Text");
		val3.transform.SetParent(countdownUIRoot.transform, false);
		countdownText = val3.AddComponent<TextMeshProUGUI>();
		((TMP_Text)countdownText).alignment = (TextAlignmentOptions)514;
		((TMP_Text)countdownText).fontSize = 64f;
		((TMP_Text)countdownText).fontStyle = (FontStyles)1;
		((Graphic)countdownText).color = Color.white;
		val3.GetComponent<RectTransform>().sizeDelta = sizeDelta;
		countdownUIRoot.SetActive(false);
	}

	[IteratorStateMachine(typeof(<HandleGameOver>d__51))]
	private IEnumerator HandleGameOver(GoalTeam winner, int red, int blue)
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <HandleGameOver>d__51(0)
		{
			<>4__this = this,
			winner = winner,
			red = red,
			blue = blue
		};
	}

	private void StartNewGame()
	{
		if (gameOver)
		{
			gameOver = false;
			redScore = 0;
			blueScore = 0;
			ACNBridge.Broadcast("BRCNewGame", "1");
			((MonoBehaviour)this).StartCoroutine(NewGameSequence());
		}
	}

	[IteratorStateMachine(typeof(<NewGameSequence>d__53))]
	private IEnumerator NewGameSequence()
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <NewGameSequence>d__53(0)
		{
			<>4__this = this
		};
	}

	public void TryResetBall()
	{
		if (resetting && !gameOver)
		{
			return;
		}
		if (gameOver)
		{
			if (FootballNet.IsHost)
			{
				StartNewGame();
			}
			else
			{
				ACNBridge.Broadcast("BRCRequestNewGame", "1");
			}
		}
		else if (FootballNet.IsHost)
		{
			((MonoBehaviour)this).StartCoroutine(ResetBall());
		}
		else
		{
			ACNBridge.Broadcast("BRCRequestReset", "1");
		}
	}

	[IteratorStateMachine(typeof(<ResetBall>d__55))]
	private IEnumerator ResetBall()
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <ResetBall>d__55(0)
		{
			<>4__this = this
		};
	}

	private void FlashGoalUI(GoalTeam team)
	{
		foreach (KeyValuePair<GoalTriggerWatcher, GoalUI> goalUI in goalUIs)
		{
			if (goalUI.Key.team == team)
			{
				if (goalUI.Value.flashRoutine != null)
				{
					((MonoBehaviour)this).StopCoroutine(goalUI.Value.flashRoutine);
				}
				goalUI.Value.flashRoutine = ((MonoBehaviour)this).StartCoroutine(FlashGoal(goalUI.Value, team));
			}
		}
	}

	[IteratorStateMachine(typeof(<FlashGoal>d__57))]
	private IEnumerator FlashGoal(GoalUI ui, GoalTeam team)
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <FlashGoal>d__57(0)
		{
			<>4__this = this,
			ui = ui,
			team = team
		};
	}

	private void OnACNBinary(string name, byte[] data, ushort sender)
	{
		//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00be: Unknown result type (might be due to invalid IL or missing references)
		if (name == "BRCBallDelta" && !FootballNet.IsHost)
		{
			lastSyncTime = Time.time;
			GameObject obj = ball;
			if (obj != null)
			{
				obj.GetComponent<BallSyncClient>()?.OnBinary(name, data);
			}
		}
		if (!(name == "BRCKick") || !FootballNet.IsHost)
		{
			return;
		}
		float num = BitConverter.ToSingle(data, 0);
		float num2 = BitConverter.ToSingle(data, 4);
		float num3 = BitConverter.ToSingle(data, 8);
		Vector3 val = default(Vector3);
		((Vector3)(ref val))..ctor(num, num2, num3);
		GameObject obj2 = ball;
		BallSyncHost ballSyncHost = ((obj2 != null) ? obj2.GetComponent<BallSyncHost>() : null);
		if ((Object)(object)ballSyncHost != (Object)null)
		{
			ballSyncHost.ApplyClientKick(val);
			return;
		}
		Rigidbody obj3 = ballRb;
		if (obj3 != null)
		{
			obj3.AddForce(val, (ForceMode)1);
		}
	}

	private void OnACNEvent(string name, string payload, ushort sender)
	{
		//IL_03bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_03b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_03c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_03c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_0450: Unknown result type (might be due to invalid IL or missing references)
		switch (name)
		{
		case "BRCHello":
			if (FootballNet.Players.Contains(sender))
			{
				return;
			}
			FootballNet.Players.Add(sender);
			FootballNet.RecalculateHost();
			((BaseUnityPlugin)this).Logger.LogInfo((object)string.Format("{0} Player {1} joined. Players={2} IsHost={3}", "[BRC-Football]", sender, FootballNet.Players.Count, FootballNet.IsHost));
			ACNBridge.AnnouncePresence();
			if (FootballNet.IsHost)
			{
				ACNBridge.Broadcast("BRCScore", $"{redScore};{blueScore}");
			}
			if (FootballNet.IsHost)
			{
				GameObject obj = ball;
				if ((Object)(object)((obj != null) ? obj.GetComponent<BallSyncHost>() : null) == (Object)null)
				{
					OnBecomeHost();
					return;
				}
			}
			if (!FootballNet.IsHost)
			{
				GameObject obj2 = ball;
				if ((Object)(object)((obj2 != null) ? obj2.GetComponent<BallSyncClient>() : null) == (Object)null)
				{
					OnBecomeClient();
				}
			}
			return;
		case "BRCBye":
			if (FootballNet.Players.Contains(sender))
			{
				ushort lowestKnownId = GetLowestKnownId();
				bool flag = sender == lowestKnownId;
				FootballNet.Players.Remove(sender);
				FootballNet.RecalculateHost();
				((BaseUnityPlugin)this).Logger.LogInfo((object)string.Format("{0} Player {1} left. WasHost={2} NowHost={3}", "[BRC-Football]", sender, flag, FootballNet.IsHost));
				if (flag && FootballNet.IsHost)
				{
					OnBecomeHost();
				}
				else if (flag && !FootballNet.IsHost)
				{
					OnBecomeClient();
				}
			}
			return;
		case "BRCScore":
		{
			string[] array = payload.Split(new char[1] { ';' });
			redScore = int.Parse(array[0]);
			blueScore = int.Parse(array[1]);
			UpdateGoalUIText(redScore, blueScore);
			UpdateScoreUI(redScore, blueScore);
			break;
		}
		}
		if (name == "BRCGoal" && !FootballNet.IsHost)
		{
			string[] array2 = payload.Split(new char[1] { ';' });
			GoalTeam team = (GoalTeam)Enum.Parse(typeof(GoalTeam), array2[0]);
			redScore = int.Parse(array2[1]);
			blueScore = int.Parse(array2[2]);
			UpdateGoalUIText(redScore, blueScore);
			UpdateScoreUI(redScore, blueScore);
			FlashGoalUI(team);
			((MonoBehaviour)this).StartCoroutine(ClientCountdown());
		}
		if (name == "BRCGameOver" && !FootballNet.IsHost)
		{
			string[] array3 = payload.Split(new char[1] { ';' });
			GoalTeam goalTeam = (GoalTeam)Enum.Parse(typeof(GoalTeam), array3[0]);
			redScore = int.Parse(array3[1]);
			blueScore = int.Parse(array3[2]);
			gameOver = true;
			winningTeam = goalTeam;
			UpdateGoalUIText(redScore, blueScore);
			FlashGoalUI(goalTeam);
			string winnerName = ((goalTeam == GoalTeam.Red) ? "RED" : "BLUE");
			Color winColor = ((goalTeam == GoalTeam.Red) ? redColor : blueColor);
			SetScoreUIWin(winnerName, winColor);
		}
		if (name == "BRCNewGame" && !FootballNet.IsHost)
		{
			gameOver = false;
			redScore = 0;
			blueScore = 0;
			UpdateGoalUIText(0, 0);
			UpdateScoreUI(0, 0);
			foreach (KeyValuePair<GoalTriggerWatcher, GoalUI> goalUI in goalUIs)
			{
				((Graphic)goalUI.Value.bg).color = new Color(0f, 0f, 0f, 0.5f);
			}
			((MonoBehaviour)this).StartCoroutine(ResetBall());
		}
		if (name == "BRCBallReset" && !FootballNet.IsHost)
		{
			((MonoBehaviour)this).StartCoroutine(ResetBall());
		}
		if (name == "BRCCountdown" && !FootballNet.IsHost)
		{
			SetScoreUICountdown(payload);
		}
		if (name == "BRCCountdownEnd" && !FootballNet.IsHost)
		{
			UpdateScoreUI(redScore, blueScore);
		}
		if (name == "BRCRequestReset" && FootballNet.IsHost)
		{
			TryResetBall();
		}
		if (name == "BRCRequestNewGame" && FootballNet.IsHost)
		{
			StartNewGame();
		}
	}

	[IteratorStateMachine(typeof(<ClientCountdown>d__60))]
	private IEnumerator ClientCountdown()
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <ClientCountdown>d__60(0)
		{
			<>4__this = this
		};
	}

	private ushort GetLowestKnownId()
	{
		ushort num = FootballNet.LocalId;
		foreach (ushort player in FootballNet.Players)
		{
			if (player < num)
			{
				num = player;
			}
		}
		return num;
	}

	private void CreateScoreUI()
	{
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_004c: Expected O, but got Unknown
		//IL_006f: 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_0090: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e9: Expected O, but got Unknown
		//IL_011f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0130: Unknown result type (might be due to invalid IL or missing references)
		//IL_013c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0143: Expected O, but got Unknown
		//IL_019e: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = GameObject.Find("ResetUI");
		if ((Object)(object)val == (Object)null)
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)"[BRC-Football] ResetUI anchor not found.");
			return;
		}
		scoreAnchor = val.transform;
		scoreUIRoot = new GameObject("ScoreUI");
		scoreUIRoot.transform.SetParent(scoreAnchor, false);
		scoreUIRoot.transform.localScale = Vector3.one * uiScale;
		scoreUIRoot.transform.localPosition = Vector3.zero;
		Vector2 sizeDelta = default(Vector2);
		((Vector2)(ref sizeDelta))..ctor(300f, 80f);
		Canvas val2 = scoreUIRoot.AddComponent<Canvas>();
		val2.renderMode = (RenderMode)2;
		val2.worldCamera = Camera.main;
		scoreUIRoot.GetComponent<RectTransform>().sizeDelta = sizeDelta;
		GameObject val3 = new GameObject("BG");
		val3.transform.SetParent(scoreUIRoot.transform, false);
		Image val4 = val3.AddComponent<Image>();
		((Graphic)val4).color = new Color(0f, 0f, 0f, 0.55f);
		val3.GetComponent<RectTransform>().sizeDelta = sizeDelta;
		GameObject val5 = new GameObject("Text");
		val5.transform.SetParent(scoreUIRoot.transform, false);
		scoreUIText = val5.AddComponent<TextMeshProUGUI>();
		((TMP_Text)scoreUIText).alignment = (TextAlignmentOptions)514;
		((TMP_Text)scoreUIText).fontSize = 28f;
		((TMP_Text)scoreUIText).fontStyle = (FontStyles)1;
		((Graphic)scoreUIText).color = Color.white;
		val5.GetComponent<RectTransform>().sizeDelta = sizeDelta;
		UpdateScoreUI(0, 0);
	}

	private void UpdateScoreUI(int red, int blue)
	{
		//IL_002a: Unknown result type (might be due to invalid IL or missing references)
		//IL_006c: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)scoreUIText == (Object)null))
		{
			((TMP_Text)scoreUIText).fontSize = 28f;
			((Graphic)scoreUIText).color = Color.white;
			((TMP_Text)scoreUIText).text = $"<color=#ff5555>{red}</color>  -  <color=#5599ff>{blue}</color>\n" + $"<size=16>First to {scoreLimit.Value} • {resetKey.Value} to reset</size>";
		}
	}

	private void SetScoreUICountdown(string step)
	{
		//IL_006e: 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)
		if ((Object)(object)countdownUIRoot == (Object)null || (Object)(object)countdownText == (Object)null)
		{
			return;
		}
		countdownUIRoot.SetActive(true);
		((TMP_Text)countdownText).fontSize = ((step == "GO!") ? 72 : 88);
		((Graphic)countdownText).color = ((step == "GO!") ? Color.green : Color.white);
		((TMP_Text)countdownText).text = step;
		if (FootballNet.IsHost)
		{
			if (step == "GO!")
			{
				ACNBridge.Broadcast("BRCCountdownEnd", step);
			}
			else
			{
				ACNBridge.Broadcast("BRCCountdown", step);
			}
		}
	}

	private void SetScoreUIWin(string winnerName, Color winColor)
	{
		//IL_002a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0043: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)scoreUIText == (Object)null))
		{
			((TMP_Text)scoreUIText).fontSize = 32f;
			((Graphic)scoreUIText).color = winColor;
			((TMP_Text)scoreUIText).text = $"{winnerName} WINS!\n<size=16>Press {resetKey.Value} to play again</size>";
		}
	}

	private void Update()
	{
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_005d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0161: Unknown result type (might be due to invalid IL or missing references)
		//IL_0182: Unknown result type (might be due to invalid IL or missing references)
		//IL_0187: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_02aa: Unknown result type (might be due to invalid IL or missing references)
		//IL_02af: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_02bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_02cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_02cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d6: Unknown result type (might be due to invalid IL or missing references)
		//IL_02db: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_0318: Unknown result type (might be due to invalid IL or missing references)
		//IL_0300: Unknown result type (might be due to invalid IL or missing references)
		//IL_034a: 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_037f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0367: Unknown result type (might be due to invalid IL or missing references)
		//IL_039c: Unknown result type (might be due to invalid IL or missing references)
		//IL_03c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_03c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_03c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_03c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_03ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_03de: Unknown result type (might be due to invalid IL or missing references)
		//IL_03e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_03e2: Unknown result type (might be due to invalid IL or missing references)
		if (!isActiveScene || (Object)(object)ball == (Object)null || (Object)(object)ballRb == (Object)null)
		{
			return;
		}
		if (Input.GetKeyDown(resetKey.Value))
		{
			TryResetBall();
		}
		if (FootballNet.IsHost && ball.transform.position.y < -50f && !resetting)
		{
			((MonoBehaviour)this).StartCoroutine(ResetBall());
		}
		if (!FootballNet.IsHost)
		{
			BallSyncClient component = ball.GetComponent<BallSyncClient>();
			desync = (((Object)(object)component != (Object)null) ? component.Desync : 0f);
		}
		else
		{
			desync = 0f;
		}
		if ((Object)(object)debugText != (Object)null)
		{
			TMP_Text obj = debugText;
			string[] obj2 = new string[11]
			{
				"ROLE: ",
				FootballNet.IsHost ? "HOST" : "CLIENT",
				"\n",
				$"Players: {FootballNet.Players.Count}\n",
				$"LocalID: {FootballNet.LocalId}\n",
				$"BallY: {ball.transform.position.y:F2}\n",
				null,
				null,
				null,
				null,
				null
			};
			Vector3 velocity = ballRb.velocity;
			obj2[6] = $"Vel: {((Vector3)(ref velocity)).magnitude:F2}m/s\n";
			obj2[7] = $"Ping: {(FootballNet.IsHost ? 0f : (Time.time - lastSyncTime)):F2}s\n";
			obj2[8] = $"Desync: {desync:F2}m\n";
			obj2[9] = $"Red: {redScore} Blue: {blueScore}\n";
			obj2[10] = $"Resetting: {resetting} GameOver: {gameOver}";
			obj.text = string.Concat(obj2);
		}
		Vector3 val = default(Vector3);
		((Vector3)(ref val))..ctor(-36f, 34f, 57.5f);
		float num = 5f;
		float num2 = 8.5f;
		float num3 = 6.5f;
		float num4 = 11f;
		float num5 = -45f;
		if ((Object)(object)ball != (Object)null && (Object)(object)ballRb != (Object)null && FootballNet.IsHost)
		{
			Quaternion val2 = Quaternion.Euler(0f, num5, 0f);
			Quaternion val3 = Quaternion.Inverse(val2);
			Vector3 val4 = val3 * (ball.transform.position - val);
			Vector3 val5 = val3 * ballRb.velocity;
			bool flag = false;
			if (val4.x > num)
			{
				val4.x = num;
				val5.x = 0f - Mathf.Abs(val5.x);
				flag = true;
			}
			else if (val4.x < 0f - num)
			{
				val4.x = 0f - num;
				val5.x = Mathf.Abs(val5.x);
				flag = true;
			}
			if (val4.z > num4)
			{
				val4.z = num4;
				val5.z = 0f - Mathf.Abs(val5.z);
				flag = true;
			}
			else if (val4.z < 0f - num3)
			{
				val4.z = 0f - num3;
				val5.z = Mathf.Abs(val5.z);
				flag = true;
			}
			if (flag)
			{
				ball.transform.position = val + val2 * val4;
				ballRb.velocity = val2 * val5;
			}
		}
	}

	private void LateUpdate()
	{
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_009e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a3: 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_00b3: Unknown result type (might be due to invalid IL or missing references)
		if (!isActiveScene)
		{
			return;
		}
		Camera main = Camera.main;
		if ((Object)(object)main == (Object)null || ((Component)main).transform.position == Vector3.zero)
		{
			return;
		}
		foreach (KeyValuePair<GoalTriggerWatcher, GoalUI> goalUI in goalUIs)
		{
			GoalUI value = goalUI.Value;
			if (value != null && !((Object)(object)value.root == (Object)null))
			{
				value.root.transform.position = ((Component)value.watcher).transform.position + Vector3.up * uiHeight;
				FaceCamera(value.root, main);
			}
		}
		if ((Object)(object)scoreUIRoot != (Object)null)
		{
			FaceCamera(scoreUIRoot, main);
		}
		if ((Object)(object)countdownUIRoot != (Object)null)
		{
			FaceCamera(countdownUIRoot, main);
		}
	}

	private void FaceCamera(GameObject obj, Camera cam)
	{
		//IL_0020: 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_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_0036: Unknown result type (might be due to invalid IL or missing references)
		//IL_0037: Unknown result type (might be due to invalid IL or missing references)
		//IL_004d: 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)
		if (!((Object)(object)cam == (Object)null) && !((Object)(object)obj == (Object)null))
		{
			Vector3 val = ((Component)cam).transform.position - obj.transform.position;
			if (!(val == Vector3.zero))
			{
				obj.transform.rotation = Quaternion.LookRotation(val);
				obj.transform.Rotate(0f, 180f, 0f);
			}
		}
	}
}
public class FootballDebugUI : MonoBehaviour
{
	private void OnGUI()
	{
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_005b: Unknown result type (might be due to invalid IL or missing references)
		//IL_007e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ac: 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)
		GUI.Label(new Rect(10f, 10f, 400f, 25f), string.Format("Football Role: {0} | PlayerID: {1}", FootballNet.IsHost ? "HOST" : "CLIENT", FootballNet.LocalId));
		Rect val = new Rect(10f, 30f, 400f, 25f);
		GameObject ball = BRC_Football.ball;
		GUI.Label(val, $"Ball Pos: {((ball != null) ? new Vector3?(ball.transform.position) : null)}");
		Rect val2 = new Rect(10f, 50f, 400f, 25f);
		Rigidbody ballRb = BRC_Football.ballRb;
		GUI.Label(val2, $"Ball Vel: {((ballRb != null) ? new Vector3?(ballRb.velocity) : null)}");
	}
}
public static class FootballNet
{
	public static bool IsHost = false;

	public static List<ushort> Players = new List<ushort>();

	public static ushort TemporaryHostId = 0;

	public static ushort LocalId => ACNBridge.LocalId;

	public static void Init()
	{
		RecalculateHost();
	}

	public static void RecalculateHost()
	{
		if (Players.Count == 0)
		{
			IsHost = true;
			return;
		}
		ushort num = LocalId;
		foreach (ushort player in Players)
		{
			if (player < num)
			{
				num = player;
			}
		}
		IsHost = LocalId == num || TemporaryHostId == LocalId;
		Debug.Log((object)$"[FootballNet] Host recalculated. Local={LocalId} Lowest={num} TempHost={TemporaryHostId}");
	}

	public static void SetTemporaryHost(ushort playerId)
	{
		TemporaryHostId = playerId;
		RecalculateHost();
	}

	public static Vector3 GetHostPosition()
	{
		//IL_000f: 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_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_0034: 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)
		if (IsHost)
		{
			return ACNBridge.GetPlayerPosition(LocalId);
		}
		GameObject ball = BRC_Football.ball;
		return (ball != null) ? ball.transform.position : Vector3.zero;
	}

	public static Vector3 GetPlayerPosition(ushort playerId)
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_000a: Unknown result type (might be due to invalid IL or missing references)
		return ACNBridge.GetPlayerPosition(playerId);
	}
}
public class FootballNetTester : MonoBehaviour
{
	private bool visible = false;

	private string log = "";

	private void Update()
	{
		if (Input.GetKeyDown((KeyCode)289))
		{
			visible = !visible;
		}
	}

	private void OnGUI()
	{
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_0134: Unknown result type (might be due to invalid IL or missing references)
		//IL_038d: Unknown result type (might be due to invalid IL or missing references)
		//IL_03a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_03a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_0372: Unknown result type (might be due to invalid IL or missing references)
		//IL_037c: 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_03b7: Unknown result type (might be due to invalid IL or missing references)
		//IL_03cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_03d2: Unknown result type (might be due to invalid IL or missing references)
		if (!visible)
		{
			return;
		}
		GUILayout.BeginArea(new Rect(10f, 100f, 420f, 500f), GUI.skin.box);
		GUILayout.Label("=== Football Net Tester ===", Array.Empty<GUILayoutOption>());
		GUILayout.Space(5f);
		ClientController instance = ClientController.Instance;
		GUILayout.Label($"Connected: {((instance != null) ? new bool?(instance.Connected) : null)}", Array.Empty<GUILayoutOption>());
		GUILayout.Label($"Local ID: {FootballNet.LocalId}", Array.Empty<GUILayoutOption>());
		GUILayout.Label($"Is Host: {FootballNet.IsHost}", Array.Empty<GUILayoutOption>());
		GUILayout.Label($"Players known: {FootballNet.Players.Count}", Array.Empty<GUILayoutOption>());
		GUILayout.Label($"Ball exists: {(Object)(object)BRC_Football.ball != (Object)null}", Array.Empty<GUILayoutOption>());
		GameObject ball = BRC_Football.ball;
		GUILayout.Label($"Ball pos: {((ball != null) ? new Vector3?(ball.transform.position) : null)}", Array.Empty<GUILayoutOption>());
		GUILayout.Space(10f);
		GUILayout.Label("--- Simulate Packets ---", Array.Empty<GUILayoutOption>());
		if (GUILayout.Button("Simulate: BRCBallReset received", Array.Empty<GUILayoutOption>()))
		{
			ACNB