Server gets the current save game from a player in the game (on join and every few minutes) instead of replaying actions; vehicle fire/smoke synced, also for parked cars
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+46
-1
@@ -1134,6 +1134,11 @@ namespace MSCO
|
||||
break;
|
||||
}
|
||||
|
||||
case MsgType.SaveRequest:
|
||||
// Server möchte den aktuellen Spielstand (für neue Spieler / zum Sichern)
|
||||
StartCoroutine(UploadSave(r.ReadInt32()));
|
||||
break;
|
||||
|
||||
case MsgType.Reconnect:
|
||||
{
|
||||
// Server hat die Welt zurückgesetzt o.ä.: Meldung zeigen, ins Menü, dann automatisch neu verbinden
|
||||
@@ -1445,7 +1450,7 @@ namespace MSCO
|
||||
}
|
||||
try { objects.Update(localPlayer, Time.deltaTime); }
|
||||
catch (System.Exception e) { ReportError("object sync", e); }
|
||||
try { vehicleFx.Update(objects, SendGame, Time.deltaTime); }
|
||||
try { vehicleFx.Update(objects, SendGame, Time.deltaTime, IsWorldAuthority); }
|
||||
catch (System.Exception e) { ReportError("vehicle lights/sound", e); }
|
||||
try { worldSync.Update(IsWorldAuthority, SendGame, Time.unscaledDeltaTime); }
|
||||
catch (System.Exception e) { ReportError("time/weather sync", e); }
|
||||
@@ -1627,6 +1632,46 @@ namespace MSCO
|
||||
public Quaternion Rotation;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Im Spiel speichern (wie auf der Toilette) und den Spielstand an den Server schicken. So bekommen neue Spieler
|
||||
/// genau die aktuelle Welt - Schrauben, Teile, alles - statt eines alten Stands mit nachgespielten Aktionen.
|
||||
/// Der eigene Spielstand ist davon nicht betroffen: er liegt gesichert im Backup und kommt im Hauptmenü zurück.
|
||||
/// </summary>
|
||||
System.Collections.IEnumerator UploadSave(int requestId)
|
||||
{
|
||||
if (!MenuHelper.InGame || !dedicated || session == null) yield break;
|
||||
PlayMakerFSM.BroadcastEvent("SAVEGAME");
|
||||
float until = Time.realtimeSinceStartup + 3f; // das Spiel schreibt die Dateien über mehrere Frames
|
||||
while (Time.realtimeSinceStartup < until) yield return null;
|
||||
if (session == null) yield break;
|
||||
|
||||
List<KeyValuePair<string, byte[]>> files;
|
||||
try { files = SaveSync.ReadLocalSave(); }
|
||||
catch (System.Exception e) { MscoLog.Warning("Could not read the save game for the server: " + e.Message); yield break; }
|
||||
|
||||
const int Chunk = 256 * 1024; // unter der Paketgrenze des Servers
|
||||
foreach (KeyValuePair<string, byte[]> f in files)
|
||||
{
|
||||
for (int offset = 0; offset < f.Value.Length || offset == 0; offset += Chunk)
|
||||
{
|
||||
if (session == null) yield break;
|
||||
int start = offset, length = Mathf.Min(Chunk, f.Value.Length - offset);
|
||||
string name = f.Key;
|
||||
byte[] data = f.Value;
|
||||
session.SendTo(NetSession.HostId, MsgType.SaveUploadPart, NetSession.Build(w =>
|
||||
{
|
||||
w.Write(requestId); w.Write(name); w.Write(data.Length); w.Write(start); w.Write(length);
|
||||
w.Write(data, start, length);
|
||||
}));
|
||||
yield return null;
|
||||
if (data.Length == 0) break;
|
||||
}
|
||||
}
|
||||
int count = files.Count;
|
||||
session.SendTo(NetSession.HostId, MsgType.SaveUploadDone, NetSession.Build(w => { w.Write(requestId); w.Write(count); }));
|
||||
MscoLog.Info("Sent the current save game to the server (" + count + " files)");
|
||||
}
|
||||
|
||||
/// <summary>Sobald die erste Position des Hosts da ist: seitlich neben ihn stellen.</summary>
|
||||
void TryTeleportToHost()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user