From fc49e70c812d669d6b4614e729e168f816dc7f03 Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell Date: Sat, 26 Sep 2026 12:46:58 -0500 Subject: [PATCH] fix(behaviour): don't crash on MissionDialogueOK from an unknown responder THIS CHANGES SERVER BEHAVIOUR (intentionally); no wire change. The MissionDialogueOK handler (carried over verbatim from GameMessages::HandleMissionDialogOK) dereferenced the responder without a null check, so a client naming an object that doesn't exist crashed the world server. It now logs and ignores the message; the script callback is no longer called with a null player (that path always ended in the crash). Test: handling a MissionDialogueOK with an unknown responder crashes without this change and passes with it. Co-Authored-By: Claude Opus 5.5 --- dGame/dGameMessages/MissionMessages.cpp | 6 +++++- .../dGameMessagesTests/MissionMessagesTests.cpp | 12 ++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/dGame/dGameMessages/MissionMessages.cpp b/dGame/dGameMessages/MissionMessages.cpp index f31791875..410c2d2f5 100644 --- a/dGame/dGameMessages/MissionMessages.cpp +++ b/dGame/dGameMessages/MissionMessages.cpp @@ -125,8 +125,12 @@ namespace GameMessages { void MissionDialogueOK::Handle(Entity& entityRef, const SystemAddress& sysAddr) { Entity* entity = &entityRef; Entity* player = Game::entityManager->GetEntity(responder); + if (!player) { + LOG("MissionDialogueOK for mission %i from unknown responder %llu", missionID, responder); + return; + } - if (entity) entity->GetScript()->OnMissionDialogueOK(entity, player, missionID, iMissionState); + entity->GetScript()->OnMissionDialogueOK(entity, player, missionID, iMissionState); // Get the player's mission component MissionComponent* missionComponent = static_cast(player->GetComponent(eReplicaComponentType::MISSION)); diff --git a/tests/dGameTests/dGameMessagesTests/MissionMessagesTests.cpp b/tests/dGameTests/dGameMessagesTests/MissionMessagesTests.cpp index f6c591ca9..b68976946 100644 --- a/tests/dGameTests/dGameMessagesTests/MissionMessagesTests.cpp +++ b/tests/dGameTests/dGameMessagesTests/MissionMessagesTests.cpp @@ -266,3 +266,15 @@ TEST_F(MissionMessagesTests, GoldenBytes) { task.updates = { 1.5f, 2.0f }; EXPECT_PACKET_EQ(FromHex("01 00 00 00 04 00 00 00 02 00 00 c0 3f 00 00 00 40"), Payload(task)); } + +// Behaviour fix: a MissionDialogueOK naming a responder that does not exist used to dereference a null player. +TEST_F(MissionMessagesTests, MissionDialogueOKWithUnknownResponderDoesNotCrash) { + Entity missionGiver(15, info); + GameMessages::MissionDialogueOK ok; + ok.bIsComplete = false; + ok.iMissionState = eMissionState::AVAILABLE; + ok.missionID = 1727; + ok.responder = 0x7777; // no such entity + ok.Handle(missionGiver, UNASSIGNED_SYSTEM_ADDRESS); + SUCCEED(); +}