Replaced fullsyncforced with reset
This commit is contained in:
@@ -13,7 +13,6 @@ namespace Marro.PacManUdon
|
||||
{
|
||||
public enum NetworkEventType
|
||||
{
|
||||
FullSyncForced = 0,
|
||||
FullSync = 1,
|
||||
InputChange = 2,
|
||||
StartGameButtonPressed = 3,
|
||||
@@ -102,6 +101,9 @@ namespace Marro.PacManUdon
|
||||
/// The total length of the header of an event, in bytes.
|
||||
/// </summary>
|
||||
private const ushort HeaderLength = 8;
|
||||
|
||||
private const ushort GuidSize = 16;
|
||||
private const ushort ResetEventSize = HeaderTimestampIndex + GuidSize;
|
||||
#endregion
|
||||
|
||||
#region Private attributes
|
||||
@@ -155,6 +157,8 @@ namespace Marro.PacManUdon
|
||||
/// </summary>
|
||||
private int retriesWithoutSuccess;
|
||||
|
||||
private byte[] lastResetEventData;
|
||||
|
||||
/// <summary>
|
||||
/// For receiver: True if there's a full sync in the queue and we are not synced, otherwise false.
|
||||
/// For transmitter: True if there's a full sync in the queue which has not yet been transmitted, otherwise false.
|
||||
@@ -302,22 +306,13 @@ namespace Marro.PacManUdon
|
||||
/// </summary>
|
||||
public void Initialize()
|
||||
{
|
||||
if (initialized)
|
||||
{
|
||||
Debug.LogWarning($"({nameof(PacManUdon)} {nameof(NetworkManager)}) Tried to call {nameof(Initialize)} when already initialized!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!BitConverter.IsLittleEndian)
|
||||
{
|
||||
Debug.LogError($"({nameof(PacManUdon)} {nameof(NetworkManager)}) Fatal: NetworkManager only supports little endian! Network sync will not be possible.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (root == null)
|
||||
{
|
||||
root = transform.parent.gameObject;
|
||||
}
|
||||
root = transform.parent.gameObject;
|
||||
|
||||
InitializeSubscribers();
|
||||
|
||||
@@ -341,6 +336,8 @@ namespace Marro.PacManUdon
|
||||
|
||||
networkEventSubscribers = new SyncedObject[eventTypeCount][];
|
||||
networkEventSubscribersIndices = new int[eventTypeCount];
|
||||
|
||||
lastResetEventData = new byte[ResetEventSize];
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
@@ -362,7 +359,6 @@ namespace Marro.PacManUdon
|
||||
|
||||
ClearBuffer();
|
||||
|
||||
Synced = IsOwner; // Owner is always synced
|
||||
retriesWithoutSuccess = 0;
|
||||
|
||||
targetTicks = 0;
|
||||
@@ -375,7 +371,12 @@ namespace Marro.PacManUdon
|
||||
// Sync up
|
||||
if (!IsOwner)
|
||||
{
|
||||
RequestEvent(NetworkEventType.FullSync);
|
||||
SetSynced(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
Synced = true; // Owner is always synced
|
||||
SendReset();
|
||||
}
|
||||
|
||||
//Debug.Log($"({nameof(PacManUdon)} {nameof(NetworkManager)}) Initialized");
|
||||
@@ -459,15 +460,13 @@ namespace Marro.PacManUdon
|
||||
ClearBuffer();
|
||||
}
|
||||
|
||||
Synced = false;
|
||||
|
||||
if (!IsOwner)
|
||||
{
|
||||
RequestEvent(NetworkEventType.FullSync);
|
||||
SetSynced(false);
|
||||
}
|
||||
else
|
||||
else if (clearBuffer)
|
||||
{
|
||||
SendEventSoon(NetworkEventType.FullSyncForced);
|
||||
SendReset();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -517,7 +516,7 @@ namespace Marro.PacManUdon
|
||||
if (eventsToSendEarlyIndex >= eventsToSendEarly.Length)
|
||||
{
|
||||
Debug.LogWarning($"({nameof(PacManUdon)} {nameof(NetworkManager)}) {nameof(eventsToSendEarly)} overflow!");
|
||||
HandleError(false);
|
||||
HandleError(true);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -528,14 +527,14 @@ namespace Marro.PacManUdon
|
||||
if (eventsToSendLateIndex >= eventsToSendLate.Length)
|
||||
{
|
||||
Debug.LogWarning($"({nameof(PacManUdon)} {nameof(NetworkManager)}) {nameof(eventsToSendLate)} overflow!");
|
||||
HandleError(false);
|
||||
HandleError(true);
|
||||
return;
|
||||
}
|
||||
|
||||
eventsToSendLate[eventsToSendLateIndex++] = eventType;
|
||||
}
|
||||
|
||||
if (IsFullSync(eventType))
|
||||
if (eventType == NetworkEventType.FullSync)
|
||||
{
|
||||
hasFullSyncReady = true;
|
||||
}
|
||||
@@ -582,15 +581,13 @@ namespace Marro.PacManUdon
|
||||
|
||||
InitializeEvent(eventType, timestamp, eventId, out byte[] data, out var index);
|
||||
|
||||
var effectiveEventType = eventType == NetworkEventType.FullSyncForced ? NetworkEventType.FullSync : eventType;
|
||||
|
||||
var subscibers = GetEventSubscribers(effectiveEventType);
|
||||
var subscibers = GetEventSubscribers(eventType);
|
||||
|
||||
if (subscibers != null)
|
||||
{
|
||||
foreach (var obj in subscibers)
|
||||
{
|
||||
obj.CollectSyncedData(data, ref index, effectiveEventType);
|
||||
obj.CollectSyncedData(data, ref index, eventType);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -623,6 +620,19 @@ namespace Marro.PacManUdon
|
||||
index = HeaderLength;
|
||||
}
|
||||
|
||||
private void SendReset()
|
||||
{
|
||||
var data = new byte[ResetEventSize];
|
||||
|
||||
var guid = Guid.NewGuid().ToByteArray();
|
||||
Array.Copy(guid, 0, data, HeaderTimestampIndex, GuidSize);
|
||||
|
||||
Debug.Log($"({nameof(PacManUdon)} {nameof(NetworkManager)}) Sent Reset event!");
|
||||
|
||||
QueueEventInBuffer(data);
|
||||
RequestSerializationForEvents();
|
||||
}
|
||||
|
||||
private void RequestSerializationForEvents()
|
||||
{
|
||||
RequestSerialization();
|
||||
@@ -641,17 +651,12 @@ namespace Marro.PacManUdon
|
||||
return;
|
||||
}
|
||||
|
||||
if (IsFullSync(eventType) && hasFullSyncReady)
|
||||
if (eventType == NetworkEventType.FullSync && hasFullSyncReady)
|
||||
{
|
||||
//Debug.Log($"Rejected event request because already have full sync ready");
|
||||
return; // Don't send another full sync if we're already preparing to send one
|
||||
}
|
||||
|
||||
if (eventType == NetworkEventType.FullSyncForced)
|
||||
{
|
||||
eventType = NetworkEventType.FullSync; // Remote is not allowed to request a forced full sync
|
||||
}
|
||||
|
||||
SendEventSoon(eventType);
|
||||
}
|
||||
|
||||
@@ -762,7 +767,7 @@ namespace Marro.PacManUdon
|
||||
int eventSize = 0; // Store event size here so we can increment the index no matter how we increment the loop
|
||||
while ((index += eventSize) < length)
|
||||
{
|
||||
if (length - index < HeaderLength)
|
||||
if (length - index < HeaderLength) // Check package is at least as long as the minimum length possible. Reset package is also larger than HeaderLength.
|
||||
{
|
||||
Debug.LogWarning($"({nameof(PacManUdon)} {nameof(NetworkManager)}) {nameof(StoreIncomingData)}: Remaining data in networkedData is not long enough to form a complete event! remaining: {length - index}.");
|
||||
HandleError(false);
|
||||
@@ -770,6 +775,12 @@ namespace Marro.PacManUdon
|
||||
}
|
||||
|
||||
eventSize = GetEventSizeFromHeader(networkedData, index);
|
||||
bool isReset = eventSize == 0;
|
||||
|
||||
if (isReset)
|
||||
{
|
||||
eventSize = ResetEventSize;
|
||||
}
|
||||
|
||||
if (length - index < eventSize)
|
||||
{
|
||||
@@ -787,11 +798,17 @@ namespace Marro.PacManUdon
|
||||
|
||||
var @event = GetArrayPart(networkedData, index, eventSize);
|
||||
|
||||
if (isReset)
|
||||
{
|
||||
TryApplyReset(@event);
|
||||
return;
|
||||
}
|
||||
|
||||
var timestamp = GetTimestampFromHeader(@event);
|
||||
var eventId = GetEventIdFromHeader(@event);
|
||||
var eventType = GetEventTypeFromHeader(@event);
|
||||
|
||||
if (eventType != NetworkEventType.FullSyncForced && (Synced || hasFullSyncReady))
|
||||
if (Synced || hasFullSyncReady)
|
||||
{
|
||||
// Check if event id is sequential
|
||||
if (eventId != GetNextEventId(lastEventId))
|
||||
@@ -821,7 +838,7 @@ namespace Marro.PacManUdon
|
||||
|
||||
//Debug.LogWarning($"({nameof(PacManUdon)} {nameof(NetworkManager)} Queued event with id {eventId}");
|
||||
}
|
||||
else if (IsFullSync(eventType)) // If we're not yet synced, we only care about full sync events.
|
||||
else if (eventType == NetworkEventType.FullSync) // If we're not yet synced, we only care about full sync events.
|
||||
{
|
||||
QueueFullSyncForReplay(@event); // Immediately process full sync
|
||||
}
|
||||
@@ -849,6 +866,47 @@ namespace Marro.PacManUdon
|
||||
//Debug.Log($"({nameof(PacManUdon)} {nameof(NetworkManager)}) Queued full sync in buffer, should execute at {nextEventTime}.");
|
||||
}
|
||||
|
||||
private void TryApplyReset(byte[] @event)
|
||||
{
|
||||
// Compare the guid to the one in the previous reset event
|
||||
if (IsDuplicateResetEvent(@event))
|
||||
{
|
||||
Debug.Log($"({nameof(PacManUdon)} {nameof(NetworkManager)}) Rejected Reset event as it was a duplicate.");
|
||||
return;
|
||||
}
|
||||
|
||||
Debug.Log($"({nameof(PacManUdon)} {nameof(NetworkManager)}) Applied Reset event!");
|
||||
|
||||
lastResetEventData = @event;
|
||||
ClearBuffer();
|
||||
SetSynced(false);
|
||||
}
|
||||
|
||||
private bool IsDuplicateResetEvent(byte[] @event)
|
||||
{
|
||||
for (int i = HeaderTimestampIndex; i < ResetEventSize; i++)
|
||||
{
|
||||
if (@event[i] != lastResetEventData[i])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void SetSynced(bool synced)
|
||||
{
|
||||
Synced = synced;
|
||||
|
||||
if (!Synced)
|
||||
{
|
||||
Synced = false;
|
||||
RequestEvent(NetworkEventType.FullSync);
|
||||
lastEventTransmissionTime = SyncedTimeTicks;
|
||||
}
|
||||
}
|
||||
|
||||
private void ApplyReceivedEvents()
|
||||
{
|
||||
IsEventUpdate = true;
|
||||
@@ -872,11 +930,11 @@ namespace Marro.PacManUdon
|
||||
var timestamp = GetTimestampFromHeader(@event);
|
||||
var eventType = GetEventTypeFromHeader(@event);
|
||||
|
||||
var isFullSync = IsFullSync(eventType);
|
||||
|
||||
if (!Synced || eventType == NetworkEventType.FullSyncForced)
|
||||
if (!Synced)
|
||||
{
|
||||
SyncToTimestamp(timestamp);
|
||||
hasFullSyncReady = false;
|
||||
SetSynced(true);
|
||||
}
|
||||
else if (timestamp < SyncedTimeTicks)
|
||||
{
|
||||
@@ -886,11 +944,6 @@ namespace Marro.PacManUdon
|
||||
return false;
|
||||
}
|
||||
|
||||
if (eventType == NetworkEventType.FullSyncForced)
|
||||
{
|
||||
eventType = NetworkEventType.FullSync;
|
||||
}
|
||||
|
||||
var index = (int)HeaderLength; // Skip header
|
||||
|
||||
var subscribers = GetEventSubscribers(eventType);
|
||||
@@ -920,12 +973,6 @@ namespace Marro.PacManUdon
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!Synced && isFullSync)
|
||||
{
|
||||
hasFullSyncReady = false;
|
||||
Synced = true;
|
||||
}
|
||||
|
||||
//Debug.Log($"({nameof(PacManUdon)} {nameof(NetworkManager)}) Performed incoming event of type {eventType}! Total {index} bytes.");
|
||||
|
||||
retriesWithoutSuccess = 0; // We had success!
|
||||
@@ -1064,9 +1111,6 @@ namespace Marro.PacManUdon
|
||||
return currentEventId;
|
||||
}
|
||||
|
||||
private static bool IsFullSync(NetworkEventType eventType)
|
||||
=> eventType == NetworkEventType.FullSync || eventType == NetworkEventType.FullSyncForced;
|
||||
|
||||
private static ushort GetEventSizeFromHeader(byte[] @event, int eventIndex = 0)
|
||||
=> BitConverter.ToUInt16(@event, eventIndex + HeaderEventSizeIndex);
|
||||
|
||||
@@ -1093,7 +1137,8 @@ namespace Marro.PacManUdon
|
||||
|
||||
if (newOwnerIsLocalPlayer)
|
||||
{
|
||||
SendEventSoon(NetworkEventType.FullSyncForced);
|
||||
ClearBuffer();
|
||||
SendReset();
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
@@ -1244,7 +1289,7 @@ namespace Marro.PacManUdon
|
||||
|
||||
public void DoFullSync()
|
||||
{
|
||||
SendEventSoon(NetworkEventType.FullSyncForced);
|
||||
SendEventSoon(NetworkEventType.FullSync);
|
||||
}
|
||||
|
||||
public void Pause()
|
||||
|
||||
Reference in New Issue
Block a user