This commit is contained in:
2025-12-13 18:35:44 +01:00
parent 02af5c8c68
commit 7fc86a804a
5 changed files with 140 additions and 28 deletions

View File

@@ -39,6 +39,8 @@ namespace KCM
Main.helper.Log("Client disconnected event start");
try
{
Main.ResetMultiplayerState("Client disconnected");
if (e.Message != null)
{
Main.helper.Log(e.Message.ToString());

View File

@@ -27,12 +27,36 @@ namespace KCM.LoadSaveOverrides
//this.PlayerSaveData = new PlayerSaveDataOverride().Pack(Player.inst);
foreach (var player in Main.kCPlayers.Values)
{
Main.helper.Log($"Attempting to pack data for: " + player.name + $"({player.steamId})");
Main.helper.Log($"{player.inst.ToString()} {player.inst?.gameObject.name}");
this.players.Add(player.steamId, new Player.PlayerSaveData().Pack(player.inst));
kingdomNames.Add(player.steamId, player.kingdomName);
try
{
if (player == null)
continue;
Main.helper.Log($"{players[player.steamId] == null}");
if (string.IsNullOrWhiteSpace(player.steamId))
{
Main.helper.Log($"Skipping save for player with missing steamId (name={player.name ?? \"\"})");
continue;
}
if (player.inst == null)
{
Main.helper.Log($"Skipping save for player {player.name ?? \"\"} ({player.steamId}) because Player.inst is null");
continue;
}
Main.helper.Log($"Attempting to pack data for: {player.name} ({player.steamId})");
Main.helper.Log($"Player object: {player.inst} {player.inst.gameObject?.name}");
this.players[player.steamId] = new Player.PlayerSaveData().Pack(player.inst);
kingdomNames[player.steamId] = player.kingdomName ?? " ";
Main.helper.Log($"{players[player.steamId] == null}");
}
catch (Exception ex)
{
Main.helper.Log($"Error packing player data for save (steamId={player?.steamId ?? \"\"}, name={player?.name ?? \"\"})");
Main.helper.Log(ex.ToString());
}
}
this.WorldSaveData = new World.WorldSaveData().Pack(World.inst);

106
Main.cs
View File

@@ -56,6 +56,76 @@ namespace KCM
public static Dictionary<ushort, string> clientSteamIds = new Dictionary<ushort, string>();
private static readonly Dictionary<int, long> lastTeamIdLookupLogMs = new Dictionary<int, long>();
private static int resetInProgress = 0;
public static void ResetMultiplayerState(string reason = null)
{
if (Interlocked.Exchange(ref resetInProgress, 1) == 1)
return;
try
{
if (!string.IsNullOrEmpty(reason))
helper?.Log($"ResetMultiplayerState: {reason}");
try { StateObserver.ClearAll(); } catch { }
try { SaveTransferPacket.ResetTransferState(); } catch { }
try
{
LoadSaveLoadHook.memoryStreamHook = false;
LoadSaveLoadHook.saveBytes = new byte[0];
LoadSaveLoadHook.saveContainer = null;
}
catch { }
try { LoadSaveLoadAtPathHook.saveData = new byte[0]; } catch { }
try { LobbyManager.loadingSave = false; } catch { }
try
{
foreach (var player in kCPlayers.Values)
{
if (player?.gameObject != null && player.gameObject.name != null && player.gameObject.name.Contains("Client Player"))
UnityEngine.Object.Destroy(player.gameObject);
}
}
catch { }
try { LobbyHandler.ClearChatEntries(); } catch { }
try { LobbyHandler.ClearPlayerList(); } catch { }
try
{
kCPlayers.Clear();
clientSteamIds.Clear();
}
catch { }
try { lastTeamIdLookupLogMs.Clear(); } catch { }
try
{
if (KCClient.client != null && KCClient.client.IsConnected)
KCClient.client.Disconnect();
}
catch { }
try
{
if (KCServer.IsRunning)
KCServer.server.Stop();
}
catch { }
try { ServerBrowser.registerServer = false; } catch { }
}
finally
{
Interlocked.Exchange(ref resetInProgress, 0);
}
}
public static KCPlayer GetPlayerByClientID(ushort clientId)
{
@@ -310,6 +380,9 @@ namespace KCM
if (newState != MainMenuMode.State.Uninitialized)
Main.menuState = (MenuState)newState;
if ((MenuState)newState == MenuState.Menu && (KCClient.client.IsConnected || KCServer.IsRunning))
ResetMultiplayerState("Returned to main menu");
}
}
@@ -1221,11 +1294,18 @@ namespace KCM
{
BinaryFormatter bf = new BinaryFormatter();
bf.Binder = new MultiplayerSaveDeserializationBinder();
saveData = File.ReadAllBytes(path);
Stream file = new FileStream(path, FileMode.Open);
try
{
MultiplayerSaveContainer loadData = (MultiplayerSaveContainer)bf.Deserialize(file);
object deserialized = bf.Deserialize(file);
MultiplayerSaveContainer loadData = deserialized as MultiplayerSaveContainer;
if (loadData == null)
{
Main.helper.Log("Selected save is not a MultiplayerSaveContainer; falling back to vanilla load.");
return true;
}
saveData = File.ReadAllBytes(path);
loadData.Unpack(null);
Broadcast.OnLoadedEvent.Broadcast(new OnLoadedEvent());
}
@@ -1335,19 +1415,33 @@ namespace KCM
{
Directory.CreateDirectory(LoadSave.GetSaveDir());
Guid guid = Guid.NewGuid();
string path = (pathOverride != "") ? pathOverride : (LoadSave.GetSaveDir() + "/" + guid);
bool hasOverride = !string.IsNullOrWhiteSpace(pathOverride);
string path = hasOverride ? pathOverride : Path.Combine(LoadSave.GetSaveDir(), guid.ToString());
if (hasOverride && !Path.IsPathRooted(path))
path = Path.Combine(LoadSave.GetSaveDir(), pathOverride);
Directory.CreateDirectory(path);
Thread thread;
try
{
thread = new Thread(new ParameterizedThreadStart(OutToFile));
MultiplayerSaveContainer packedData = new MultiplayerSaveContainer().Pack(null);
MultiplayerSaveContainer packedData;
try
{
packedData = new MultiplayerSaveContainer().Pack(null);
}
catch (Exception ex)
{
Main.helper.Log("Failed to pack multiplayer save data; falling back to vanilla save.");
Main.helper.Log(ex.ToString());
__result = null;
return true;
}
Broadcast.OnSaveEvent.Broadcast(new OnSaveEvent());
thread.Start(new OutData
{
LoadSaveContainer = packedData,
Path = path + "/world"
Path = Path.Combine(path, "world")
});
}
catch (Exception e)
@@ -1379,7 +1473,7 @@ namespace KCM
try
{
World.inst.TakeScreenshot(path + "/cover", new Func<int, int, Texture2D>(World.inst.Func_CaptureWorldShot), onCompleteCallback);
World.inst.TakeScreenshot(Path.Combine(path, "cover"), new Func<int, int, Texture2D>(World.inst.Func_CaptureWorldShot), onCompleteCallback);
}
catch (Exception e3)
{

View File

@@ -18,6 +18,14 @@ namespace KCM.Packets.Lobby
public static bool loadingSave = false;
public static int received = 0;
public static void ResetTransferState()
{
loadingSave = false;
received = 0;
saveData = new byte[1];
chunksReceived = new bool[1];
}
public int chunkId { get; set; }
public int chunkSize { get; set; }

View File

@@ -154,23 +154,7 @@ namespace Riptide.Demos.Steam.PlayerHosted
//NetworkManager.Singleton.StopServer();
//NetworkManager.Singleton.DisconnectClient();
SteamMatchmaking.LeaveLobby(lobbyId);
if (KCClient.client.IsConnected)
KCClient.client.Disconnect();
StateObserver.ClearAll();
Main.helper.Log("clear players");
Main.kCPlayers.Clear();
Main.clientSteamIds.Clear();
LobbyHandler.ClearPlayerList();
LobbyHandler.ClearChatEntries();
Main.helper.Log("end clear players");
if (KCServer.IsRunning)
KCServer.server.Stop();
Main.ResetMultiplayerState("LeaveLobby");
Main.TransitionTo(MenuState.ServerBrowser);
ServerBrowser.registerServer = false;