Carry painting across lobby/map respawns with isolated snapshot transfers

Persist each owner's paint snapshot on the MatchManager across the
despawn/respawn that happens on a lobby<->map scene switch, then reload
and rebroadcast it onto the freshly spawned avatar so painted meshes
survive the transition. Cleared on disconnect/shutdown to avoid stale
carry across sessions.

Isolate concurrent snapshot transfers by id so a respawning replica's
late-join request and the carry broadcast no longer share one reassembly
buffer (which decoded a mixed deflate blob -> "Corrupted data"), and drop
transfers with an older cutoff so a blank late-join cannot overwrite the
carried image.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
adminandClaude Opus 4.8 committed 2026-06-28 01:21:39 +02:00
1 parent b00c415c8c
commit 9d6570f7fe
3 files changed
+120 -8

No files matched your search

+25
View File
@@ -238,6 +238,31 @@ public partial class MeshPainter
SetHistoryBaseline(canonical, baselineId);
}
/// <summary>
/// Owner-side: re-seeds the painter from an in-memory snapshot blob and resets history to it as a fresh
/// local baseline - exactly like <see cref="LoadPaintByName"/> does for a file, just from bytes. Used to
/// carry a painting onto a freshly spawned avatar across a scene-switch respawn; the caller then
/// BroadcastLoadedPaint()s it to peers via the same path a manual load uses. Returns false if the painter
/// is not ready or the blob is missing / incompatible (the current painting is left untouched).
/// </summary>
public bool LoadPaintFromSnapshot(byte[] compressed)
{
if (!_setupValid || compressed == null || compressed.Length == 0) return false;
Color32[][] canonical;
try { canonical = DecodeSnapshot(compressed); }
catch (System.Exception e)
{
Debug.LogWarning($"[MeshPainter] Carry snapshot decode failed: {e.Message}", this);
return false;
}
if (canonical == null) return false;
ReseedCanonical(canonical);
ResetHistoryToCurrent(canonical);
return true;
}
private Color32[][] DecodeSnapshot(byte[] compressed)
{
byte[] raw = Inflate(compressed);