ServerSyncAjustmentSystem.cs 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using KairoEngine.Core;
  5. using Sirenix.OdinInspector;
  6. using UniRx;
  7. namespace KairoEngine.Multiplayer
  8. {
  9. [HideMonoScript]
  10. public class ServerSyncAjustmentSystem : MonoBehaviour
  11. {
  12. public ServerBehaviour server;
  13. public NetworkTick networkTick;
  14. public ClientList clientList;
  15. public int adjustmentInterval = 3000;
  16. public int adjustmentIterations = 10;
  17. private List<PingData> pings = new List<PingData>();
  18. private bool serverIsRunning = false;
  19. private bool adjusting = false;
  20. private int adjustmentIterationCount = 0;
  21. private CompositeDisposable adjustmentLoop;
  22. private void OnEnable()
  23. {
  24. GenericEvents.StartListening($"{server.eventStreamName}_Listening", OnServerStart);
  25. GenericEvents.StartListening($"{server.eventStreamName}_Stopped", OnServerStop);
  26. GenericEvents.StartListening($"{server.eventStreamName}_OnTick", OnTick);
  27. NetMsgEvents.StartListening($"{server.eventStreamName}_PingSent", OnPingSent);
  28. NetMsgEvents.StartListening($"{server.eventStreamName}_PongReceived", OnPongReceived);
  29. }
  30. private void OnDisable()
  31. {
  32. GenericEvents.StopListening($"{server.eventStreamName}_Listening", OnServerStart);
  33. GenericEvents.StopListening($"{server.eventStreamName}_Stopped", OnServerStop);
  34. GenericEvents.StopListening($"{server.eventStreamName}_OnTick", OnTick);
  35. NetMsgEvents.StopListening($"{server.eventStreamName}_PingSent", OnPingSent);
  36. NetMsgEvents.StopListening($"{server.eventStreamName}_PongReceived", OnPongReceived);
  37. }
  38. private void OnServerStart(string text)
  39. {
  40. serverIsRunning = true;
  41. schedualedjustmentCalculation();
  42. }
  43. private void OnServerStop(string text)
  44. {
  45. serverIsRunning = false;
  46. adjustmentLoop.Dispose();
  47. }
  48. private void OnTick(int tick)
  49. {
  50. if(!serverIsRunning) return;
  51. if(!adjusting) return;
  52. for (int i = 0; i < clientList.clients.Count; i++)
  53. {
  54. if(clientList.clients[i].isConnected) PingClient(i);
  55. }
  56. adjustmentIterationCount += 1;
  57. if(adjustmentIterationCount >= adjustmentIterations)
  58. {
  59. // done
  60. adjusting = false;
  61. }
  62. }
  63. private void schedualedjustmentCalculation()
  64. {
  65. adjustmentLoop = Timer.ExecuteRealTime(adjustmentInterval, () => {
  66. if(!serverIsRunning) return;
  67. adjusting = true;
  68. adjustmentIterationCount = 0;
  69. pings = new List<PingData>();
  70. schedualedjustmentCalculation();
  71. });
  72. }
  73. private void PingClient(int i)
  74. {
  75. ClientData client = clientList.clients[i];
  76. NetPingMsg netPingMsg = new NetPingMsg((uint)networkTick.tick);
  77. server.SendNetMsgToClient(client.connectionId, (uint)NetOpCode.Ping, netPingMsg);
  78. PingData ping = new PingData(client.connectionId, networkTick.tick);
  79. pings.Add(ping);
  80. }
  81. private void OnPingSent(string text, int clientId, uint code, NetMsg netMsg)
  82. {
  83. NetPingMsg msg = (NetPingMsg)netMsg;
  84. PingData ping = GetPingData(clientId, (int)msg.pingId);
  85. if(ping != null) ping.startTime = Time.realtimeSinceStartup;
  86. }
  87. private void OnPongReceived(string text, int clientId, uint code, NetMsg netMsg)
  88. {
  89. NetPongMsg msg = (NetPongMsg)netMsg;
  90. PingData ping = GetPingData(clientId, (int)msg.pingId);
  91. if(ping != null)
  92. {
  93. ping.endTime = Time.realtimeSinceStartup;
  94. ClientData clientData = clientList.GetClientData(ping.clientId);
  95. if(clientData != null) clientData.latency = CalculateLatency(clientData.connectionId);
  96. }
  97. else Debug.LogWarning($"Could not find ping data ({(int)msg.pingId})");
  98. }
  99. public PingData GetPingData(int clientId, int pingId)
  100. {
  101. for (int i = 0; i < pings.Count; i++)
  102. {
  103. if(pings[i].clientId == clientId && pings[i].pingId == pingId) return pings[i];
  104. }
  105. return null;
  106. }
  107. public int CalculateLatency(int clientId)
  108. {
  109. int total = 0;
  110. int count = 0;
  111. for (int i = 0; i < pings.Count; i++)
  112. {
  113. if(pings[i].clientId == clientId && pings[i].endTime != 0)
  114. {
  115. total += pings[i].elapsedTime();
  116. count +=1;
  117. }
  118. }
  119. return total/count;
  120. }
  121. }
  122. }