Added NetworkTime resync option

This commit is contained in:
Albin Corén 2018-04-10 20:31:24 +02:00
parent ac31f46089
commit 3b0d7b592c
7 changed files with 77 additions and 20 deletions

View File

@ -135,6 +135,10 @@ namespace MLAPI.Data
/// Wheter or not to enable scene switching /// Wheter or not to enable scene switching
/// </summary> /// </summary>
public bool EnableSceneSwitching = true; public bool EnableSceneSwitching = true;
/// <summary>
/// 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
/// </summary>
public bool EnableTimeResync = false;
private byte[] ConfigHash = null; private byte[] ConfigHash = null;
/// <summary> /// <summary>

View File

@ -460,7 +460,7 @@ namespace MLAPI.MonoBehaviours.Core
if (!syncVarInit) if (!syncVarInit)
SyncVarInit(); SyncVarInit();
SetDirtyness(); SetDirtyness();
if(Time.time - lastSyncTime >= SyncVarSyncDelay) if(NetworkingManager.singleton.NetworkTime - lastSyncTime >= SyncVarSyncDelay)
{ {
byte dirtyCount = 0; byte dirtyCount = 0;
for (byte i = 0; i < dirtyFields.Length; i++) 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()); NetworkingManager.singleton.Send("MLAPI_SYNC_VAR_UPDATE", "MLAPI_INTERNAL", stream.ToArray());
} }
lastSyncTime = Time.time; lastSyncTime = NetworkingManager.singleton.NetworkTime;
} }
} }

View File

