From b60086d10703a2f21a640e8e28a386470102f91f Mon Sep 17 00:00:00 2001 From: "j.foucher" Date: Tue, 31 Mar 2026 18:24:55 +0200 Subject: [PATCH] Add server authority checks for networking safety - PerceptionComponent: omniscient TActorIterator only runs with HasAuthority() - PersonalityComponent: ApplyReaction and ForceState gate replicated CurrentState writes to server only Co-Authored-By: Claude Opus 4.6 (1M context) --- .../Private/PS_AI_Behavior_PerceptionComponent.cpp | 3 ++- .../Private/PS_AI_Behavior_PersonalityComponent.cpp | 12 ++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Source/PS_AI_Behavior/Private/PS_AI_Behavior_PerceptionComponent.cpp b/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Source/PS_AI_Behavior/Private/PS_AI_Behavior_PerceptionComponent.cpp index 1b02ce4..55bfcae 100644 --- a/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Source/PS_AI_Behavior/Private/PS_AI_Behavior_PerceptionComponent.cpp +++ b/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Source/PS_AI_Behavior/Private/PS_AI_Behavior_PerceptionComponent.cpp @@ -280,7 +280,8 @@ AActor* UPS_AI_Behavior_PerceptionComponent::GetHighestThreatActor( const AAIController* OwnerAIC = Cast(GetOwner()); const APawn* OwnerPawn = OwnerAIC ? OwnerAIC->GetPawn() : nullptr; - if (OwnerPawn) + // Only run on server — TActorIterator results differ on clients + if (OwnerPawn && OwnerPawn->HasAuthority()) { const EPS_AI_Behavior_TargetType TopPriority = TargetPriority[0]; const UPS_AI_Behavior_Settings* Settings = GetDefault(); diff --git a/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Source/PS_AI_Behavior/Private/PS_AI_Behavior_PersonalityComponent.cpp b/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Source/PS_AI_Behavior/Private/PS_AI_Behavior_PersonalityComponent.cpp index 49f5e33..6fe1bc7 100644 --- a/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Source/PS_AI_Behavior/Private/PS_AI_Behavior_PersonalityComponent.cpp +++ b/Unreal/PS_AI_Agent/Plugins/PS_AI_Behavior/Source/PS_AI_Behavior/Private/PS_AI_Behavior_PersonalityComponent.cpp @@ -132,6 +132,12 @@ EPS_AI_Behavior_State UPS_AI_Behavior_PersonalityComponent::EvaluateReaction() c EPS_AI_Behavior_State UPS_AI_Behavior_PersonalityComponent::ApplyReaction() { + // Only server can change replicated state + if (!GetOwner() || !GetOwner()->HasAuthority()) + { + return CurrentState; + } + const EPS_AI_Behavior_State NewState = EvaluateReaction(); if (NewState != CurrentState) { @@ -151,6 +157,12 @@ EPS_AI_Behavior_State UPS_AI_Behavior_PersonalityComponent::ApplyReaction() void UPS_AI_Behavior_PersonalityComponent::ForceState(EPS_AI_Behavior_State NewState) { + // Only server can change replicated state + if (!GetOwner() || !GetOwner()->HasAuthority()) + { + return; + } + if (NewState != CurrentState) { const EPS_AI_Behavior_State OldState = CurrentState;