Added eventId
This commit is contained in:
@@ -36,8 +36,9 @@ namespace Marro.PacManUdon
|
||||
// An event has the following structure:
|
||||
// [0-1]: (ushort) Size of event.
|
||||
// [2-5]: (uint) Time in seconds at which event occured.
|
||||
// [6]: (byte) Type of event. 0 = Full Sync, which is used to sync up from an undefinted state.
|
||||
// [7+]: Event-specific data
|
||||
// [6]: (byte) Message id, increments by one for each message with the same timestamp.
|
||||
// [7]: (byte) Type of event. 0 = Full Sync, which is used to sync up from an undefinted state.
|
||||
// [+]: Event-specific data.
|
||||
|
||||
#region Constants
|
||||
/// <summary>
|
||||
@@ -58,13 +59,25 @@ namespace Marro.PacManUdon
|
||||
/// </summary>
|
||||
private const ushort HeaderTimestampIndex = 2;
|
||||
/// <summary>
|
||||
/// The index in an event where the event id is stored.
|
||||
/// </summary>
|
||||
private const ushort HeaderEventIdIndex = 6;
|
||||
/// <summary>
|
||||
/// The index in an event where the event type is stored.
|
||||
/// </summary>
|
||||
private const ushort HeaderEventTypeIndex = 6;
|
||||
private const ushort HeaderEventTypeIndex = 7;
|
||||
/// <summary>
|
||||
/// The total length of the header of an event, in bytes.
|
||||
/// </summary>
|
||||
private const ushort HeaderLength = 7;
|
||||
private const ushort HeaderLength = 8;
|
||||
/// <summary>
|
||||
/// The length of the event size part of the header, in bytes.
|
||||
/// </summary>
|
||||
private const ushort HeaderEventSizeBytes = 2;
|
||||
/// <summary>
|
||||
/// The amount of parts of which the header consists.
|
||||
/// </summary>
|
||||
private const ushort HeaderPartsCount = 4;
|
||||
|
||||
/// <summary>
|
||||
/// The multiplier from Unity time to a timestamp.
|
||||
@@ -110,6 +123,15 @@ namespace Marro.PacManUdon
|
||||
/// </summary>
|
||||
private float nextEventTime;
|
||||
|
||||
/// <summary>
|
||||
/// The timestamp of the most recent event created or received.
|
||||
/// </summary>
|
||||
private uint lastEventTimestamp;
|
||||
/// <summary>
|
||||
/// The message id of the most recent event created or received.
|
||||
/// </summary>
|
||||
private byte lastEventId;
|
||||
|
||||
/// <summary>
|
||||
/// Amounot of retries in a row without a successful sync.
|
||||
/// </summary>
|
||||
@@ -182,6 +204,8 @@ namespace Marro.PacManUdon
|
||||
bufferIndex = 0;
|
||||
isSynced = isOwner; // Owner is always synced
|
||||
retriesWithoutSuccess = 0;
|
||||
lastEventTimestamp = 0;
|
||||
lastEventId = 0;
|
||||
|
||||
offsetTime = Time.fixedTime;
|
||||
internalTime = 0;
|
||||
@@ -267,16 +291,27 @@ namespace Marro.PacManUdon
|
||||
return;
|
||||
}
|
||||
|
||||
var eventTime = TimeToTimestamp(SyncedTime);
|
||||
var timestamp = TimeToTimestamp(SyncedTime);
|
||||
|
||||
InitializeEvent(eventType, eventTime, BufferMaxSizeBytes, out byte[][] data, out var index);
|
||||
if (timestamp != lastEventTimestamp)
|
||||
{
|
||||
lastEventId = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
lastEventId++;
|
||||
}
|
||||
|
||||
var eventId = lastEventId;
|
||||
|
||||
InitializeEvent(eventType, timestamp, eventId, BufferMaxSizeBytes, out byte[][] data, out var index);
|
||||
|
||||
foreach (var obj in syncedObjects)
|
||||
{
|
||||
obj.AppendSyncedData(data, ref index, eventType);
|
||||
}
|
||||
|
||||
// Get event size, skipping over the event size which is not yet included
|
||||
// Get event size
|
||||
ushort eventSize = 0;
|
||||
for (int i = 0; i < index; i++)
|
||||
{
|
||||
@@ -288,27 +323,36 @@ namespace Marro.PacManUdon
|
||||
return;
|
||||
}
|
||||
|
||||
data[0] = BitConverter.GetBytes(eventSize);
|
||||
var eventSizeBytes = BitConverter.GetBytes(eventSize);
|
||||
Array.Copy(eventSizeBytes, 0, data[0], HeaderEventSizeIndex, eventSizeBytes.Length);
|
||||
|
||||
var oldIndex = this.bufferIndex;
|
||||
|
||||
FlattenAndCopy(data, index, buffer, ref this.bufferIndex);
|
||||
|
||||
Debug.Log($"({nameof(PacManUdon)} {nameof(NetworkManager)}) Prepared event with {eventSize} bytes and timestamp {eventTime} for serialization, index went from {oldIndex} to {this.bufferIndex}");
|
||||
Debug.Log($"({nameof(PacManUdon)} {nameof(NetworkManager)}) Prepared event with {eventSize} bytes and timestamp {timestamp} for serialization, index went from {oldIndex} to {this.bufferIndex}");
|
||||
|
||||
RequestSerialization();
|
||||
|
||||
retriesWithoutSuccess = 0; // We had success!
|
||||
}
|
||||
|
||||
private static void InitializeEvent(NetworkEventType eventType, uint eventTime, int maxSize, out byte[][] data, out int index)
|
||||
private static void InitializeEvent(NetworkEventType eventType, uint timestamp, byte eventId, int maxSize, out byte[][] data, out int index)
|
||||
{
|
||||
data = new byte[maxSize][];
|
||||
index = 3;
|
||||
// Create header
|
||||
var timestampBytes = BitConverter.GetBytes(timestamp);
|
||||
|
||||
data[0] = new byte[2]; // Placeholder for event size
|
||||
data[1] = BitConverter.GetBytes(eventTime);
|
||||
data[2] = new byte[] { GameManager.Int32ToByte((int)eventType) };
|
||||
var header = new byte[HeaderLength];
|
||||
|
||||
// Event size is added later
|
||||
Array.Copy(timestampBytes, 0, header, HeaderTimestampIndex, timestampBytes.Length);
|
||||
header[HeaderEventIdIndex] = eventId;
|
||||
header[HeaderEventTypeIndex] = GameManager.Int32ToByte((int)eventType);
|
||||
|
||||
// Initialize event container
|
||||
data = new byte[maxSize][];
|
||||
data[0] = header;
|
||||
index = 1;
|
||||
}
|
||||
#endregion
|
||||
|
||||
@@ -361,6 +405,17 @@ namespace Marro.PacManUdon
|
||||
continue;
|
||||
}
|
||||
|
||||
var timestamp = networkedData[index + HeaderTimestampIndex];
|
||||
var messageId = networkedData[index + HeaderEventIdIndex];
|
||||
|
||||
if (timestamp == lastEventTimestamp
|
||||
&& messageId == lastEventId)
|
||||
{
|
||||
Debug.LogWarning($"({nameof(PacManUdon)} {nameof(NetworkManager)}) Duplicate message of type {eventType}, timestamp: {timestamp}, messageId: {messageId}.");
|
||||
index += eventSize;
|
||||
continue;
|
||||
}
|
||||
|
||||
AppendEventToBuffer(index, eventSize);
|
||||
index += eventSize;
|
||||
}
|
||||
@@ -378,7 +433,8 @@ namespace Marro.PacManUdon
|
||||
|
||||
// Sync up to the time in the full sync
|
||||
var timestamp = BitConverter.ToUInt32(networkedData, index + HeaderTimestampIndex);
|
||||
SyncToTimestamp(timestamp);
|
||||
var eventId = networkedData[index + HeaderEventIdIndex];
|
||||
SyncToTimestamp(timestamp, eventId);
|
||||
|
||||
// Immediately apply the full sync
|
||||
UpdateNextEventTime(ignoreOrder: true);
|
||||
@@ -534,7 +590,7 @@ namespace Marro.PacManUdon
|
||||
SyncedTime = newTime;
|
||||
}
|
||||
|
||||
private void SyncToTimestamp(uint timestamp)
|
||||
private void SyncToTimestamp(uint timestamp, byte eventId)
|
||||
{
|
||||
var oldOffset = offsetTime;
|
||||
var timeToSyncTo = TimestampToTime(timestamp) - Delay;
|
||||
@@ -544,6 +600,9 @@ namespace Marro.PacManUdon
|
||||
internalTime = internalTime - delta;
|
||||
SyncedTime = SyncedTime - delta;
|
||||
|
||||
lastEventTimestamp = timestamp;
|
||||
lastEventId = eventId;
|
||||
|
||||
Debug.Log($"({nameof(PacManUdon)} {nameof(NetworkManager)}) Synced to timestamp {timestamp}, current time is {Time.fixedTime}, timeToSyncTo is {timeToSyncTo}, offsetTime is now {offsetTime}, internalTime is now {internalTime}, SyncedTime is now {SyncedTime}");
|
||||
}
|
||||
|
||||
@@ -657,7 +716,7 @@ namespace Marro.PacManUdon
|
||||
#region Debug
|
||||
public void SimulateSyncToTimestamp(uint timestamp)
|
||||
{
|
||||
SyncToTimestamp(timestamp);
|
||||
SyncToTimestamp(timestamp, 0);
|
||||
}
|
||||
|
||||
public void WriteDebugOutput(TMP_InputField debugOutput)
|
||||
|
||||
Reference in New Issue
Block a user