feat(network): migra entityId int32→int64 nos delegates do ZeusNetwork

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 <noreply@anthropic.com>
This commit is contained in:
2026-06-02 12:53:43 -03:00
parent e3aab64c8c
commit 5e32cb0757
10 changed files with 31 additions and 31 deletions

View File

@@ -302,7 +302,7 @@ void AZMMOPlayerCharacter::TryRegisterLocalEntityFromCachedSpawn()
return; return;
} }
int32 CachedEntityId = 0; int64 CachedEntityId = 0;
FVector CachedPosCm = FVector::ZeroVector; FVector CachedPosCm = FVector::ZeroVector;
float CachedYawDeg = 0.0f; float CachedYawDeg = 0.0f;
int64 CachedServerTimeMs = 0; int64 CachedServerTimeMs = 0;
@@ -316,7 +316,7 @@ void AZMMOPlayerCharacter::TryRegisterLocalEntityFromCachedSpawn()
TryApplyCachedCharInfo(); 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) const FVector PosCm, const float YawDeg, const int64 ServerTimeMs)
{ {
if (!bIsLocal) if (!bIsLocal)
@@ -328,7 +328,7 @@ void AZMMOPlayerCharacter::HandleZeusPlayerSpawned(const int32 InEntityId, const
HandleLocalSpawnReady(InEntityId, PosCm, YawDeg, ServerTimeMs); 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) const float YawDeg, const int64 ServerTimeMs)
{ {
if (InEntityId == 0) if (InEntityId == 0)
@@ -336,23 +336,23 @@ void AZMMOPlayerCharacter::HandleLocalSpawnReady(const int32 InEntityId, const F
return; return;
} }
const int64 EntityIdAsInt64 = static_cast<int64>(InEntityId); // PR-HANDOFF-007 — InEntityId é int64 (era int32)
if (ZMMOEntityId == EntityIdAsInt64) if (ZMMOEntityId == InEntityId)
{ {
return; return;
} }
ZMMOEntityId = EntityIdAsInt64; ZMMOEntityId = InEntityId;
UE_LOG(LogZMMOPlayer, Log, 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); InEntityId, *PosCm.ToString(), YawDeg, ServerTimeMs);
if (UWorld* World = GetWorld()) if (UWorld* World = GetWorld())
{ {
if (UZMMOWorldSubsystem* WorldSubsystem = World->GetSubsystem<UZMMOWorldSubsystem>()) if (UZMMOWorldSubsystem* WorldSubsystem = World->GetSubsystem<UZMMOWorldSubsystem>())
{ {
WorldSubsystem->RegisterLocalEntity(EntityIdAsInt64, this); WorldSubsystem->RegisterLocalEntity(InEntityId, this);
} }
} }
@@ -364,7 +364,7 @@ void AZMMOPlayerCharacter::HandleLocalSpawnReady(const int32 InEntityId, const F
{ {
if (AZMMOPlayerState* ZMMOPs = Cast<AZMMOPlayerState>(PS)) if (AZMMOPlayerState* ZMMOPs = Cast<AZMMOPlayerState>(PS))
{ {
ZMMOPs->SetPublicIdentity(EntityIdAsInt64, /*CharId*/ FString(), ZMMOPs->SetPublicIdentity(InEntityId, /*CharId*/ FString(),
/*BaseLevel*/ 1, /*ClassId*/ 0); /*BaseLevel*/ 1, /*ClassId*/ 0);
} }
if (UZMMOAttributeComponent* AttrComp = PS->FindComponentByClass<UZMMOAttributeComponent>()) if (UZMMOAttributeComponent* AttrComp = PS->FindComponentByClass<UZMMOAttributeComponent>())
@@ -382,10 +382,10 @@ void AZMMOPlayerCharacter::HandleLocalSpawnReady(const int32 InEntityId, const F
// no UZMMOAttributeComponent via PlayerState. // 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, 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); InEntityId, *CharName, *GuildName);
APlayerState* PS = GetPlayerState(); APlayerState* PS = GetPlayerState();
@@ -408,7 +408,7 @@ void AZMMOPlayerCharacter::TryApplyCachedCharInfo()
{ {
return; return;
} }
int32 CachedEntityId = 0; int64 CachedEntityId = 0;
FString CachedCharName; FString CachedCharName;
FString CachedGuildName; FString CachedGuildName;
if (!ZeusNetwork->TryGetLastLocalCharInfo(CachedEntityId, CachedCharName, CachedGuildName)) if (!ZeusNetwork->TryGetLastLocalCharInfo(CachedEntityId, CachedCharName, CachedGuildName))

View File

@@ -136,13 +136,13 @@ private:
* Metadados publicos do char (Name/Guild) chegam via S_CHAR_INFO em * Metadados publicos do char (Name/Guild) chegam via S_CHAR_INFO em
* HandleZeusCharInfo (servidor envia ANTES de S_SPAWN_PLAYER). * 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() 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() UFUNCTION()
void HandleZeusCharInfo(int32 InEntityId, const FString& CharName, const FString& GuildName); void HandleZeusCharInfo(int64 InEntityId, const FString& CharName, const FString& GuildName);
void TryApplyCachedCharInfo(); void TryApplyCachedCharInfo();

View File

@@ -42,7 +42,7 @@ void UZMMOWorldSubsystem::OnWorldBeginPlay(UWorld& InWorld)
// esta pronto (GameMode ativo, WorldPartition cells inicializadas). // esta pronto (GameMode ativo, WorldPartition cells inicializadas).
int32 ReplayCount = 0; int32 ReplayCount = 0;
ZeusNet->ForEachPendingRemoteSpawn( 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); HandlePlayerSpawned(EntityId, /*bIsLocal=*/false, PosCm, YawDeg, ServerTimeMs);
++ReplayCount; ++ReplayCount;
@@ -85,7 +85,7 @@ void UZMMOWorldSubsystem::RegisterLocalEntity(const int64 EntityId, AActor* Loca
EntityId, *GetNameSafe(LocalActor)); 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) const FVector PosCm, const float YawDeg, const int64 ServerTimeMs)
{ {
if (EntityId == 0) if (EntityId == 0)
@@ -165,7 +165,7 @@ void UZMMOWorldSubsystem::HandlePlayerSpawned(const int32 EntityId, const bool b
EntityId, *PosCm.ToString(), YawDeg, ServerTimeMs); EntityId, *PosCm.ToString(), YawDeg, ServerTimeMs);
} }
void UZMMOWorldSubsystem::HandlePlayerDespawned(const int32 EntityId) void UZMMOWorldSubsystem::HandlePlayerDespawned(const int64 EntityId)
{ {
const TWeakObjectPtr<AActor>* Entry = RemoteEntities.Find(EntityId); const TWeakObjectPtr<AActor>* Entry = RemoteEntities.Find(EntityId);
if (!Entry) if (!Entry)
@@ -192,7 +192,7 @@ void UZMMOWorldSubsystem::HandlePlayerDespawned(const int32 EntityId)
UE_LOG(LogZMMO, Log, TEXT("ZMMOWorldSubsystem: despawn EntityId=%d (destroyed)"), 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) const FVector PosCm, const FVector VelCmS, const bool bGrounded, const int64 ServerTimeMs)
{ {
if (EntityId == 0) if (EntityId == 0)

View File

@@ -72,13 +72,13 @@ protected:
private: private:
UFUNCTION() 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() UFUNCTION()
void HandlePlayerDespawned(int32 EntityId); void HandlePlayerDespawned(int64 EntityId);
UFUNCTION() 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; UClass* ResolveActorClass(EZMMOEntityType EntityType) const;
UZeusNetworkSubsystem* ResolveZeusNetworkSubsystem() const; UZeusNetworkSubsystem* ResolveZeusNetworkSubsystem() const;

View File

@@ -485,7 +485,7 @@ void UUIFrontEndFlowSubsystem::HandlePostLoadMap(UWorld* /*LoadedWorld*/)
PendingLoadingSteps_.Add(TEXT("MapLoaded")); PendingLoadingSteps_.Add(TEXT("MapLoaded"));
} }
void UUIFrontEndFlowSubsystem::HandlePlayerSpawned(int32 /*EntityId*/, bool bIsLocal, void UUIFrontEndFlowSubsystem::HandlePlayerSpawned(int64 /*EntityId*/, bool bIsLocal,
FVector /*PosCm*/, float /*YawDeg*/, FVector /*PosCm*/, float /*YawDeg*/,
int64 /*ServerTimeMs*/) int64 /*ServerTimeMs*/)
{ {

View File

@@ -195,7 +195,7 @@ private:
* Assinatura espelha FZeusOnPlayerSpawned (FiveParams). * Assinatura espelha FZeusOnPlayerSpawned (FiveParams).
*/ */
UFUNCTION() UFUNCTION()
void HandlePlayerSpawned(int32 EntityId, bool bIsLocal, FVector PosCm, void HandlePlayerSpawned(int64 EntityId, bool bIsLocal, FVector PosCm,
float YawDeg, int64 ServerTimeMs); float YawDeg, int64 ServerTimeMs);
/** Disparado pela tela de loading quando todas as etapas viram Done. */ /** Disparado pela tela de loading quando todas as etapas viram Done. */

View File

@@ -63,7 +63,7 @@ namespace
// //
// Cada UZMMOAttributeComponent carrega seu proprio EntityId (seed em // Cada UZMMOAttributeComponent carrega seu proprio EntityId (seed em
// AZMMOPlayerCharacter::HandleLocalSpawnReady ou no primeiro snapshot). // 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; } if (!World || EntityId == 0) { return nullptr; }
const AGameStateBase* GS = World->GetGameState(); 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(); UWorld* World = GetWorld();
if (!World) { return; } 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(); UWorld* World = GetWorld();
if (!World) { return; } if (!World) { return; }

View File

@@ -64,7 +64,7 @@ public:
/// chegar, garantindo que o NetworkHandler consiga rotear via lookup /// chegar, garantindo que o NetworkHandler consiga rotear via lookup
/// por EntityId desde o inicio. /// por EntityId desde o inicio.
UFUNCTION(BlueprintCallable, Category = "Zeus|Attributes") UFUNCTION(BlueprintCallable, Category = "Zeus|Attributes")
void SeedEntityId(int32 InEntityId) { Current.EntityId = InEntityId; } void SeedEntityId(int64 InEntityId) { Current.EntityId = InEntityId; }
UFUNCTION(BlueprintPure, Category = "Zeus|Attributes") UFUNCTION(BlueprintPure, Category = "Zeus|Attributes")
const FZMMOAttributesSnapshot& GetSnapshot() const { return Current; } const FZMMOAttributesSnapshot& GetSnapshot() const { return Current; }

View File

@@ -34,8 +34,8 @@ public:
private: private:
void HandleAttributeSnapshotFull(const FZeusAttributesPayload& Payload); void HandleAttributeSnapshotFull(const FZeusAttributesPayload& Payload);
void HandleHpSpUpdate(int32 EntityId, int32 Hp, int32 Sp); void HandleHpSpUpdate(int64 EntityId, int32 Hp, int32 Sp);
void HandleLevelUp(int32 EntityId, int32 NewBaseLevel, int32 StatusPointDelta); void HandleLevelUp(int64 EntityId, int32 NewBaseLevel, int32 StatusPointDelta);
void HandleStatAllocReply(bool bAccepted, int32 Reason); void HandleStatAllocReply(bool bAccepted, int32 Reason);
UZeusNetworkSubsystem* GetZeusNetSubsystem() const; UZeusNetworkSubsystem* GetZeusNetSubsystem() const;

View File

@@ -20,7 +20,7 @@ struct ZMMOATTRIBUTES_API FZMMOAttributesSnapshot
GENERATED_BODY() GENERATED_BODY()
// === Identidade + classe === // === 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; UPROPERTY(BlueprintReadOnly, Category = "Zeus|Attributes") int32 ClassId = 0;
// === Progressao === // === Progressao ===