|
@@ -0,0 +1,135 @@
|
|
|
+using System.Collections;
|
|
|
+using System.Collections.Generic;
|
|
|
+using UnityEngine;
|
|
|
+using KairoEngine.Core;
|
|
|
+using Sirenix.OdinInspector;
|
|
|
+using UniRx;
|
|
|
+
|
|
|
+namespace KairoEngine.Multiplayer
|
|
|
+{
|
|
|
+ [HideMonoScript]
|
|
|
+ public class ServerSyncAjustmentSystem : MonoBehaviour
|
|
|
+ {
|
|
|
+ public ServerBehaviour server;
|
|
|
+ public NetworkTick networkTick;
|
|
|
+ public ClientList clientList;
|
|
|
+ public int adjustmentInterval = 3000;
|
|
|
+ public int adjustmentIterations = 10;
|
|
|
+
|
|
|
+ private List<PingData> pings = new List<PingData>();
|
|
|
+ private bool serverIsRunning = false;
|
|
|
+ private bool adjusting = false;
|
|
|
+ private int adjustmentIterationCount = 0;
|
|
|
+ private CompositeDisposable adjustmentLoop;
|
|
|
+
|
|
|
+ private void OnEnable()
|
|
|
+ {
|
|
|
+ GenericEvents.StartListening($"{server.eventStreamName}_Listening", OnServerStart);
|
|
|
+ GenericEvents.StartListening($"{server.eventStreamName}_Stopped", OnServerStop);
|
|
|
+ GenericEvents.StartListening($"{server.eventStreamName}_OnTick", OnTick);
|
|
|
+ NetMsgEvents.StartListening($"{server.eventStreamName}_PingSent", OnPingSent);
|
|
|
+ NetMsgEvents.StartListening($"{server.eventStreamName}_PongReceived", OnPongReceived);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void OnDisable()
|
|
|
+ {
|
|
|
+ GenericEvents.StopListening($"{server.eventStreamName}_Listening", OnServerStart);
|
|
|
+ GenericEvents.StopListening($"{server.eventStreamName}_Stopped", OnServerStop);
|
|
|
+ GenericEvents.StopListening($"{server.eventStreamName}_OnTick", OnTick);
|
|
|
+ NetMsgEvents.StopListening($"{server.eventStreamName}_PingSent", OnPingSent);
|
|
|
+ NetMsgEvents.StopListening($"{server.eventStreamName}_PongReceived", OnPongReceived);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void OnServerStart(string text)
|
|
|
+ {
|
|
|
+ serverIsRunning = true;
|
|
|
+ schedualedjustmentCalculation();
|
|
|
+ }
|
|
|
+
|
|
|
+ private void OnServerStop(string text)
|
|
|
+ {
|
|
|
+ serverIsRunning = false;
|
|
|
+ adjustmentLoop.Dispose();
|
|
|
+ }
|
|
|
+
|
|
|
+ private void OnTick(int tick)
|
|
|
+ {
|
|
|
+ if(!serverIsRunning) return;
|
|
|
+ if(!adjusting) return;
|
|
|
+ for (int i = 0; i < clientList.clients.Count; i++)
|
|
|
+ {
|
|
|
+ if(clientList.clients[i].isConnected) PingClient(i);
|
|
|
+ }
|
|
|
+ adjustmentIterationCount += 1;
|
|
|
+ if(adjustmentIterationCount >= adjustmentIterations)
|
|
|
+ {
|
|
|
+ // done
|
|
|
+ adjusting = false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void schedualedjustmentCalculation()
|
|
|
+ {
|
|
|
+ adjustmentLoop = Timer.ExecuteRealTime(adjustmentInterval, () => {
|
|
|
+ if(!serverIsRunning) return;
|
|
|
+ adjusting = true;
|
|
|
+ adjustmentIterationCount = 0;
|
|
|
+ schedualedjustmentCalculation();
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ private void PingClient(int i)
|
|
|
+ {
|
|
|
+ ClientData client = clientList.clients[i];
|
|
|
+ NetPingMsg netPingMsg = new NetPingMsg((uint)networkTick.tick);
|
|
|
+ server.SendNetMsgToClient(client.connectionId, (uint)NetOpCode.Ping, netPingMsg);
|
|
|
+ PingData ping = new PingData(client.connectionId, networkTick.tick);
|
|
|
+ pings.Add(ping);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void OnPingSent(string text, int clientId, uint code, NetMsg netMsg)
|
|
|
+ {
|
|
|
+ NetPingMsg msg = (NetPingMsg)netMsg;
|
|
|
+ PingData ping = GetPingData(clientId, (int)msg.pingId);
|
|
|
+ if(ping != null) ping.startTime = Time.realtimeSinceStartup;
|
|
|
+ }
|
|
|
+
|
|
|
+ private void OnPongReceived(string text, int clientId, uint code, NetMsg netMsg)
|
|
|
+ {
|
|
|
+ NetPongMsg msg = (NetPongMsg)netMsg;
|
|
|
+ PingData ping = GetPingData(clientId, (int)msg.pingId);
|
|
|
+ if(ping != null)
|
|
|
+ {
|
|
|
+ ping.endTime = Time.realtimeSinceStartup;
|
|
|
+ ClientData clientData = clientList.GetClientData(ping.clientId);
|
|
|
+ if(clientData != null) clientData.latency = CalculateLatency(clientData.connectionId);
|
|
|
+ }
|
|
|
+ else Debug.LogWarning($"Could not find ping data ({(int)msg.pingId})");
|
|
|
+ }
|
|
|
+
|
|
|
+ public PingData GetPingData(int clientId, int pingId)
|
|
|
+ {
|
|
|
+ for (int i = 0; i < pings.Count; i++)
|
|
|
+ {
|
|
|
+ if(pings[i].clientId == clientId && pings[i].pingId == pingId) return pings[i];
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ public int CalculateLatency(int clientId)
|
|
|
+ {
|
|
|
+ int total = 0;
|
|
|
+ int count = 0;
|
|
|
+ for (int i = 0; i < pings.Count; i++)
|
|
|
+ {
|
|
|
+ if(pings[i].clientId == clientId && pings[i].endTime != 0)
|
|
|
+ {
|
|
|
+ total += pings[i].elapsedTime();
|
|
|
+ count +=1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return total/count;
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+}
|