Skip to content

Commit 79da5f8

Browse files
committed
Increase SyncInfo packet size limits
1 parent 1183806 commit 79da5f8

File tree

5 files changed

+32
-18
lines changed

5 files changed

+32
-18
lines changed

Source/Client/ConstantTicker.cs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System;
12
using HarmonyLib;
23
using Multiplayer.Client.Desyncs;
34
using Multiplayer.Common;
@@ -80,10 +81,19 @@ private static void TickSyncCoordinator()
8081
{
8182
sync.currentOpinion.roundMode = RoundMode.GetCurrentRoundMode();
8283

83-
if (!TickPatch.Simulating && (Multiplayer.LocalServer != null || Multiplayer.arbiterInstance))
84-
Multiplayer.Client.SendFragmented(new ClientSyncInfoPacket
85-
{ SyncOpinion = sync.currentOpinion.ToNet() }.Serialize());
86-
84+
try
85+
{
86+
// In case sending the opinion failed, just keep on going and ignore it. We need to make sure that
87+
// sync.currentOpinion is set to null to prevent cascading failure where the opinion keeps getting
88+
// bigger and the sending keeps failing because of a too big packet.
89+
if (!TickPatch.Simulating && (Multiplayer.LocalServer != null || Multiplayer.arbiterInstance))
90+
Multiplayer.Client.SendFragmented(new ClientSyncInfoPacket
91+
{ SyncOpinion = sync.currentOpinion.ToNet() }.Serialize());
92+
}
93+
catch (Exception e)
94+
{
95+
Log.Error($"Failed to send client sync info packet {e}");
96+
}
8797
sync.AddClientOpinionAndCheckDesync(sync.currentOpinion);
8898
sync.currentOpinion = null;
8999
}

