fix: Enhance SaveTransferPacket handling for out-of-order delivery and reset transfer state
122 lines
4.0 KiB
C#
122 lines
4.0 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using Riptide.Demos.Steam.PlayerHosted;
|
|
using static KCM.Main;
|
|
|
|
namespace KCM.Packets.Lobby
|
|
{
|
|
public class SaveTransferPacket : Packet
|
|
{
|
|
public override ushort packetId => (ushort)Enums.Packets.SaveTransferPacket;
|
|
|
|
public static byte[] saveData = new byte[1];
|
|
public static bool[] chunksReceived = new bool[1];
|
|
public static bool loadingSave = false;
|
|
public static int received = 0;
|
|
|
|
|
|
public int chunkId { get; set; }
|
|
public int chunkSize { get; set; }
|
|
|
|
public int saveSize { get; set; }
|
|
public int saveDataIndex { get; set; }
|
|
public int totalChunks { get; set; }
|
|
|
|
public byte[] saveDataChunk { get; set; }
|
|
|
|
public override void HandlePacketClient()
|
|
{
|
|
// Initialize on first chunk OR if arrays aren't properly sized yet
|
|
// This handles out-of-order packet delivery
|
|
if (!loadingSave || saveData.Length != saveSize || chunksReceived.Length != totalChunks)
|
|
{
|
|
Main.helper.Log($"Save Transfer initializing. saveSize={saveSize}, totalChunks={totalChunks}");
|
|
loadingSave = true;
|
|
|
|
saveData = new byte[saveSize];
|
|
chunksReceived = new bool[totalChunks];
|
|
received = 0;
|
|
|
|
ServerLobbyScript.LoadingSave.SetActive(true);
|
|
}
|
|
|
|
// Skip if we already received this chunk (duplicate packet)
|
|
if (chunksReceived[chunkId])
|
|
{
|
|
Main.helper.Log($"[SaveTransfer] Duplicate chunk {chunkId} received, skipping.");
|
|
return;
|
|
}
|
|
|
|
Array.Copy(saveDataChunk, 0, saveData, saveDataIndex, saveDataChunk.Length);
|
|
|
|
chunksReceived[chunkId] = true;
|
|
|
|
received += chunkSize;
|
|
|
|
Main.helper.Log($"[SaveTransfer] Processed chunk {chunkId}/{totalChunks}. Received: {received} bytes of {saveSize}.");
|
|
|
|
// Update progress bar
|
|
if (saveSize > 0)
|
|
{
|
|
float savePercent = (float)received / (float)saveSize;
|
|
string receivedKB = ((float)received / 1000f).ToString("0.00");
|
|
string totalKB = ((float)saveSize / 1000f).ToString("0.00");
|
|
|
|
ServerLobbyScript.ProgressBar.fillAmount = savePercent;
|
|
ServerLobbyScript.ProgressBarText.text = (savePercent * 100).ToString("0.00") + "%";
|
|
ServerLobbyScript.ProgressText.text = $"{receivedKB} KB / {totalKB} KB";
|
|
}
|
|
else
|
|
{
|
|
ServerLobbyScript.ProgressBar.fillAmount = 0f;
|
|
ServerLobbyScript.ProgressBarText.text = "0.00%";
|
|
ServerLobbyScript.ProgressText.text = "0.00 KB / 0.00 KB";
|
|
}
|
|
|
|
if (IsTransferComplete())
|
|
{
|
|
Main.helper.Log("Save Transfer complete!");
|
|
|
|
// Reset the loading state before processing
|
|
loadingSave = false;
|
|
|
|
LoadSaveLoadHook.saveBytes = saveData;
|
|
LoadSaveLoadHook.memoryStreamHook = true;
|
|
|
|
LoadSave.Load();
|
|
|
|
GameState.inst.SetNewMode(GameState.inst.playingMode);
|
|
LobbyManager.loadingSave = false;
|
|
|
|
Broadcast.OnLoadedEvent.Broadcast(new OnLoadedEvent());
|
|
|
|
ServerLobbyScript.LoadingSave.SetActive(false);
|
|
|
|
// Reset static state for next transfer
|
|
ResetTransferState();
|
|
}
|
|
}
|
|
|
|
public static void ResetTransferState()
|
|
{
|
|
saveData = new byte[1];
|
|
chunksReceived = new bool[1];
|
|
loadingSave = false;
|
|
received = 0;
|
|
}
|
|
|
|
public static bool IsTransferComplete()
|
|
{
|
|
return chunksReceived.All(x => x == true);
|
|
}
|
|
|
|
public override void HandlePacketServer()
|
|
{
|
|
}
|
|
}
|
|
}
|