From 5e32cb07577f9550513a71697ff6392494dd5f5a Mon Sep 17 00:00:00 2001 From: Mateus Rodrigues Date: Tue, 2 Jun 2026 12:53:43 -0300 Subject: [PATCH] =?UTF-8?q?feat(network):=20migra=20entityId=20int32?= =?UTF-8?q?=E2=86=92int64=20nos=20delegates=20do=20ZeusNetwork?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit V3 Server Meshing (server-side) precisa entityId 64-bit (high32 = FNV-1a do worldId, low32 = counter local) pra evitar collision cross-ZS. Os delegates do plugin (OnPlayerSpawned, OnPlayerDespawned, OnCharInfoReceived, OnPlayerStateUpdate, OnHpSpUpdate, OnLevelUp) e os métodos TryGetLast* migram pra int64; handlers em ZMMOPlayerCharacter, ZMMOWorldSubsystem, UIFrontEndFlowSubsystem e ZMMOAttributeNetworkHandler acompanham. FCachedSpawn::EntityId, FZMMOAttributesSnapshot::EntityId e SeedEntityId também viram int64. Wire S_SPAWN_PLAYER ainda carrega uint32 (server faz XOR high32^low32 pra manter unicidade estatística entre ZSs); ampliação do opcode pra uint64 fica pra PR futuro. Co-Authored-By: Claude Opus 4.7 --- .../ZMMO/Game/Entity/ZMMOPlayerCharacter.cpp | 24 +++++++++---------- Source/ZMMO/Game/Entity/ZMMOPlayerCharacter.h | 6 ++--- .../ZMMO/Game/Network/ZMMOWorldSubsystem.cpp | 8 +++---- Source/ZMMO/Game/Network/ZMMOWorldSubsystem.h | 6 ++--- .../UI/FrontEnd/UIFrontEndFlowSubsystem.cpp | 2 +- .../UI/FrontEnd/UIFrontEndFlowSubsystem.h | 2 +- .../Private/ZMMOAttributeNetworkHandler.cpp | 6 ++--- .../Public/ZMMOAttributeComponent.h | 2 +- .../Public/ZMMOAttributeNetworkHandler.h | 4 ++-- .../Public/ZMMOAttributeTypes.h | 2 +- 10 files changed, 31 insertions(+), 31 deletions(-) diff --git a/Source/ZMMO/Game/Entity/ZMMOPlayerCharacter.cpp b/Source/ZMMO/Game/Entity/ZMMOPlayerCharacter.cpp index 8d96d73..5cbe9f8 100644 --- a/Source/ZMMO/Game/Entity/ZMMOPlayerCharacter.cpp +++ b/Source/ZMMO/Game/Entity/ZMMOPlayerCharacter.cpp @@ -302,7 +302,7 @@ void AZMMOPlayerCharacter::TryRegisterLocalEntityFromCachedSpawn() return; } - int32 CachedEntityId = 0; + int64 CachedEntityId = 0; FVector CachedPosCm = FVector::ZeroVector; float CachedYawDeg = 0.0f; int64 CachedServerTimeMs = 0; @@ -316,7 +316,7 @@ void AZMMOPlayerCharacter::TryRegisterLocalEntityFromCachedSpawn() TryApplyCachedCharInfo(); } -void AZMMOPlayerCharacter::HandleZeusPlayerSpawned(const int32 InEntityId, const bool bIsLocal, +void AZMMOPlayerCharacter::HandleZeusPlayerSpawned(const int64 InEntityId, const bool bIsLocal, const FVector PosCm, const float YawDeg, const int64 ServerTimeMs) { if (!bIsLocal) @@ -328,7 +328,7 @@ void AZMMOPlayerCharacter::HandleZeusPlayerSpawned(const int32 InEntityId, const HandleLocalSpawnReady(InEntityId, PosCm, YawDeg, ServerTimeMs); } -void AZMMOPlayerCharacter::HandleLocalSpawnReady(const int32 InEntityId, const FVector PosCm, +void AZMMOPlayerCharacter::HandleLocalSpawnReady(const int64 InEntityId, const FVector PosCm, const float YawDeg, const int64 ServerTimeMs) { if (InEntityId == 0) @@ -336,23 +336,23 @@ void AZMMOPlayerCharacter::HandleLocalSpawnReady(const int32 InEntityId, const F return; } - const int64 EntityIdAsInt64 = static_cast(InEntityId); - if (ZMMOEntityId == EntityIdAsInt64) + // PR-HANDOFF-007 — InEntityId é int64 (era int32) + if (ZMMOEntityId == InEntityId) { return; } - ZMMOEntityId = EntityIdAsInt64; + ZMMOEntityId = InEntityId; UE_LOG(LogZMMOPlayer, Log, - TEXT("AZMMOPlayerCharacter: local spawn captured EntityId=%d pos=(%s) yaw=%.1f t=%lld"), + TEXT("AZMMOPlayerCharacter: local spawn captured EntityId=%lld pos=(%s) yaw=%.1f t=%lld"), InEntityId, *PosCm.ToString(), YawDeg, ServerTimeMs); if (UWorld* World = GetWorld()) { if (UZMMOWorldSubsystem* WorldSubsystem = World->GetSubsystem()) { - WorldSubsystem->RegisterLocalEntity(EntityIdAsInt64, this); + WorldSubsystem->RegisterLocalEntity(InEntityId, this); } } @@ -364,7 +364,7 @@ void AZMMOPlayerCharacter::HandleLocalSpawnReady(const int32 InEntityId, const F { if (AZMMOPlayerState* ZMMOPs = Cast(PS)) { - ZMMOPs->SetPublicIdentity(EntityIdAsInt64, /*CharId*/ FString(), + ZMMOPs->SetPublicIdentity(InEntityId, /*CharId*/ FString(), /*BaseLevel*/ 1, /*ClassId*/ 0); } if (UZMMOAttributeComponent* AttrComp = PS->FindComponentByClass()) @@ -382,10 +382,10 @@ void AZMMOPlayerCharacter::HandleLocalSpawnReady(const int32 InEntityId, const F // no UZMMOAttributeComponent via PlayerState. } -void AZMMOPlayerCharacter::HandleZeusCharInfo(const int32 InEntityId, const FString& CharName, const FString& GuildName) +void AZMMOPlayerCharacter::HandleZeusCharInfo(const int64 InEntityId, const FString& CharName, const FString& GuildName) { UE_LOG(LogZMMOPlayer, Log, - TEXT("AZMMOPlayerCharacter: S_CHAR_INFO recebido EntityId=%d name=%s guild=%s"), + TEXT("AZMMOPlayerCharacter: S_CHAR_INFO recebido EntityId=%lld name=%s guild=%s"), InEntityId, *CharName, *GuildName); APlayerState* PS = GetPlayerState(); @@ -408,7 +408,7 @@ void AZMMOPlayerCharacter::TryApplyCachedCharInfo() { return; } - int32 CachedEntityId = 0; + int64 CachedEntityId = 0; FString CachedCharName; FString CachedGuildName; if (!ZeusNetwork->TryGetLastLocalCharInfo(CachedEntityId, CachedCharName, CachedGuildName)) diff --git a/Source/ZMMO/Game/Entity/ZMMOPlayerCharacter.h b/Source/ZMMO/Game/Entity/ZMMOPlayerCharacter.h index bc058e5..40bd923 100644 --- a/Source/ZMMO/Game/Entity/ZMMOPlayerCharacter.h +++ b/Source/ZMMO/Game/Entity/ZMMOPlayerCharacter.h @@ -136,13 +136,13 @@ private: * Metadados publicos do char (Name/Guild) chegam via S_CHAR_INFO em * HandleZeusCharInfo (servidor envia ANTES de S_SPAWN_PLAYER). */ - void HandleLocalSpawnReady(int32 InEntityId, FVector PosCm, float YawDeg, int64 ServerTimeMs); + void HandleLocalSpawnReady(int64 InEntityId, FVector PosCm, float YawDeg, int64 ServerTimeMs); UFUNCTION() - void HandleZeusPlayerSpawned(int32 InEntityId, bool bIsLocal, FVector PosCm, float YawDeg, int64 ServerTimeMs); + void HandleZeusPlayerSpawned(int64 InEntityId, bool bIsLocal, FVector PosCm, float YawDeg, int64 ServerTimeMs); UFUNCTION() - void HandleZeusCharInfo(int32 InEntityId, const FString& CharName, const FString& GuildName); + void HandleZeusCharInfo(int64 InEntityId, const FString& CharName, const FString& GuildName); void TryApplyCachedCharInfo(); diff --git a/Source/ZMMO/Game/Network/ZMMOWorldSubsystem.cpp b/Source/ZMMO/Game/Network/ZMMOWorldSubsystem.cpp index 3850726..25d3021 100644 --- a/Source/ZMMO/Game/Network/ZMMOWorldSubsystem.cpp +++ b/Source/ZMMO/Game/Network/ZMMOWorldSubsystem.cpp @@ -42,7 +42,7 @@ void UZMMOWorldSubsystem::OnWorldBeginPlay(UWorld& InWorld) // esta pronto (GameMode ativo, WorldPartition cells inicializadas). int32 ReplayCount = 0; ZeusNet->ForEachPendingRemoteSpawn( - [this, &ReplayCount](const int32 EntityId, const FVector PosCm, const float YawDeg, const int64 ServerTimeMs) + [this, &ReplayCount](const int64 EntityId, const FVector PosCm, const float YawDeg, const int64 ServerTimeMs) { HandlePlayerSpawned(EntityId, /*bIsLocal=*/false, PosCm, YawDeg, ServerTimeMs); ++ReplayCount; @@ -85,7 +85,7 @@ void UZMMOWorldSubsystem::RegisterLocalEntity(const int64 EntityId, AActor* Loca EntityId, *GetNameSafe(LocalActor)); } -void UZMMOWorldSubsystem::HandlePlayerSpawned(const int32 EntityId, const bool bIsLocal, +void UZMMOWorldSubsystem::HandlePlayerSpawned(const int64 EntityId, const bool bIsLocal, const FVector PosCm, const float YawDeg, const int64 ServerTimeMs) { if (EntityId == 0) @@ -165,7 +165,7 @@ void UZMMOWorldSubsystem::HandlePlayerSpawned(const int32 EntityId, const bool b EntityId, *PosCm.ToString(), YawDeg, ServerTimeMs); } -void UZMMOWorldSubsystem::HandlePlayerDespawned(const int32 EntityId) +void UZMMOWorldSubsystem::HandlePlayerDespawned(const int64 EntityId) { const TWeakObjectPtr* Entry = RemoteEntities.Find(EntityId); if (!Entry) @@ -192,7 +192,7 @@ void UZMMOWorldSubsystem::HandlePlayerDespawned(const int32 EntityId) UE_LOG(LogZMMO, Log, TEXT("ZMMOWorldSubsystem: despawn EntityId=%d (destroyed)"), EntityId); } -void UZMMOWorldSubsystem::HandlePlayerStateUpdate(const int32 EntityId, const int32 InputSeq, +void UZMMOWorldSubsystem::HandlePlayerStateUpdate(const int64 EntityId, const int32 InputSeq, const FVector PosCm, const FVector VelCmS, const bool bGrounded, const int64 ServerTimeMs) { if (EntityId == 0) diff --git a/Source/ZMMO/Game/Network/ZMMOWorldSubsystem.h b/Source/ZMMO/Game/Network/ZMMOWorldSubsystem.h index 44edfcf..00ae7ce 100644 --- a/Source/ZMMO/Game/Network/ZMMOWorldSubsystem.h +++ b/Source/ZMMO/Game/Network/ZMMOWorldSubsystem.h @@ -72,13 +72,13 @@ protected: private: UFUNCTION() - void HandlePlayerSpawned(int32 EntityId, bool bIsLocal, FVector PosCm, float YawDeg, int64 ServerTimeMs); + void HandlePlayerSpawned(int64 EntityId, bool bIsLocal, FVector PosCm, float YawDeg, int64 ServerTimeMs); UFUNCTION() - void HandlePlayerDespawned(int32 EntityId); + void HandlePlayerDespawned(int64 EntityId); UFUNCTION() - void HandlePlayerStateUpdate(int32 EntityId, int32 InputSeq, FVector PosCm, FVector VelCmS, bool bGrounded, int64 ServerTimeMs); + void HandlePlayerStateUpdate(int64 EntityId, int32 InputSeq, FVector PosCm, FVector VelCmS, bool bGrounded, int64 ServerTimeMs); UClass* ResolveActorClass(EZMMOEntityType EntityType) const; UZeusNetworkSubsystem* ResolveZeusNetworkSubsystem() const; diff --git a/Source/ZMMO/Game/UI/FrontEnd/UIFrontEndFlowSubsystem.cpp b/Source/ZMMO/Game/UI/FrontEnd/UIFrontEndFlowSubsystem.cpp index a4c18b2..0c7aa00 100644 --- a/Source/ZMMO/Game/UI/FrontEnd/UIFrontEndFlowSubsystem.cpp +++ b/Source/ZMMO/Game/UI/FrontEnd/UIFrontEndFlowSubsystem.cpp @@ -485,7 +485,7 @@ void UUIFrontEndFlowSubsystem::HandlePostLoadMap(UWorld* /*LoadedWorld*/) PendingLoadingSteps_.Add(TEXT("MapLoaded")); } -void UUIFrontEndFlowSubsystem::HandlePlayerSpawned(int32 /*EntityId*/, bool bIsLocal, +void UUIFrontEndFlowSubsystem::HandlePlayerSpawned(int64 /*EntityId*/, bool bIsLocal, FVector /*PosCm*/, float /*YawDeg*/, int64 /*ServerTimeMs*/) { diff --git a/Source/ZMMO/Game/UI/FrontEnd/UIFrontEndFlowSubsystem.h b/Source/ZMMO/Game/UI/FrontEnd/UIFrontEndFlowSubsystem.h index 637c361..6f4783c 100644 --- a/Source/ZMMO/Game/UI/FrontEnd/UIFrontEndFlowSubsystem.h +++ b/Source/ZMMO/Game/UI/FrontEnd/UIFrontEndFlowSubsystem.h @@ -195,7 +195,7 @@ private: * Assinatura espelha FZeusOnPlayerSpawned (FiveParams). */ UFUNCTION() - void HandlePlayerSpawned(int32 EntityId, bool bIsLocal, FVector PosCm, + void HandlePlayerSpawned(int64 EntityId, bool bIsLocal, FVector PosCm, float YawDeg, int64 ServerTimeMs); /** Disparado pela tela de loading quando todas as etapas viram Done. */ diff --git a/Source/ZMMOAttributes/Private/ZMMOAttributeNetworkHandler.cpp b/Source/ZMMOAttributes/Private/ZMMOAttributeNetworkHandler.cpp index f272c73..e2c1e5e 100644 --- a/Source/ZMMOAttributes/Private/ZMMOAttributeNetworkHandler.cpp +++ b/Source/ZMMOAttributes/Private/ZMMOAttributeNetworkHandler.cpp @@ -63,7 +63,7 @@ namespace // // Cada UZMMOAttributeComponent carrega seu proprio EntityId (seed em // AZMMOPlayerCharacter::HandleLocalSpawnReady ou no primeiro snapshot). - UZMMOAttributeComponent* FindComponentForEntity(UWorld* World, int32 EntityId) + UZMMOAttributeComponent* FindComponentForEntity(UWorld* World, int64 EntityId) // PR-HANDOFF-007 int64 { if (!World || EntityId == 0) { return nullptr; } const AGameStateBase* GS = World->GetGameState(); @@ -176,7 +176,7 @@ void UZMMOAttributeNetworkHandler::HandleAttributeSnapshotFull(const FZeusAttrib } } -void UZMMOAttributeNetworkHandler::HandleHpSpUpdate(int32 EntityId, int32 Hp, int32 Sp) +void UZMMOAttributeNetworkHandler::HandleHpSpUpdate(int64 EntityId, int32 Hp, int32 Sp) { UWorld* World = GetWorld(); if (!World) { return; } @@ -187,7 +187,7 @@ void UZMMOAttributeNetworkHandler::HandleHpSpUpdate(int32 EntityId, int32 Hp, in } } -void UZMMOAttributeNetworkHandler::HandleLevelUp(int32 EntityId, int32 NewBaseLevel, int32 StatusPointDelta) +void UZMMOAttributeNetworkHandler::HandleLevelUp(int64 EntityId, int32 NewBaseLevel, int32 StatusPointDelta) { UWorld* World = GetWorld(); if (!World) { return; } diff --git a/Source/ZMMOAttributes/Public/ZMMOAttributeComponent.h b/Source/ZMMOAttributes/Public/ZMMOAttributeComponent.h index 22522ed..6d11055 100644 --- a/Source/ZMMOAttributes/Public/ZMMOAttributeComponent.h +++ b/Source/ZMMOAttributes/Public/ZMMOAttributeComponent.h @@ -64,7 +64,7 @@ public: /// chegar, garantindo que o NetworkHandler consiga rotear via lookup /// por EntityId desde o inicio. UFUNCTION(BlueprintCallable, Category = "Zeus|Attributes") - void SeedEntityId(int32 InEntityId) { Current.EntityId = InEntityId; } + void SeedEntityId(int64 InEntityId) { Current.EntityId = InEntityId; } UFUNCTION(BlueprintPure, Category = "Zeus|Attributes") const FZMMOAttributesSnapshot& GetSnapshot() const { return Current; } diff --git a/Source/ZMMOAttributes/Public/ZMMOAttributeNetworkHandler.h b/Source/ZMMOAttributes/Public/ZMMOAttributeNetworkHandler.h index 0f47348..dbc81e3 100644 --- a/Source/ZMMOAttributes/Public/ZMMOAttributeNetworkHandler.h +++ b/Source/ZMMOAttributes/Public/ZMMOAttributeNetworkHandler.h @@ -34,8 +34,8 @@ public: private: void HandleAttributeSnapshotFull(const FZeusAttributesPayload& Payload); - void HandleHpSpUpdate(int32 EntityId, int32 Hp, int32 Sp); - void HandleLevelUp(int32 EntityId, int32 NewBaseLevel, int32 StatusPointDelta); + void HandleHpSpUpdate(int64 EntityId, int32 Hp, int32 Sp); + void HandleLevelUp(int64 EntityId, int32 NewBaseLevel, int32 StatusPointDelta); void HandleStatAllocReply(bool bAccepted, int32 Reason); UZeusNetworkSubsystem* GetZeusNetSubsystem() const; diff --git a/Source/ZMMOAttributes/Public/ZMMOAttributeTypes.h b/Source/ZMMOAttributes/Public/ZMMOAttributeTypes.h index 846a397..e19e322 100644 --- a/Source/ZMMOAttributes/Public/ZMMOAttributeTypes.h +++ b/Source/ZMMOAttributes/Public/ZMMOAttributeTypes.h @@ -20,7 +20,7 @@ struct ZMMOATTRIBUTES_API FZMMOAttributesSnapshot GENERATED_BODY() // === Identidade + classe === - UPROPERTY(BlueprintReadOnly, Category = "Zeus|Attributes") int32 EntityId = 0; + UPROPERTY(BlueprintReadOnly, Category = "Zeus|Attributes") int64 EntityId = 0; UPROPERTY(BlueprintReadOnly, Category = "Zeus|Attributes") int32 ClassId = 0; // === Progressao ===