Source/Common/Networking/Packet/IPacket.cs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ public override void BindBytes(ref byte[] obj, int maxLength = DefaultMaxLength)
179179
public override void Bind<T>(ref T[] obj, Binder<T> bind, int maxLength = DefaultMaxLength)
180180
{
181181
int len = reader.ReadInt32();
182-
if (len > maxLength && maxLength != -1) throw new ReaderException("Object too big");
182+
if (len > maxLength && maxLength != -1) throw new ReaderException($"Array too big ({len}>{maxLength})");
183183

184184
obj = new T[len];
185185
for (var i = 0; i < len; i++)
@@ -192,14 +192,14 @@ public override void Bind<T>(ref T[] obj, Binder<T> bind, int maxLength = Defaul
192192

193193
public override void BindRemaining(ref byte[] obj, int maxLength = DefaultMaxLength)
194194
{
195-
if (reader.Left > maxLength) throw new ReaderException("Object too big");
195+
if (reader.Left > maxLength) throw new ReaderException($"Remaining bytes too big ({reader.Left}>{maxLength})");
196196
obj = reader.ReadRaw(reader.Left);
197197
}
198198

199199
public override void Bind<T>(ref List<T> obj, Binder<T> bind, int maxLength = DefaultMaxLength)
200200
{
201201
int len = reader.ReadInt32();
202-
if (len > maxLength) throw new ReaderException("Object too big");
202+
if (len > maxLength) throw new ReaderException($"List too big ({len}>{maxLength})");
203203

204204
obj = new List<T>(len);
205205
for (var i = 0; i < len; i++)
@@ -214,7 +214,7 @@ public override void Bind<K, V>(ref Dictionary<K, V> obj, Binder<K> bindKey, Bin
214214
int maxLength = DefaultMaxLength)
215215
{
216216
int len = reader.ReadInt32();
217-
if (len > maxLength && maxLength != -1) throw new ReaderException("Object too big");
217+
if (len > maxLength && maxLength != -1) throw new ReaderException($"Dictionary too big ({len}>{maxLength})");
218218

219219
obj = new Dictionary<K, V>(len);
220220
for (int i = 0; i < len; i++)
@@ -260,7 +260,7 @@ public sealed class PacketWriter(ByteWriter writer) : PacketBuffer(true)
260260

261261
public override void Bind(ref string obj, int maxLength = DefaultMaxLength)
262262
{
263-
if (obj != null && obj.Length > maxLength) throw new WriterException("Too long string");
263+
if (obj != null && obj.Length > maxLength) throw new WriterException($"Too long string ({obj.Length}>{maxLength})");
264264
writer.WriteString(obj);
265265
}
266266

@@ -274,7 +274,7 @@ public override void BindBytes(ref byte[] obj, int maxLength = DefaultMaxLength)
274274

275275
public override void Bind<T>(ref T[] obj, Binder<T> bind, int maxLength = DefaultMaxLength)
276276
{
277-
if (obj.Length > maxLength) throw new WriterException("Object too big");
277+
if (obj.Length > maxLength) throw new WriterException($"Array too big ({obj.Length}>{maxLength})");
278278
writer.WriteInt32(obj.Length);
279279
for (var i = 0; i < obj.Length; i++)
280280
{
@@ -284,13 +284,13 @@ public override void Bind<T>(ref T[] obj, Binder<T> bind, int maxLength = Defaul
284284

285285
public override void BindRemaining(ref byte[] obj, int maxLength = DefaultMaxLength)
286286
{
287-
if (obj.Length > maxLength) throw new WriterException("Object too big");
287+
if (obj.Length > maxLength) throw new WriterException($"Remaining bytes too big ({obj.Length}>{maxLength})");
288288
writer.WriteRaw(obj);
289289
}
290290

291291
public override void Bind<T>(ref List<T> obj, Binder<T> bind, int maxLength = DefaultMaxLength)
292292
{
293-
if (obj.Count > maxLength) throw new WriterException("Object too big");
293+
if (obj.Count > maxLength) throw new WriterException($"List too big ({obj.Count}>{maxLength})");
294294
writer.WriteInt32(obj.Count);
295295
for (var i = 0; i < obj.Count; i++)
296296
{
@@ -302,7 +302,7 @@ public override void Bind<T>(ref List<T> obj, Binder<T> bind, int maxLength = De
302302
public override void Bind<K, V>(ref Dictionary<K, V> obj, Binder<K> bindKey, Binder<V> bindValue,
303303
int maxLength = DefaultMaxLength)
304304
{
305-
if (obj.Count > maxLength) throw new WriterException("Object too big");
305+
if (obj.Count > maxLength) throw new WriterException($"Dictionary too big ({obj.Count}>{maxLength})");
306306
writer.WriteInt32(obj.Count);
307307
foreach (var (key, value) in obj)
308308
{

Source/Common/Networking/Packet/SyncInfoPacket.cs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ namespace Multiplayer.Common.Networking.Packet;
55
[PacketDefinition(Packets.Client_SyncInfo, allowFragmented: true)]
66
public record struct ClientSyncInfoPacket : IPacket
77
{
8+
// 1MiB. For some big saves, the sync opinion can reach ~650KiB, so this includes some leeway.
9+
public const int MaxLength = 1 << 20;
810
public byte[] rawSyncOpinion;
911

1012
public SyncOpinion SyncOpinion
@@ -15,7 +17,7 @@ public SyncOpinion SyncOpinion
1517

1618
public void Bind(PacketBuffer buf)
1719
{
18-
buf.BindRemaining(ref rawSyncOpinion);
20+
buf.BindRemaining(ref rawSyncOpinion, maxLength: MaxLength);
1921
}
2022

2123
private static readonly Binder<SyncOpinion> SyncOpinionBinder = BinderOf.Identity<SyncOpinion>();
@@ -33,7 +35,7 @@ public SyncOpinion SyncOpinion
3335

3436
public void Bind(PacketBuffer buf)
3537
{
36-
buf.BindRemaining(ref rawSyncOpinion);
38+
buf.BindRemaining(ref rawSyncOpinion, maxLength: ClientSyncInfoPacket.MaxLength);
3739
}
3840

3941
private static readonly Binder<SyncOpinion> SyncOpinionBinder = BinderOf.Identity<SyncOpinion>();
@@ -56,7 +58,9 @@ public void Bind(PacketBuffer buf)
5658
buf.Bind(ref commandRandomStates, BinderOf.UInt());
5759
buf.Bind(ref worldRandomStates, BinderOf.UInt());
5860
buf.Bind(ref mapRandomStates, BinderOf.Identity<MapRandomState>());
59-
buf.Bind(ref traceHashes, BinderOf.Int());
61+
// Max 262k (256Ki) trace hashes. For some big saves, the trace hashes can reach ~60k entries, so this includes
62+
// some leeway.
63+
buf.Bind(ref traceHashes, BinderOf.Int(), maxLength: 1<<18);
6064

6165
buf.Bind(ref simulating);
6266
buf.BindEnum(ref roundMode);
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
39-30-00-00-03-00-00-00-01-00-00-00-02-00-00-00-03-00-00-00-03-00-00-00-0A-00-00-00-14-00-00-00-1E-00-00-00-02-00-00-00-01-00-00-00-02-00-00-00-6F-00-00-00-DE-00-00-00-02-00-00-00-03-00-00-00-4D-01-00-00-BC-01-00-00-2B-02-00-00-03-00-00-00-E7-03-00-00-78-03-00-00-09-03-00-00-01-00-00
1+
39-30-00-00-03-00-00-00-01-00-00-00-02-00-00-00-03-00-00-00-03-00-00-00-0A-00-00-00-14-00-00-00-1E-00-00-00-02-00-00-00-01-00-00-00-02-00-00-00-6F-00-00-00-DE-00-00-00-02-00-00-00-03-00-00-00-4D-01-00-00-BC-01-00-00-2B-02-00-00-03-00-00-00-E7-03-00-00-78-03-00-00-09-03-00-00-01-00-00 (95 bytes)
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
39-30-00-00-03-00-00-00-01-00-00-00-02-00-00-00-03-00-00-00-03-00-00-00-0A-00-00-00-14-00-00-00-1E-00-00-00-02-00-00-00-01-00-00-00-02-00-00-00-6F-00-00-00-DE-00-00-00-02-00-00-00-03-00-00-00-4D-01-00-00-BC-01-00-00-2B-02-00-00-03-00-00-00-E7-03-00-00-78-03-00-00-09-03-00-00-01-00-00
1+
39-30-00-00-03-00-00-00-01-00-00-00-02-00-00-00-03-00-00-00-03-00-00-00-0A-00-00-00-14-00-00-00-1E-00-00-00-02-00-00-00-01-00-00-00-02-00-00-00-6F-00-00-00-DE-00-00-00-02-00-00-00-03-00-00-00-4D-01-00-00-BC-01-00-00-2B-02-00-00-03-00-00-00-E7-03-00-00-78-03-00-00-09-03-00-00-01-00-00 (95 bytes)

0 commit comments

Comments
 (0)