Add advanced sync logging for debugging host-client sync issues

- Add LogSync() helper method in Main.cs for consistent sync logging
- Log all packet send/receive events in PacketHandler and Packet classes
- Add detailed building placement logging in WorldPlace.cs (all properties, final state)
- Add building state update logging in BuildingStatePacket.cs
- Add building state send logging in BuildingStateManager.cs

All sync logs are prefixed with [SYNC] for easy filtering.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2025-12-14 15:35:57 +01:00
parent 6b014c72db
commit c4e25f6c12
6 changed files with 47 additions and 11 deletions

View File

@@ -56,6 +56,12 @@ namespace KCM
public static Dictionary<ushort, string> clientSteamIds = new Dictionary<ushort, string>();
public static Dictionary<Guid, BuildingStatePacket> pendingBuildingStatePackets = new Dictionary<Guid, BuildingStatePacket>();
// Advanced sync logging helper
public static void LogSync(string message)
{
helper.Log($"[SYNC] {message}");
}
public static KCPlayer GetPlayerByClientID(ushort clientId)
{
return kCPlayers[clientSteamIds[clientId]];

View File

@@ -46,7 +46,16 @@ namespace KCM.Packets.Game.GameWorld
public void PlaceBuilding()
{
Main.helper.Log("Received place building packet for " + uniqueName + " from " + player.name + $"({player.id})");
Main.LogSync("========== BUILDING PLACEMENT START ==========");
Main.LogSync($"Building: {uniqueName} from player: {player?.name} (id={player?.id})");
Main.LogSync($" guid={guid}");
Main.LogSync($" globalPosition={globalPosition}");
Main.LogSync($" localPosition={localPosition}");
Main.LogSync($" rotation={rotation} (euler={rotation.eulerAngles})");
Main.LogSync($" built={built}, placed={placed}, open={open}");
Main.LogSync($" constructionProgress={constructionProgress}, constructionPaused={constructionPaused}");
Main.LogSync($" life={life}, ModifiedMaxLife={ModifiedMaxLife}");
Main.LogSync($" yearBuilt={yearBuilt}, decayProtection={decayProtection}");
// Check for duplicate building by guid to prevent double placement from network retries
var existingBuilding = player.inst.Buildings.data.FirstOrDefault(b => b != null && b.guid == guid);
@@ -156,15 +165,24 @@ namespace KCM.Packets.Game.GameWorld
Main.helper.Log($"Client player ({player.name}) Landmass Names Count: {player.inst.LandMassNames.Count}, Contents: {string.Join(", ", player.inst.LandMassNames)}");
player.inst.LandMassNames[building.LandMass()] = player.kingdomName;
Player.inst.LandMassNames[building.LandMass()] = player.kingdomName;
Player.inst.LandMassNames[building.LandMass()] = player.kingdomName;
//Player.inst = originalPlayer;
// Log final building state after placement
Main.LogSync("---------- BUILDING PLACED FINAL STATE ----------");
Main.LogSync($" Final position: {building.transform.position}");
if (building.transform.childCount > 0)
{
Main.LogSync($" Child[0] rotation: {building.transform.GetChild(0).rotation} (euler={building.transform.GetChild(0).rotation.eulerAngles})");
Main.LogSync($" Child[0] localPosition: {building.transform.GetChild(0).localPosition}");
}
Main.LogSync($" IsBuilt={building.IsBuilt()}, IsPlaced={building.IsPlaced()}");
Main.LogSync($" TeamID={building.TeamID()}, LandMass={building.LandMass()}");
Main.LogSync("========== BUILDING PLACEMENT END ==========");
}
else
{
Main.helper.Log(structureData.uniqueName + " failed to load correctly");
Main.LogSync($"FAILED to place building: {structureData.uniqueName} - GetPlaceableByUniqueName returned null");
}
//building.Init();
}
}

View File

@@ -128,8 +128,7 @@ namespace KCM.Packets.Handlers
IPacket packet = DeserialisePacket(messageReceived);
//Main.helper.Log($"Server Received packet {Packets[id].packet.GetType().Name} from {messageReceived.FromConnection.Id}");
Main.LogSync($"SERVER RECV: {Packets[id].packet.GetType().Name} (id={id}) from client {messageReceived.FromConnection.Id}");
if (KCServer.IsRunning)
{
@@ -169,11 +168,9 @@ namespace KCM.Packets.Handlers
var id = messageReceived.MessageId;
//Main.helper.Log($"Client Received packet {Packets[id].packet.GetType().Name} from {messageReceived.FromConnection.Id}");
IPacket packet = DeserialisePacket(messageReceived);
//Main.helper.Log($"Client Received packet {Packets[id].packet.GetType().Name} from {packet.clientId}");
Main.LogSync($"CLIENT RECV: {Packets[id].packet.GetType().Name} (id={id}) from client {packet.clientId}");
if (KCClient.client.IsConnected)
{

View File

@@ -38,6 +38,7 @@ namespace KCM.Packets
{
try
{
Main.LogSync($"SEND TO ALL: {this.GetType().Name} (id={packetId}) except={exceptToClient}");
if (exceptToClient == 0)
{
if (KCServer.IsRunning)
@@ -75,6 +76,7 @@ namespace KCM.Packets
{
try
{
Main.LogSync($"SEND: {this.GetType().Name} (id={packetId}) to={toClient} myId={KCClient.client?.Id}");
if (KCClient.client.IsConnected && toClient == 0)
{
this.clientId = KCClient.client.Id;

View File

@@ -58,6 +58,14 @@ namespace KCM.Packets.State
if (building == null)
return;
Main.LogSync($"========== BUILDING STATE UPDATE ==========");
Main.LogSync($"Building: {uniqueName} guid={guid}");
Main.LogSync($" globalPosition={globalPosition}");
Main.LogSync($" localPosition={localPosition}");
Main.LogSync($" rotation={rotation} (euler={rotation.eulerAngles})");
Main.LogSync($" built={built}, placed={placed}, open={open}");
Main.LogSync($" constructionProgress={constructionProgress}");
try
{
building.UniqueName = uniqueName;

View File

@@ -26,7 +26,12 @@ namespace KCM.StateManagement.BuildingState
Building building = (Building)observer.state;
//Main.helper.Log("Should send building network update for: " + building.UniqueName);
Main.LogSync($"SENDING building state update for: {building.UniqueName} guid={building.guid}");
Main.LogSync($" position={building.transform.position}");
if (building.transform.childCount > 0)
{
Main.LogSync($" rotation={building.transform.GetChild(0).rotation} (euler={building.transform.GetChild(0).rotation.eulerAngles})");
}
new BuildingStatePacket()
{