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
/// </summary>
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;
/// <summary>

View File

@ -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;
}
}

View File

@ -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<MessageType> messageTypes = new List<MessageType>(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<uint, NetworkedClient> 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<uint, NetworkedClient> pair in connectedClients)
{
Send("MLAPI_TIME_SYNC", "MLAPI_TIME_SYNC", stream.GetBuffer());
}
}
}
private void HandleApproval(uint clientId, bool approved)
{
if(approved)

View File

@ -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<float> node = Framekeys.First;
LinkedListNode<float> 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);
}
}
}

View File

@ -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())
{

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))
{
@ -130,7 +130,7 @@ namespace MLAPI.MonoBehaviours.Prototyping
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))
{
//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))