fix: check for the player before handling the messages a player sends

Several messages used the player, the character or the user they named
without checking that there is one. A match request and a trade request
are now only handled for the player that sent them, a linked mission
request and a build mode change only for the sending player, and the
remaining handlers return when the player, character or user is
missing.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
This commit is contained in:
Aaron Kimbrell
2026-11-10 13:08:57 -06:00
parent 0f1bce32fb
commit 718bd78e8c
6 changed files with 30 additions and 5 deletions

View File

@@ -136,6 +136,11 @@ namespace GameMessages {
}
void MatchRequest::Handle(Entity& entity, const SystemAddress& sysAddr) {
// A player asks for their own match
if (!entity.IsPlayer() || entity.GetSystemAddress() != sysAddr) {
LOG("Object %llu (LOT %i) is not the player that sent a match request for it", entity.GetObjectID(), entity.GetLOT());
return;
}
std::vector<Entity*> scriptedActs = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::SCRIPTED_ACTIVITY);
if (type == 0) { // join
if (value != 0) {

View File

@@ -1,5 +1,6 @@
#include "BuildingMessages.h"
#include "PlayerManager.h"
#include "BitStreamUtils.h"
#include "Character.h"
#include "ClientPackets.h"
@@ -99,9 +100,8 @@ namespace GameMessages {
LOG("Handling start building with item (%i): (%d) (%d) (%i) (%llu) (%i) (%i) (%llu) (%i) (%i)", entity.GetLOT(), firstTime, success, sourceBag, sourceId, sourceLot, arrangedSourceType, targetId, targetLot, targetType);
auto* user = UserManager::Instance()->GetUser(sysAddr);
auto* player = Game::entityManager->GetEntity(user->GetLoggedInChar());
auto* player = PlayerManager::GetPlayer(sysAddr);
if (!player) return;
StartArrangingWithItem arranging;
arranging.target = player->GetObjectID();
@@ -435,7 +435,12 @@ namespace GameMessages {
void SetBuildMode::Handle(Entity& entity, const SystemAddress& sysAddr) {
auto* player = Game::entityManager->GetEntity(playerId);
if (!player || !player->GetCharacter()) return;
// A player sets their own build mode
if (!player || !player->IsPlayer() || player->GetSystemAddress() != sysAddr || !player->GetCharacter()) {
LOG("Player %llu of a build mode change is not the player that sent it", playerId);
return;
}
auto confirmedStartPos = startPos;
if (confirmedStartPos == NiPoint3Constant::ZERO) {

View File

@@ -223,6 +223,12 @@ namespace GameMessages {
void RequestLinkedMission::Handle(Entity& entity, const SystemAddress& sysAddr) {
auto* player = Game::entityManager->GetEntity(playerID);
// A player asks for the missions offered to themselves
if (!player || !player->IsPlayer() || player->GetSystemAddress() != sysAddr) {
LOG("Player %llu of a linked mission request is not the player that sent it", playerID);
return;
}
auto* missionOfferComponent = static_cast<MissionOfferComponent*>(entity.GetComponent(eReplicaComponentType::MISSION_OFFER));
if (missionOfferComponent != nullptr) {

View File

@@ -246,7 +246,7 @@ namespace GameMessages {
return;
}
if (interactedObject->GetLOT() == 9524) {
if (interactedObject->GetLOT() == 9524 && entity.GetCharacter()) {
entity.GetCharacter()->SetBuildMode(true);
}

View File

@@ -114,8 +114,15 @@ namespace GameMessages {
}
void ClientTradeRequest::Handle(Entity& entity, const SystemAddress& sysAddr) {
// A player asks for their own trade
if (!entity.IsPlayer() || entity.GetSystemAddress() != sysAddr) {
LOG("Object %llu (LOT %i) is not the player that sent a trade request for it", entity.GetObjectID(), entity.GetLOT());
return;
}
// Check if the player has restricted trade access
auto* character = entity.GetCharacter();
if (!character || !character->GetParentUser()) return;
const bool restrictTradeOnMute = UserManager::Instance()->GetMuteRestrictTrade();
if (character->HasPermission(ePermissionMap::RestrictedTradeAccess) || (restrictTradeOnMute && character->GetParentUser()->GetIsMuted())) {
@@ -132,6 +139,7 @@ namespace GameMessages {
if (invitee != nullptr && invitee->IsPlayer()) {
character = invitee->GetCharacter();
if (!character || !character->GetParentUser()) return;
if (character->HasPermission(ePermissionMap::RestrictedTradeAccess) || (restrictTradeOnMute && character->GetParentUser()->GetIsMuted())) {
// Send a message to the player

View File

@@ -70,6 +70,7 @@
namespace DEVGMCommands {
void SetGMLevel(Entity* entity, const SystemAddress& sysAddr, const std::string args) {
User* user = UserManager::Instance()->GetUser(entity->GetSystemAddress());
if (!user) return;
const auto level_intermed = GeneralUtils::TryParse<uint32_t>(args);
if (!level_intermed) {