Some handling of dropped packages

This commit is contained in:
2026-01-04 19:06:03 +01:00
parent 60abba8498
commit 2636e65e4d
4 changed files with 1240 additions and 1040 deletions

View File

@@ -266,6 +266,37 @@ CanvasRenderer:
m_PrefabAsset: {fileID: 0} m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2406178} m_GameObject: {fileID: 2406178}
m_CullTransparentMesh: 1 m_CullTransparentMesh: 1
--- !u!1 &2841571
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 2841572}
m_Layer: 0
m_Name: Resend previous events
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &2841572
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2841571}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 297676220}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1001 &6734103 --- !u!1001 &6734103
PrefabInstance: PrefabInstance:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@@ -9639,6 +9670,42 @@ PrefabInstance:
m_AddedGameObjects: [] m_AddedGameObjects: []
m_AddedComponents: [] m_AddedComponents: []
m_SourcePrefab: {fileID: 100100000, guid: 00a825a5aeafee94789192f61cbb3a5a, type: 3} m_SourcePrefab: {fileID: 100100000, guid: 00a825a5aeafee94789192f61cbb3a5a, type: 3}
--- !u!1 &297676219
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 297676220}
m_Layer: 0
m_Name: NetworkManager
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &297676220
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 297676219}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 1897221841}
- {fileID: 2841572}
- {fileID: 963448677}
- {fileID: 1334822256}
- {fileID: 1683006206}
m_Father: {fileID: 1886023632}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1001 &300095180 --- !u!1001 &300095180
PrefabInstance: PrefabInstance:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@@ -28642,6 +28709,37 @@ Transform:
m_CorrespondingSourceObject: {fileID: 1315692994360949719, guid: 00a825a5aeafee94789192f61cbb3a5a, type: 3} m_CorrespondingSourceObject: {fileID: 1315692994360949719, guid: 00a825a5aeafee94789192f61cbb3a5a, type: 3}
m_PrefabInstance: {fileID: 1641300668} m_PrefabInstance: {fileID: 1641300668}
m_PrefabAsset: {fileID: 0} m_PrefabAsset: {fileID: 0}
--- !u!1 &963448676
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 963448677}
m_Layer: 0
m_Name: Ping
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &963448677
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 963448676}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 297676220}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &964231232 stripped --- !u!1 &964231232 stripped
GameObject: GameObject:
m_CorrespondingSourceObject: {fileID: 4099390335584803315, guid: 00a825a5aeafee94789192f61cbb3a5a, type: 3} m_CorrespondingSourceObject: {fileID: 4099390335584803315, guid: 00a825a5aeafee94789192f61cbb3a5a, type: 3}
@@ -41660,6 +41758,37 @@ GameObject:
m_CorrespondingSourceObject: {fileID: 1914595051839510733, guid: 9fbd72f5bc3c5434a87ab8539789c584, type: 3} m_CorrespondingSourceObject: {fileID: 1914595051839510733, guid: 9fbd72f5bc3c5434a87ab8539789c584, type: 3}
m_PrefabInstance: {fileID: 8042777216032092028} m_PrefabInstance: {fileID: 8042777216032092028}
m_PrefabAsset: {fileID: 0} m_PrefabAsset: {fileID: 0}
--- !u!1 &1334822255
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1334822256}
m_Layer: 0
m_Name: FullSync respects delay
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &1334822256
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1334822255}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 297676220}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1001 &1335132404 --- !u!1001 &1335132404
PrefabInstance: PrefabInstance:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@@ -51668,6 +51797,37 @@ PrefabInstance:
m_AddedGameObjects: [] m_AddedGameObjects: []
m_AddedComponents: [] m_AddedComponents: []
m_SourcePrefab: {fileID: 100100000, guid: 00a825a5aeafee94789192f61cbb3a5a, type: 3} m_SourcePrefab: {fileID: 100100000, guid: 00a825a5aeafee94789192f61cbb3a5a, type: 3}
--- !u!1 &1683006205
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1683006206}
m_Layer: 0
m_Name: Store events in separate arrays
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &1683006206
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1683006205}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 297676220}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!4 &1683500364 stripped --- !u!4 &1683500364 stripped
Transform: Transform:
m_CorrespondingSourceObject: {fileID: 1315692994360949719, guid: 00a825a5aeafee94789192f61cbb3a5a, type: 3} m_CorrespondingSourceObject: {fileID: 1315692994360949719, guid: 00a825a5aeafee94789192f61cbb3a5a, type: 3}
@@ -58786,6 +58946,7 @@ Transform:
- {fileID: 712073434} - {fileID: 712073434}
- {fileID: 106401850} - {fileID: 106401850}
- {fileID: 851913432} - {fileID: 851913432}
- {fileID: 297676220}
- {fileID: 1961479820} - {fileID: 1961479820}
- {fileID: 2129311453} - {fileID: 2129311453}
- {fileID: 2142346958} - {fileID: 2142346958}
@@ -58899,12 +59060,12 @@ Transform:
m_PrefabAsset: {fileID: 0} m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1897221840} m_GameObject: {fileID: 1897221840}
serializedVersion: 2 serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1} m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0 m_ConstrainProportionsScale: 0
m_Children: [] m_Children: []
m_Father: {fileID: 1961479820} m_Father: {fileID: 297676220}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &1898242099 stripped --- !u!1 &1898242099 stripped
GameObject: GameObject:
@@ -60490,7 +60651,6 @@ Transform:
- {fileID: 2030126881} - {fileID: 2030126881}
- {fileID: 2103220969} - {fileID: 2103220969}
- {fileID: 455444785} - {fileID: 455444785}
- {fileID: 1897221841}
- {fileID: 147662346} - {fileID: 147662346}
- {fileID: 29433776} - {fileID: 29433776}
m_Father: {fileID: 1886023632} m_Father: {fileID: 1886023632}

