From 3b0d7b592c12f7b4d1f86bea769c8a5bd7173cec Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Albin=20Cor=C3=A9n?= <2108U9@gmail.com>
Date: Tue, 10 Apr 2018 20:31:24 +0200
Subject: [PATCH] Added NetworkTime resync option
---
MLAPI/Data/NetworkConfig.cs | 4 ++
.../MonoBehaviours/Core/NetworkedBehaviour.cs | 4 +-
.../MonoBehaviours/Core/NetworkingManager.cs | 69 ++++++++++++++++---
MLAPI/MonoBehaviours/Core/TrackedObject.cs | 8 +--
.../Prototyping/NetworkedAnimator.cs | 4 +-
.../Prototyping/NetworkedNavMeshAgent.cs | 4 +-
.../Prototyping/NetworkedTransform.cs | 4 +-
7 files changed, 77 insertions(+), 20 deletions(-)
diff --git a/MLAPI/Data/NetworkConfig.cs b/MLAPI/Data/NetworkConfig.cs
index 0a27b63..c49b806 100644
--- a/MLAPI/Data/NetworkConfig.cs
+++ b/MLAPI/Data/NetworkConfig.cs
@@ -135,6 +135,10 @@ namespace MLAPI.Data
/// Wheter or not to enable scene switching
///
public bool EnableSceneSwitching = true;
+ ///
+ /// If your logic uses the NetwokrTime, this should probably be turned off. If however it's needed to maximize accuracy, this is recommended to be turned on
+ ///
+ public bool EnableTimeResync = false;
private byte[] ConfigHash = null;
///
diff --git a/MLAPI/MonoBehaviours/Core/NetworkedBehaviour.cs b/MLAPI/MonoBehaviours/Core/NetworkedBehaviour.cs
index 523b2a3..4d97a46 100644
--- a/MLAPI/MonoBehaviours/Core/NetworkedBehaviour.cs
+++ b/MLAPI/MonoBehaviours/Core/NetworkedBehaviour.cs
@@ -460,7 +460,7 @@ namespace MLAPI.MonoBehaviours.Core
if (!syncVarInit)
SyncVarInit();
SetDirtyness();
- if(Time.time - lastSyncTime >= SyncVarSyncDelay)
+ if(NetworkingManager.singleton.NetworkTime - lastSyncTime >= SyncVarSyncDelay)
{
byte dirtyCount = 0;
for (byte i = 0; i < dirtyFields.Length; i++)
@@ -557,7 +557,7 @@ namespace MLAPI.MonoBehaviours.Core
}
NetworkingManager.singleton.Send("MLAPI_SYNC_VAR_UPDATE", "MLAPI_INTERNAL", stream.ToArray());
}
- lastSyncTime = Time.time;
+ lastSyncTime = NetworkingManager.singleton.NetworkTime;
}
}
diff --git a/MLAPI/MonoBehaviours/Core/NetworkingManager.cs b/MLAPI/MonoBehaviours/Core/NetworkingManager.cs
index 021640c..16a1753 100644
--- a/MLAPI/MonoBehaviours/Core/NetworkingManager.cs
+++ b/MLAPI/MonoBehaviours/Core/NetworkingManager.cs
@@ -311,6 +311,11 @@ namespace MLAPI.MonoBehaviours.Core
{
Name = "MLAPI_NAV_AGENT_CORRECTION",
Type = QosType.StateUpdate
+ },
+ new Channel()
+ {
+ Name = "MLAPI_TIME_SYNC",
+ Type = QosType.Unreliable
}
};
@@ -361,6 +366,7 @@ namespace MLAPI.MonoBehaviours.Core
MessageManager.messageTypes.Add("MLAPI_CHANGE_OWNER", 8);
MessageManager.messageTypes.Add("MLAPI_SYNC_VAR_UPDATE", 9);
MessageManager.messageTypes.Add("MLAPI_ADD_OBJECTS", 10);
+ MessageManager.messageTypes.Add("MLAPI_TIME_SYNC", 11);
List messageTypes = new List(NetworkConfig.MessageTypes)
{
@@ -656,11 +662,12 @@ namespace MLAPI.MonoBehaviours.Core
private float lastReceiveTickTime;
private float lastSendTickTime;
private float lastEventTickTime;
+ private float lastTimeSyncTime;
private void Update()
{
if(isListening)
{
- if((Time.time - lastSendTickTime >= (1f / NetworkConfig.SendTickrate)) || NetworkConfig.SendTickrate <= 0)
+ if((NetworkTime - lastSendTickTime >= (1f / NetworkConfig.SendTickrate)) || NetworkConfig.SendTickrate <= 0)
{
foreach (KeyValuePair pair in connectedClients)
{
@@ -671,9 +678,9 @@ namespace MLAPI.MonoBehaviours.Core
byte error;
NetworkTransport.SendQueuedMessages(netId.HostId, netId.ConnectionId, out error);
}
- lastSendTickTime = Time.time;
+ lastSendTickTime = NetworkTime;
}
- if((Time.time - lastReceiveTickTime >= (1f / NetworkConfig.ReceiveTickrate)) || NetworkConfig.ReceiveTickrate <= 0)
+ if((NetworkTime - lastReceiveTickTime >= (1f / NetworkConfig.ReceiveTickrate)) || NetworkConfig.ReceiveTickrate <= 0)
{
NetworkEventType eventType;
int processedEvents = 0;
@@ -766,23 +773,31 @@ namespace MLAPI.MonoBehaviours.Core
}
// Only do another iteration if: there are no more messages AND (there is no limit to max events or we have processed less than the maximum)
} while (eventType != NetworkEventType.Nothing && (NetworkConfig.MaxReceiveEventsPerTickRate <= 0 || processedEvents < NetworkConfig.MaxReceiveEventsPerTickRate));
- lastReceiveTickTime = Time.time;
+ lastReceiveTickTime = NetworkTime;
}
- if (isServer && ((Time.time - lastEventTickTime >= (1f / NetworkConfig.EventTickrate)) || NetworkConfig.EventTickrate <= 0))
+
+ if (isServer && ((NetworkTime - lastEventTickTime >= (1f / NetworkConfig.EventTickrate)) || NetworkConfig.EventTickrate <= 0))
{
LagCompensationManager.AddFrames();
NetworkedObject.InvokeSyncvarUpdate();
- lastEventTickTime = Time.time;
+ lastEventTickTime = NetworkTime;
}
+
+ if (NetworkConfig.EnableTimeResync && NetworkTime - lastTimeSyncTime >= 30)
+ {
+ SyncTime();
+ lastTimeSyncTime = NetworkTime;
+ }
+
networkTime += Time.deltaTime;
}
}
private IEnumerator ApprovalTimeout(uint clientId)
{
- float timeStarted = Time.time;
+ float timeStarted = NetworkTime;
//We yield every frame incase a pending client disconnects and someone else gets its connection id
- while (Time.time - timeStarted < NetworkConfig.ClientConnectionBufferTimeout && pendingClients.Contains(clientId))
+ while (NetworkTime - timeStarted < NetworkConfig.ClientConnectionBufferTimeout && pendingClients.Contains(clientId))
{
yield return null;
}
@@ -1335,6 +1350,26 @@ namespace MLAPI.MonoBehaviours.Core
}
}
+ break;
+ case 11:
+ if (isClient)
+ {
+ using (MemoryStream messageReadStream = new MemoryStream(incommingData))
+ {
+ using (BinaryReader messageReader = new BinaryReader(messageReadStream))
+ {
+ float netTime = messageReader.ReadSingle();
+ int timestamp = messageReader.ReadInt32();
+
+ NetId netId = new NetId(clientId);
+ byte error;
+ int msDelay = NetworkTransport.GetRemoteDelayTimeMS(netId.HostId, netId.ConnectionId, timestamp, out error);
+ if ((NetworkError)error != NetworkError.Ok)
+ msDelay = 0;
+ networkTime = netTime + (msDelay / 1000f);
+ }
+ }
+ }
break;
}
#endregion
@@ -1725,6 +1760,24 @@ namespace MLAPI.MonoBehaviours.Core
}
}
+ private void SyncTime()
+ {
+ using (MemoryStream stream = new MemoryStream(8))
+ {
+ using (BinaryWriter writer = new BinaryWriter(stream))
+ {
+ writer.Write(NetworkTime);
+ int timestamp = NetworkTransport.GetNetworkTimestamp();
+ writer.Write(timestamp);
+ }
+
+ foreach (KeyValuePair pair in connectedClients)
+ {
+ Send("MLAPI_TIME_SYNC", "MLAPI_TIME_SYNC", stream.GetBuffer());
+ }
+ }
+ }
+
private void HandleApproval(uint clientId, bool approved)
{
if(approved)
diff --git a/MLAPI/MonoBehaviours/Core/TrackedObject.cs b/MLAPI/MonoBehaviours/Core/TrackedObject.cs
index eecb992..716c2d5 100644
--- a/MLAPI/MonoBehaviours/Core/TrackedObject.cs
+++ b/MLAPI/MonoBehaviours/Core/TrackedObject.cs
@@ -48,7 +48,7 @@ namespace MLAPI.MonoBehaviours.Core
{
savedPosition = transform.position;
savedRotation = transform.rotation;
- float currentTime = Time.time;
+ float currentTime = NetworkingManager.singleton.NetworkTime;
float targetTime = currentTime - secondsAgo;
float previousTime = 0;
float nextTime = 0;
@@ -97,7 +97,7 @@ namespace MLAPI.MonoBehaviours.Core
internal void AddFrame()
{
- float currentTime = Time.time;
+ float currentTime = NetworkingManager.singleton.NetworkTime;
LinkedListNode node = Framekeys.First;
LinkedListNode nextNode = node.Next;
while (node != null && currentTime - node.Value >= NetworkingManager.singleton.NetworkConfig.SecondsHistory)
@@ -107,12 +107,12 @@ namespace MLAPI.MonoBehaviours.Core
Framekeys.RemoveFirst();
node = nextNode;
}
- FrameData.Add(Time.time, new TrackedPointData()
+ FrameData.Add(NetworkingManager.singleton.NetworkTime, new TrackedPointData()
{
position = transform.position,
rotation = transform.rotation
});
- Framekeys.AddLast(Time.time);
+ Framekeys.AddLast(NetworkingManager.singleton.NetworkTime);
}
}
}
diff --git a/MLAPI/MonoBehaviours/Prototyping/NetworkedAnimator.cs b/MLAPI/MonoBehaviours/Prototyping/NetworkedAnimator.cs
index c968874..049e850 100644
--- a/MLAPI/MonoBehaviours/Prototyping/NetworkedAnimator.cs
+++ b/MLAPI/MonoBehaviours/Prototyping/NetworkedAnimator.cs
@@ -193,9 +193,9 @@ namespace MLAPI.MonoBehaviours.Prototyping
private void CheckSendRate()
{
- if (sendMessagesAllowed && sendRate != 0 && sendTimer < Time.time)
+ if (sendMessagesAllowed && sendRate != 0 && sendTimer < NetworkingManager.singleton.NetworkTime)
{
- sendTimer = Time.time + sendRate;
+ sendTimer = NetworkingManager.singleton.NetworkTime + sendRate;
using(MemoryStream stream = new MemoryStream())
{
diff --git a/MLAPI/MonoBehaviours/Prototyping/NetworkedNavMeshAgent.cs b/MLAPI/MonoBehaviours/Prototyping/NetworkedNavMeshAgent.cs
index 2958bc9..8fb2856 100644
--- a/MLAPI/MonoBehaviours/Prototyping/NetworkedNavMeshAgent.cs
+++ b/MLAPI/MonoBehaviours/Prototyping/NetworkedNavMeshAgent.cs
@@ -100,7 +100,7 @@ namespace MLAPI.MonoBehaviours.Prototyping
}
}
- if(Time.time - lastCorrectionTime >= CorrectionDelay)
+ if(NetworkingManager.singleton.NetworkTime - lastCorrectionTime >= CorrectionDelay)
{
using (MemoryStream stream = new MemoryStream(correctionBuffer))
{
@@ -130,7 +130,7 @@ namespace MLAPI.MonoBehaviours.Prototyping
SendToClientsTarget(proximityClients, "MLAPI_OnNavMeshCorrectionUpdate", "MLAPI_NAV_AGENT_CORRECTION", correctionBuffer);
}
}
- lastCorrectionTime = Time.time;
+ lastCorrectionTime = NetworkingManager.singleton.NetworkTime;
}
}
diff --git a/MLAPI/MonoBehaviours/Prototyping/NetworkedTransform.cs b/MLAPI/MonoBehaviours/Prototyping/NetworkedTransform.cs
index c453572..e6f2458 100644
--- a/MLAPI/MonoBehaviours/Prototyping/NetworkedTransform.cs
+++ b/MLAPI/MonoBehaviours/Prototyping/NetworkedTransform.cs
@@ -101,9 +101,9 @@ namespace MLAPI.MonoBehaviours.Prototyping
if(isOwner || isLocalPlayer || (new NetId(ownerClientId).IsInvalid() && isServer))
{
//We own the object OR we are server and the object is not owned by anyone OR we are the object.
- if(Time.time - lastSendTime >= timeForLerp && (Vector3.Distance(transform.position, lastSentPos) > MinMeters || Quaternion.Angle(transform.rotation, lastSentRot) > MinDegrees))
+ if(NetworkingManager.singleton.NetworkTime - lastSendTime >= timeForLerp && (Vector3.Distance(transform.position, lastSentPos) > MinMeters || Quaternion.Angle(transform.rotation, lastSentRot) > MinDegrees))
{
- lastSendTime = Time.time;
+ lastSendTime = NetworkingManager.singleton.NetworkTime;
lastSentPos = transform.position;
lastSentRot = transform.rotation;
using (MemoryStream writeStream = new MemoryStream(positionUpdateBuffer))