diff --git a/Assets/Scripts/Networking/GameProtocol.cs b/Assets/Scripts/Networking/GameProtocol.cs index 02ade33..109f881 100644 --- a/Assets/Scripts/Networking/GameProtocol.cs +++ b/Assets/Scripts/Networking/GameProtocol.cs @@ -18,6 +18,7 @@ namespace NeonTea.Quakeball.Networking { public GameProtocol(NetInstance instance) { Instance = instance; RegisterPacket(typeof(HelloPckt)); + RegisterPacket(typeof(PingPckt)); RegisterPacket(typeof(SpawnPckt)); RegisterPacket(typeof(SelfIdentPckt)); RegisterPacket(typeof(PlayerUpdatePckt)); diff --git a/Assets/Scripts/Networking/Instances/Client.cs b/Assets/Scripts/Networking/Instances/Client.cs index 8ee47b8..6c6cb96 100644 --- a/Assets/Scripts/Networking/Instances/Client.cs +++ b/Assets/Scripts/Networking/Instances/Client.cs @@ -18,6 +18,10 @@ namespace NeonTea.Quakeball.Networking.Instances { private NetPlayer LocalPlayer; private bool SelfIdentified = false; + public float Ping { get; private set; } + private float LastPingReceived; + private byte LastPingIdent; + public override void Start(string address, int port, PeerMessageListener listener) { if (Peer != null) { return; @@ -81,6 +85,20 @@ namespace NeonTea.Quakeball.Networking.Instances { } else if (packet is PlayerJumpPckt) { PlayerJumpPckt jump = (PlayerJumpPckt)packet; Players[jump.PlayerId].Controlled.Jump(); + } else if (packet is PingPckt) { + PingPckt ping = (PingPckt)packet; + ping.ClientReceived = true; + if (!ping.ServerReceived) { + Peer.SendReliable(Server.uid, ping); + LastPingIdent = ping.Identifier; + LastPingReceived = Time.time; + } else { + if (LastPingIdent == ping.Identifier) { + Ping = Time.time - LastPingReceived; + } else { + Ping = Instances.Server.PingInterval + 0.001f; + } + } } } diff --git a/Assets/Scripts/Networking/Instances/NetInstance.cs b/Assets/Scripts/Networking/Instances/NetInstance.cs index 997dd09..da5800d 100644 --- a/Assets/Scripts/Networking/Instances/NetInstance.cs +++ b/Assets/Scripts/Networking/Instances/NetInstance.cs @@ -22,6 +22,8 @@ namespace NeonTea.Quakeball.Networking.Instances { public abstract void SendPlayerSync(); public abstract void LocalPlayerJump(); + public virtual void Update() { } + public void Stop() { if (Peer != null) { Peer.Stop(); diff --git a/Assets/Scripts/Networking/Instances/Server.cs b/Assets/Scripts/Networking/Instances/Server.cs index 6613bdf..678a175 100644 --- a/Assets/Scripts/Networking/Instances/Server.cs +++ b/Assets/Scripts/Networking/Instances/Server.cs @@ -13,11 +13,14 @@ namespace NeonTea.Quakeball.Networking.Instances { private NetChaperone Net; private Dictionary Players = new Dictionary(); + public List PlayerList { get; private set; } = new List(); private ulong PlayerIdCounter; private NetPlayer LocalPlayer = new NetPlayer(ulong.MaxValue); - private List PlayerList = new List(); + private byte LastPingIdent; + private float LastSentPing; + public static float PingInterval = 1; public override void Start(string address, int port, PeerMessageListener listener) { if (Peer != null) { @@ -96,6 +99,26 @@ namespace NeonTea.Quakeball.Networking.Instances { Players[conn.uid].Unsynced = true; } } + } else if (packet is PingPckt) { + PingPckt ping = (PingPckt)packet; + if (!ping.ServerReceived) { + ping.ServerReceived = true; + Peer.SendReliable(conn.uid, ping); + if (ping.Identifier == LastPingIdent) { + Players[conn.uid].Ping = Time.time - LastSentPing; + } else { + Players[conn.uid].Ping = PingInterval + 0.001f; + } + } + } + } + + public override void Update() { + if (Time.time > LastSentPing + PingInterval) { + LastPingIdent = (byte)((LastPingIdent + 1) % 200); + PingPckt ping = new PingPckt(LastPingIdent); + SendReliableToAll(ping); + LastSentPing = Time.time; } } diff --git a/Assets/Scripts/Networking/NetChaperone.cs b/Assets/Scripts/Networking/NetChaperone.cs index aeee67c..dc1b892 100644 --- a/Assets/Scripts/Networking/NetChaperone.cs +++ b/Assets/Scripts/Networking/NetChaperone.cs @@ -2,7 +2,7 @@ using System; using UnityEngine; using NeonTea.Quakeball.Interface; -using NeonTea.Quakeball.Networking; +using NeonTea.Quakeball.Networking.Instances; using NeonTea.Quakeball.TeaNet.Peers; namespace NeonTea.Quakeball.Networking { @@ -25,12 +25,14 @@ namespace NeonTea.Quakeball.Networking { Terminal = Terminal.Singleton; Terminal.RegisterCommand("host", Host, "host [port] [address] - Hosts server at given address and port."); Terminal.RegisterCommand("join", Join, "join [address] [port] - Tries to join a server at given address and port."); + Terminal.RegisterCommand("ping", Ping, "ping - return the current ping to any connection(s)."); } } private void Update() { if (Net.Singleton.Instance != null) { Net.Singleton.Instance.Peer.Update(); + Net.Singleton.Instance.Update(); } if (Terminal != null && Terminal.isActiveAndEnabled) { while (MessageQueue.Count > 0) { @@ -81,6 +83,24 @@ namespace NeonTea.Quakeball.Networking { return true; } + private bool Ping(string[] args) { + if (Net.Singleton.Instance == null) { + Terminal.Println("No hosting or connecting has been done!"); + return false; + } + if (Net.Singleton.Instance is Client) { + int ping = (int)(((Client)Net.Singleton.Instance).Ping * 1000); + Terminal.Println($"Ping: {ping}ms"); + } else if (Net.Singleton.Instance is Server) { + Server s = (Server)Net.Singleton.Instance; + foreach (NetPlayer p in s.PlayerList) { + int ping = (int)(p.Ping * 1000); + Terminal.Println($"Ping for {p.Id}: {ping}ms"); + } + } + return true; + } + public void Message(string msg) { MessageQueue.Enqueue(msg); } diff --git a/Assets/Scripts/Networking/NetPlayer.cs b/Assets/Scripts/Networking/NetPlayer.cs index f3500a2..9df32df 100644 --- a/Assets/Scripts/Networking/NetPlayer.cs +++ b/Assets/Scripts/Networking/NetPlayer.cs @@ -6,6 +6,7 @@ namespace NeonTea.Quakeball.Networking { public ulong Id; public Player Controlled; public bool Unsynced = false; + public float Ping = 0; public NetPlayer(ulong id, Player obj = null) { Id = id; diff --git a/Assets/Scripts/Networking/Packets/PingPckt.cs b/Assets/Scripts/Networking/Packets/PingPckt.cs new file mode 100644 index 0000000..150f274 --- /dev/null +++ b/Assets/Scripts/Networking/Packets/PingPckt.cs @@ -0,0 +1,31 @@ + +using NeonTea.Quakeball.TeaNet.Packets; + +namespace NeonTea.Quakeball.Networking.Packets { + public class PingPckt : Packet { + + public byte Identifier; + public bool ServerReceived = false; + public bool ClientReceived = false; + + public PingPckt() { } + public PingPckt(byte identifier) { + Identifier = identifier; + } + + public override void Read(ByteBuffer buffer) { + Identifier = buffer.Read(); + byte result = buffer.Read(); + ServerReceived = (result & 1) == 1; + ClientReceived = (result & 2) == 1; + } + + public override void Write(ByteBuffer buffer) { + buffer.Write(Identifier); + byte serverFlag = ServerReceived ? (byte)1 : (byte)0; + byte clientFlag = ClientReceived ? (byte)2 : (byte)0; + byte total = (byte)(serverFlag | clientFlag); + buffer.Write(total); + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Networking/Packets/PingPckt.cs.meta b/Assets/Scripts/Networking/Packets/PingPckt.cs.meta new file mode 100644 index 0000000..15b4d13 --- /dev/null +++ b/Assets/Scripts/Networking/Packets/PingPckt.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1f47d2ea4b65e4849938985989e54a12 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Players/Player.cs b/Assets/Scripts/Players/Player.cs index 6423c5d..b1706cb 100644 --- a/Assets/Scripts/Players/Player.cs +++ b/Assets/Scripts/Players/Player.cs @@ -94,7 +94,6 @@ namespace NeonTea.Quakeball.Players { transform.position = syncPckt.Location; GroundVelocity = syncPckt.GroundVelocity; } - Terminal.Singleton.Println($"Processing sync: {syncPckt.Unsynced}"); return ShouldApply; }