File diff suppressed because it is too large Load Diff

View File

@@ -245,7 +245,7 @@ namespace Marro.PacManUdon
} }
} }
private void HandleError() private void HandleError(bool clearBuffer)
{ {
retriesWithoutSuccess++; retriesWithoutSuccess++;
@@ -259,7 +259,12 @@ namespace Marro.PacManUdon
Debug.LogWarning($"({nameof(PacManUdon)} {nameof(NetworkManager)}) Encountered data error, attempting to recover via full sync."); Debug.LogWarning($"({nameof(PacManUdon)} {nameof(NetworkManager)}) Encountered data error, attempting to recover via full sync.");
if (clearBuffer)
{
ClearBuffer(); ClearBuffer();
}
isSynced = false;
if (!isOwner) if (!isOwner)
{ {
@@ -293,16 +298,7 @@ namespace Marro.PacManUdon
var timestamp = TimeToTimestamp(SyncedTime); var timestamp = TimeToTimestamp(SyncedTime);
if (timestamp != lastEventTimestamp) var eventId = GetNextEventId(lastEventId);
{
lastEventId = 0;
}
else
{
lastEventId++;
}
var eventId = lastEventId;
InitializeEvent(eventType, timestamp, eventId, BufferMaxSizeBytes, out byte[][] data, out var index); InitializeEvent(eventType, timestamp, eventId, BufferMaxSizeBytes, out byte[][] data, out var index);
@@ -334,6 +330,9 @@ namespace Marro.PacManUdon
RequestSerialization(); RequestSerialization();
lastEventTimestamp = timestamp;
lastEventId = eventId;
retriesWithoutSuccess = 0; // We had success! retriesWithoutSuccess = 0; // We had success!
} }
@@ -354,6 +353,12 @@ namespace Marro.PacManUdon
data[0] = header; data[0] = header;
index = 1; index = 1;
} }
[NetworkCallable]
public void RequestEventReceived(NetworkEventType eventType)
{
SendEvent(eventType);
}
#endregion #endregion
#region Receiver #region Receiver
@@ -368,56 +373,78 @@ namespace Marro.PacManUdon
SendCustomNetworkEvent(VRC.Udon.Common.Interfaces.NetworkEventTarget.Owner, "RequestEventReceived", eventType); SendCustomNetworkEvent(VRC.Udon.Common.Interfaces.NetworkEventTarget.Owner, "RequestEventReceived", eventType);
} }
private void ProcessIncomingData() private void StoreIncomingData()
{ {
if (networkedData.Length == 0) if (networkedData.Length == 0)
{ {
return; // Nothing to process return; // Nothing to store
} }
Debug.Log($"({nameof(PacManUdon)} {nameof(NetworkManager)}) Received {networkedData.Length} bytes!\nBytes received:\n{BytesToString(networkedData)}"); Debug.Log($"({nameof(PacManUdon)} {nameof(NetworkManager)}) Received {networkedData.Length} bytes!\nBytes received:\n{BytesToString(networkedData)}");
var length = networkedData.Length; var length = networkedData.Length;
int index = 0; int index = 0;
while (index < length) int eventSize = 0; // Store event size here so we can increment the index no matter how we increment the loop
while (true)
{ {
index += eventSize;
if (index >= length)
{
break;
}
if (length - index < HeaderLength) if (length - index < HeaderLength)
{ {
Debug.LogWarning($"({nameof(PacManUdon)} {nameof(NetworkManager)}) {nameof(ProcessIncomingData)}: Remaining data in networkedData is not long enough to form a complete event!"); 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(); HandleError(false);
return;
}
eventSize = networkedData[index + HeaderEventSizeIndex];
if (length - index < eventSize)
{
Debug.LogWarning($"({nameof(PacManUdon)} {nameof(NetworkManager)}) {nameof(StoreIncomingData)}: Event size is larger than total remaining data! {nameof(eventSize)}: {eventSize}, remaining: {length - index}.");
HandleError(false);
return; return;
} }
var eventSize = networkedData[index + HeaderEventSizeIndex];
var eventType = (NetworkEventType)networkedData[index + HeaderEventTypeIndex]; var eventType = (NetworkEventType)networkedData[index + HeaderEventTypeIndex];
if (eventType == NetworkEventType.FullSync) if (eventType == NetworkEventType.FullSync)
{ {
ProcessIncomingFullSync(index, eventSize); // Immediately process full sync ProcessIncomingFullSync(index, eventSize); // Immediately process full sync
index += eventSize;
continue; continue;
} }
if (!isSynced) if (!isSynced)
{ {
Debug.LogWarning($"({nameof(PacManUdon)} {nameof(NetworkManager)}) Received event of type {eventType} while we are not yet synced to the remote time, ignoring event."); Debug.LogWarning($"({nameof(PacManUdon)} {nameof(NetworkManager)}) Received event of type {eventType} while we are not yet synced to the remote time, ignoring event.");
index += eventSize;
continue; continue;
} }
var timestamp = networkedData[index + HeaderTimestampIndex]; var timestamp = networkedData[index + HeaderTimestampIndex];
var messageId = networkedData[index + HeaderEventIdIndex]; var eventId = networkedData[index + HeaderEventIdIndex];
if (timestamp == lastEventTimestamp if (timestamp == lastEventTimestamp
&& messageId == lastEventId) && eventId == lastEventId)
{ {
Debug.LogWarning($"({nameof(PacManUdon)} {nameof(NetworkManager)}) Duplicate message of type {eventType}, timestamp: {timestamp}, messageId: {messageId}."); Debug.LogWarning($"({nameof(PacManUdon)} {nameof(NetworkManager)}) Duplicate message of type {eventType}, timestamp: {timestamp}, messageId: {eventId}.");
index += eventSize;
continue; continue;
} }
if (eventId != GetNextEventId(lastEventId))
{
Debug.LogWarning($"({nameof(PacManUdon)} {nameof(NetworkManager)}) EventIds were not sequential! Did we miss a serialization? Timestamp: {timestamp}, eventId: {eventId}, lastEventId: {lastEventId}.");
HandleError(false);
return;
}
AppendEventToBuffer(index, eventSize); AppendEventToBuffer(index, eventSize);
index += eventSize;
lastEventTimestamp = timestamp;
lastEventId = eventId;
} }
} }
@@ -472,14 +499,14 @@ namespace Marro.PacManUdon
if (!success) if (!success)
{ {
Debug.LogWarning($"({nameof(PacManUdon)} {nameof(NetworkManager)}) Malformed data reported by {obj.name} during event type {eventType}!"); Debug.LogWarning($"({nameof(PacManUdon)} {nameof(NetworkManager)}) Malformed data reported by {obj.name} during event type {eventType}!");
HandleError(); HandleError(true);
return; return;
} }
if (index > this.bufferIndex) if (index > this.bufferIndex)
{ {
Debug.LogWarning($"({nameof(PacManUdon)} {nameof(NetworkManager)}) Buffer overflow during {nameof(SyncedObject.SetSyncedData)} for {obj.name} in event type {eventType}!"); Debug.LogWarning($"({nameof(PacManUdon)} {nameof(NetworkManager)}) Buffer overflow during {nameof(SyncedObject.SetSyncedData)} for {obj.name} in event type {eventType}!");
HandleError(); HandleError(true);
return; return;
} }
} }
@@ -488,7 +515,7 @@ namespace Marro.PacManUdon
if (index != eventSize) if (index != eventSize)
{ {
Debug.LogWarning($"({nameof(PacManUdon)} {nameof(NetworkManager)}) Amount of data read does not match event size! Expected {eventSize}, read {index}."); Debug.LogWarning($"({nameof(PacManUdon)} {nameof(NetworkManager)}) Amount of data read does not match event size! Expected {eventSize}, read {index}.");
HandleError(); HandleError(true);
return; return;
} }
@@ -558,7 +585,7 @@ namespace Marro.PacManUdon
Debug.LogWarning($"({nameof(PacManUdon)} {nameof(NetworkManager)}) Too much data in buffer to store event!"); Debug.LogWarning($"({nameof(PacManUdon)} {nameof(NetworkManager)}) Too much data in buffer to store event!");
} }
HandleError(); // We can store event now that we cleared the buffer. HandleError(false);
return false; return false;
} }
@@ -621,7 +648,7 @@ namespace Marro.PacManUdon
else else
{ {
Debug.LogWarning($"({nameof(PacManUdon)} {nameof(NetworkManager)}) New event is earlier than previous event!"); Debug.LogWarning($"({nameof(PacManUdon)} {nameof(NetworkManager)}) New event is earlier than previous event!");
HandleError(); HandleError(true);
return; return;
} }
} }
@@ -637,15 +664,24 @@ namespace Marro.PacManUdon
} }
#endregion #endregion
#region Header
public static byte GetNextEventId(byte currentEventId)
{
if (currentEventId == byte.MaxValue) // Udon forces overflow checks
{
return 0;
}
currentEventId += 1;
return currentEventId;
}
#endregion
#region VRC events #region VRC events
public override void OnOwnershipTransferred(VRCPlayerApi newOwner) public override void OnOwnershipTransferred(VRCPlayerApi newOwner)
{ {
SetOwner(newOwner == Networking.LocalPlayer); SetOwner(newOwner == Networking.LocalPlayer);
if(isOwner)
{
HandleError();
}
} }
public override void OnPreSerialization() public override void OnPreSerialization()
@@ -685,7 +721,7 @@ namespace Marro.PacManUdon
{ {
if (!isOwner) if (!isOwner)
{ {
ProcessIncomingData(); StoreIncomingData();
} }
} }
#endregion #endregion

View File

@@ -58,9 +58,13 @@ public class TestBallManager : UdonSharpBehaviour
{ {
networkManager.SimulateSyncToTimestamp(NetworkManager.TimeToTimestamp(networkManager.SyncedTime - 0.5f)); networkManager.SimulateSyncToTimestamp(NetworkManager.TimeToTimestamp(networkManager.SyncedTime - 0.5f));
} }
else if (networkManager.IsOwner)
{
networkManager.SendEvent(NetworkEventType.FullSync);
}
else else
{ {
networkManager.SendEvent((NetworkEventType)0); networkManager.RequestEvent(NetworkEventType.FullSync);
} }
} }
} }