@ -311,6 +311,11 @@ namespace MLAPI.MonoBehaviours.Core
{ {
Name = "MLAPI_NAV_AGENT_CORRECTION", Name = "MLAPI_NAV_AGENT_CORRECTION",
Type = QosType.StateUpdate 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_CHANGE_OWNER", 8);
MessageManager.messageTypes.Add("MLAPI_SYNC_VAR_UPDATE", 9); MessageManager.messageTypes.Add("MLAPI_SYNC_VAR_UPDATE", 9);
MessageManager.messageTypes.Add("MLAPI_ADD_OBJECTS", 10); MessageManager.messageTypes.Add("MLAPI_ADD_OBJECTS", 10);
MessageManager.messageTypes.Add("MLAPI_TIME_SYNC", 11);
List<MessageType> messageTypes = new List<MessageType>(NetworkConfig.MessageTypes) List<MessageType> messageTypes = new List<MessageType>(NetworkConfig.MessageTypes)
{ {
@ -656,11 +662,12 @@ namespace MLAPI.MonoBehaviours.Core
private float lastReceiveTickTime; private float lastReceiveTickTime;
private float lastSendTickTime; private float lastSendTickTime;
private float lastEventTickTime; private float lastEventTickTime;
private float lastTimeSyncTime;
private void Update() private void Update()
{ {
if(isListening) if(isListening)
{ {
if((Time.time - lastSendTickTime >= (1f / NetworkConfig.SendTickrate)) || NetworkConfig.SendTickrate <= 0) if((NetworkTime - lastSendTickTime >= (1f / NetworkConfig.SendTickrate)) || NetworkConfig.SendTickrate <= 0)
{ {
foreach (KeyValuePair<uint, NetworkedClient> pair in connectedClients) foreach (KeyValuePair<uint, NetworkedClient> pair in connectedClients)
{ {
@ -671,9 +678,9 @@ namespace MLAPI.MonoBehaviours.Core
byte error; byte error;
NetworkTransport.SendQueuedMessages(netId.HostId, netId.ConnectionId, out 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; NetworkEventType eventType;
int processedEvents = 0; 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) // 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)); } 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(); LagCompensationManager.AddFrames();
NetworkedObject.InvokeSyncvarUpdate(); NetworkedObject.InvokeSyncvarUpdate();
lastEventTickTime = Time.time; lastEventTickTime = NetworkTime;
} }
if (NetworkConfig.EnableTimeResync && NetworkTime - lastTimeSyncTime >= 30)
{
SyncTime();
lastTimeSyncTime = NetworkTime;
}
networkTime += Time.deltaTime; networkTime += Time.deltaTime;
} }
} }
private IEnumerator ApprovalTimeout(uint clientId) 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 //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; 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; break;
} }
#endregion #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<uint, NetworkedClient> pair in connectedClients)
{
Send("MLAPI_TIME_SYNC", "MLAPI_TIME_SYNC", stream.GetBuffer());
}
}
}
private void HandleApproval(uint clientId, bool approved) private void HandleApproval(uint clientId, bool approved)
{ {
if(approved) if(approved)

View File

@ -48,7 +48,7 @@ namespace MLAPI.MonoBehaviours.Core
{ {
savedPosition = transform.position; savedPosition = transform.position;
savedRotation = transform.rotation; savedRotation = transform.rotation;
float currentTime = Time.time; float currentTime = NetworkingManager.singleton.NetworkTime;
float targetTime = currentTime - secondsAgo; float targetTime = currentTime - secondsAgo;
float previousTime = 0; float previousTime = 0;
float nextTime = 0; float nextTime = 0;
@ -97,7 +97,7 @@ namespace MLAPI.MonoBehaviours.Core
internal void AddFrame() internal void AddFrame()
{ {
float currentTime = Time.time; float currentTime = NetworkingManager.singleton.NetworkTime;
LinkedListNode<float> node = Framekeys.First; LinkedListNode<float> node = Framekeys.First;
LinkedListNode<float> nextNode = node.Next; LinkedListNode<float> nextNode = node.Next;
while (node != null && currentTime - node.Value >= NetworkingManager.singleton.NetworkConfig.SecondsHistory) while (node != null && currentTime - node.Value >= NetworkingManager.singleton.NetworkConfig.SecondsHistory)
@ -107,12 +107,12 @@ namespace MLAPI.MonoBehaviours.Core
Framekeys.RemoveFirst(); Framekeys.RemoveFirst();
node = nextNode; node = nextNode;
} }
FrameData.Add(Time.time, new TrackedPointData() FrameData.Add(NetworkingManager.singleton.NetworkTime, new TrackedPointData()
{ {
position = transform.position, position = transform.position,
rotation = transform.rotation rotation = transform.rotation
}); });
Framekeys.AddLast(Time.time); Framekeys.AddLast(NetworkingManager.singleton.NetworkTime);
} }
} }
} }

View File

@ -193,9 +193,9 @@ namespace MLAPI.MonoBehaviours.Prototyping
private void CheckSendRate() 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()) using(MemoryStream stream = new MemoryStream())
{ {

View File

@ -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)) using (MemoryStream stream = new MemoryStream(correctionBuffer))
{ {
@ -130,7 +130,7 @@ namespace MLAPI.MonoBehaviours.Prototyping
SendToClientsTarget(proximityClients, "MLAPI_OnNavMeshCorrectionUpdate", "MLAPI_NAV_AGENT_CORRECTION", correctionBuffer); SendToClientsTarget(proximityClients, "MLAPI_OnNavMeshCorrectionUpdate", "MLAPI_NAV_AGENT_CORRECTION", correctionBuffer);
} }
} }
lastCorrectionTime = Time.time; lastCorrectionTime = NetworkingManager.singleton.NetworkTime;
} }
} }

View File

@ -101,9 +101,9 @@ namespace MLAPI.MonoBehaviours.Prototyping
if(isOwner || isLocalPlayer || (new NetId(ownerClientId).IsInvalid() && isServer)) 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. //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; lastSentPos = transform.position;
lastSentRot = transform.rotation; lastSentRot = transform.rotation;
using (MemoryStream writeStream = new MemoryStream(positionUpdateBuffer)) using (MemoryStream writeStream = new MemoryStream(positionUpdateBuffer))