From 0e2e240883b30f3a7f42105495bbae990ab614c9 Mon Sep 17 00:00:00 2001 From: WinterSolstice8 <60417494+wintersolstice8@users.noreply.github.com> Date: Wed, 11 Feb 2026 15:54:46 -0700 Subject: [PATCH] [core] Add nullptr checks to direct usages of loc.zone in lua baseentity --- src/map/lua/lua_baseentity.cpp | 148 +++++++++++++++++++++++++++------ 1 file changed, 121 insertions(+), 27 deletions(-) diff --git a/src/map/lua/lua_baseentity.cpp b/src/map/lua/lua_baseentity.cpp index 67b86d91cdd..100a76f3699 100644 --- a/src/map/lua/lua_baseentity.cpp +++ b/src/map/lua/lua_baseentity.cpp @@ -211,7 +211,7 @@ void CLuaBaseEntity::showText(CLuaBaseEntity* entity, uint16 messageID, const so bool showName = (p4 != sol::lua_nil) ? p4.as() : false; // ShowName is false in GP_SERV_COMMAND_TALKNUMWORK Constructor, so mimic the same default. bool turn = (p5 != sol::lua_nil) ? p5.as() : true; // Turn to player, default behavior is true - if (turn && PBaseEntity->objtype == TYPE_NPC) + if (turn && PBaseEntity->objtype == TYPE_NPC && PBaseEntity->loc.zone) { PBaseEntity->m_TargID = m_PBaseEntity->targid; PBaseEntity->loc.p.rotation = worldAngle(PBaseEntity->loc.p, m_PBaseEntity->loc.p); @@ -223,7 +223,7 @@ void CLuaBaseEntity::showText(CLuaBaseEntity* entity, uint16 messageID, const so { static_cast(m_PBaseEntity)->pushPacket(PBaseEntity, messageID, param0, param1, param2, param3, showName); } - else + else if (m_PBaseEntity->loc.zone) { m_PBaseEntity->loc.zone->PushPacket(m_PBaseEntity, CHAR_INRANGE, std::make_unique(PBaseEntity, messageID, param0, param1, param3, showName)); } @@ -358,6 +358,11 @@ void CLuaBaseEntity::printToArea(const std::string& message, const sol::object& std::string name = (arg3 == sol::lua_nil) ? "" : arg3.as(); bool skipSender = (arg4 == sol::lua_nil) ? false : arg4.as(); + if (!PChar->loc.zone) + { + return; + } + if (messageRange == ChatMessageArea::System) { message::send(ipc::ChatMessageServerMessage{ @@ -460,7 +465,7 @@ void CLuaBaseEntity::messageBasic(uint16 messageID, const sol::object& p0, const { static_cast(m_PBaseEntity)->pushPacket(m_PBaseEntity, PTarget, param0, param1, static_cast(messageID)); } - else + else if (m_PBaseEntity->loc.zone) { // Broadcast in range m_PBaseEntity->loc.zone->PushPacket(m_PBaseEntity, CHAR_INRANGE, std::make_unique(m_PBaseEntity, PTarget, param0, param1, static_cast(messageID))); @@ -490,7 +495,7 @@ void CLuaBaseEntity::messageName(uint16 messageID, const sol::object& entity, co { PChar->pushPacket(PChar, messageID, PNameEntity, param0, param1, param2, param3, chatType); } - else + else if (m_PBaseEntity->loc.zone) { m_PBaseEntity->loc.zone->PushPacket(m_PBaseEntity, CHAR_INRANGE, std::make_unique(m_PBaseEntity, messageID, PNameEntity, param0, param1, param2, param3, chatType)); } @@ -508,7 +513,7 @@ void CLuaBaseEntity::messagePublic(uint16 messageID, const CLuaBaseEntity* PEnti uint32 param0 = (arg2 != sol::lua_nil) ? arg2.as() : 0; uint32 param1 = (arg3 != sol::lua_nil) ? arg3.as() : 0; - if (PEntity != nullptr) + if (PEntity != nullptr && m_PBaseEntity->loc.zone) { m_PBaseEntity->loc.zone->PushPacket(m_PBaseEntity, CHAR_INRANGE_SELF, std::make_unique(m_PBaseEntity, PEntity->GetBaseEntity(), param0, param1, static_cast(messageID))); } @@ -935,7 +940,10 @@ void CLuaBaseEntity::injectActionPacket(const uint32 inTargetID, uint16 inCatego }, }; - m_PBaseEntity->loc.zone->PushPacket(m_PBaseEntity, CHAR_INRANGE_SELF, std::make_unique(Action)); + if (m_PBaseEntity->loc.zone) + { + m_PBaseEntity->loc.zone->PushPacket(m_PBaseEntity, CHAR_INRANGE_SELF, std::make_unique(Action)); + } } /************************************************************************ @@ -989,7 +997,7 @@ void CLuaBaseEntity::entityAnimationPacket(const char* command, const sol::objec { static_cast(m_PBaseEntity)->pushPacket(m_PBaseEntity, PTarget, command); } - else + else if (m_PBaseEntity->loc.zone) { m_PBaseEntity->loc.zone->PushPacket(m_PBaseEntity, CHAR_INRANGE, std::make_unique(m_PBaseEntity, PTarget, command)); } @@ -1863,7 +1871,10 @@ void CLuaBaseEntity::facePlayer(CLuaBaseEntity* PLuaBaseEntity, const sol::objec void CLuaBaseEntity::clearTargID() { m_PBaseEntity->m_TargID = 0; - m_PBaseEntity->loc.zone->UpdateEntityPacket(m_PBaseEntity, ENTITY_UPDATE, UPDATE_POS); + if (m_PBaseEntity->loc.zone) + { + m_PBaseEntity->loc.zone->UpdateEntityPacket(m_PBaseEntity, ENTITY_UPDATE, UPDATE_POS); + } } /************************************************************************ @@ -2189,6 +2200,11 @@ void CLuaBaseEntity::openDoor(const sol::object& seconds) return; } + if (!m_PBaseEntity->loc.zone) + { + return; + } + if (m_PBaseEntity->animation == ANIMATION_CLOSE_DOOR) { uint32 OpenTime = (seconds != sol::lua_nil) ? seconds.as() * 1000 : 7000; @@ -2201,7 +2217,10 @@ void CLuaBaseEntity::openDoor(const sol::object& seconds) [](CBaseEntity* PNpc) { PNpc->animation = ANIMATION_CLOSE_DOOR; - PNpc->loc.zone->UpdateEntityPacket(PNpc, ENTITY_UPDATE, UPDATE_COMBAT); + if (PNpc->loc.zone) + { + PNpc->loc.zone->UpdateEntityPacket(PNpc, ENTITY_UPDATE, UPDATE_COMBAT); + } })); // clang-format on } @@ -2220,7 +2239,10 @@ void CLuaBaseEntity::closeDoor(const sol::object& seconds) ShowWarning("CLuaBaseEntity::closeDoor() - Non-NPC passed to function."); return; } - + if (!m_PBaseEntity->loc.zone) + { + return; + } if (m_PBaseEntity->animation == ANIMATION_OPEN_DOOR) { uint32 CloseTime = (seconds != sol::lua_nil) ? seconds.as() * 1000 : 7000; @@ -2231,7 +2253,10 @@ void CLuaBaseEntity::closeDoor(const sol::object& seconds) m_PBaseEntity->PAI->QueueAction(queueAction_t(std::chrono::milliseconds(CloseTime), false, [](CBaseEntity* PNpc) { PNpc->animation = ANIMATION_OPEN_DOOR; - PNpc->loc.zone->UpdateEntityPacket(PNpc, ENTITY_UPDATE, UPDATE_COMBAT); + if (PNpc->loc.zone) + { + PNpc->loc.zone->UpdateEntityPacket(PNpc, ENTITY_UPDATE, UPDATE_COMBAT); + } })); // clang-format on } @@ -2277,7 +2302,14 @@ void CLuaBaseEntity::setElevator(uint8 id, uint32 lowerDoor, uint32 upperDoor, u elevator.movetime = xi::vanadiel_clock::minutes(3); elevator.interval = xi::vanadiel_clock::minutes(8); - elevator.zoneID = m_PBaseEntity->loc.zone->GetID(); + if (m_PBaseEntity->loc.zone) + { + elevator.zoneID = m_PBaseEntity->loc.zone->GetID(); + } + else + { + ShowError("setElevator failed! Entity does not have loc.zone assigned!"); + } CTransportHandler::getInstance()->insertElevator(elevator); } @@ -2334,6 +2366,11 @@ void CLuaBaseEntity::showNPC(const sol::object& seconds) return; } + if (!m_PBaseEntity->loc.zone) + { + return; + } + uint32 showTime = (seconds != sol::lua_nil) ? seconds.as() * 1000 : 15000; m_PBaseEntity->status = STATUS_TYPE::NORMAL; @@ -2343,7 +2380,10 @@ void CLuaBaseEntity::showNPC(const sol::object& seconds) m_PBaseEntity->PAI->QueueAction(queueAction_t(std::chrono::milliseconds(showTime), false, [](CBaseEntity* PNpc) { PNpc->status = STATUS_TYPE::DISAPPEAR; - PNpc->loc.zone->UpdateEntityPacket(PNpc, ENTITY_DESPAWN, UPDATE_NONE); + if (PNpc->loc.zone) + { + PNpc->loc.zone->UpdateEntityPacket(PNpc, ENTITY_DESPAWN, UPDATE_NONE); + } })); // clang-format on } @@ -2363,6 +2403,11 @@ void CLuaBaseEntity::hideNPC(const sol::object& seconds) return; } + if (!m_PBaseEntity->loc.zone) + { + return; + } + if (m_PBaseEntity->status == STATUS_TYPE::NORMAL) { uint32 hideTime = (seconds != sol::lua_nil) ? seconds.as() * 1000 : 15000; @@ -2374,7 +2419,10 @@ void CLuaBaseEntity::hideNPC(const sol::object& seconds) m_PBaseEntity->PAI->QueueAction(queueAction_t(std::chrono::milliseconds(hideTime), false, [](CBaseEntity* PNpc) { PNpc->status = STATUS_TYPE::NORMAL; - PNpc->loc.zone->UpdateEntityPacket(PNpc, ENTITY_UPDATE, UPDATE_COMBAT); + if (PNpc->loc.zone) + { + PNpc->loc.zone->UpdateEntityPacket(PNpc, ENTITY_UPDATE, UPDATE_COMBAT); + } })); // clang-format on } @@ -2403,7 +2451,10 @@ void CLuaBaseEntity::updateNPCHideTime(const sol::object& seconds) m_PBaseEntity->PAI->QueueAction(queueAction_t(std::chrono::milliseconds(hideTime), false, [](CBaseEntity* PNpc) { PNpc->status = STATUS_TYPE::NORMAL; - PNpc->loc.zone->UpdateEntityPacket(PNpc, ENTITY_UPDATE, UPDATE_COMBAT); + if (PNpc->loc.zone) + { + PNpc->loc.zone->UpdateEntityPacket(PNpc, ENTITY_UPDATE, UPDATE_COMBAT); + } })); // clang-format on } @@ -2599,7 +2650,7 @@ void CLuaBaseEntity::sendEmote(const CLuaBaseEntity* target, uint8 emID, uint8 e const auto emoteID = static_cast(emID); const auto emoteMode = static_cast(emMode); - if (auto* PEntity = dynamic_cast(m_PBaseEntity)) + if (auto* PEntity = dynamic_cast(m_PBaseEntity); PEntity && PEntity->loc.zone) { auto targetId = PTarget ? PTarget->id : PEntity->id; auto targetTargId = PTarget ? PTarget->targid : PEntity->targid; @@ -2610,7 +2661,7 @@ void CLuaBaseEntity::sendEmote(const CLuaBaseEntity* target, uint8 emID, uint8 e return; } - if (auto* PChar = dynamic_cast(m_PBaseEntity)) + if (auto* PChar = dynamic_cast(m_PBaseEntity); PChar && PChar->loc.zone) { auto targetId = PTarget ? PTarget->id : PChar->id; auto targetTargId = PTarget ? PTarget->targid : PChar->targid; @@ -2895,6 +2946,13 @@ uint8 CLuaBaseEntity::getCurrentRegion() uint8 CLuaBaseEntity::getContinentID() { + if (!m_PBaseEntity->loc.zone) + { + ShowError("Attempting to get Continent ID when entity's zone is null."); + + return 255; + } + return static_cast(m_PBaseEntity->loc.zone->GetContinentID()); } @@ -3015,7 +3073,10 @@ void CLuaBaseEntity::updateToEntireZone(uint8 statusID, uint8 animation, const s PNpc->SetLocalVar("TransportTimestamp", earth_time::vanadiel_timestamp()); } - PNpc->loc.zone->UpdateEntityPacket(PNpc, ENTITY_UPDATE, UPDATE_COMBAT, true); + if (PNpc->loc.zone) + { + PNpc->loc.zone->UpdateEntityPacket(PNpc, ENTITY_UPDATE, UPDATE_COMBAT, true); + } } // Sends an arbitrary entity update to a specific player only @@ -3179,7 +3240,10 @@ void CLuaBaseEntity::positionSpecial(std::map pos, POSMODE m static_cast(pos["rot"]), }; - m_PBaseEntity->loc.zone->PushPacket(m_PBaseEntity, CHAR_INRANGE_SELF, std::make_unique(m_PBaseEntity, newPos, mode)); + if (m_PBaseEntity->loc.zone) + { + m_PBaseEntity->loc.zone->PushPacket(m_PBaseEntity, CHAR_INRANGE_SELF, std::make_unique(m_PBaseEntity, newPos, mode)); + } } /************************************************************************ @@ -3341,8 +3405,11 @@ void CLuaBaseEntity::teleport(std::map pos, const sol::objec newPos.rotation = worldAngle(m_PBaseEntity->loc.p, PLuaBaseEntity->GetBaseEntity()->loc.p); } - m_PBaseEntity->loc.zone->PushPacket(m_PBaseEntity, CHAR_INRANGE_SELF, std::make_unique(m_PBaseEntity, newPos)); - m_PBaseEntity->updatemask |= UPDATE_POS; + if (m_PBaseEntity->loc.zone) + { + m_PBaseEntity->loc.zone->PushPacket(m_PBaseEntity, CHAR_INRANGE_SELF, std::make_unique(m_PBaseEntity, newPos)); + m_PBaseEntity->updatemask |= UPDATE_POS; + } } /************************************************************************ @@ -5924,7 +5991,7 @@ void CLuaBaseEntity::setAnimationSub(uint8 animationsub, const sol::object& send PChar->pushPacket(PChar); } } - else if (sendPacket) + else if (sendPacket && m_PBaseEntity->loc.zone) { m_PBaseEntity->loc.zone->UpdateEntityPacket(m_PBaseEntity, ENTITY_UPDATE, UPDATE_COMBAT); } @@ -6489,7 +6556,7 @@ void CLuaBaseEntity::setBaseSpeed(uint8 speedVal) auto* PChar = static_cast(m_PBaseEntity); PChar->pushPacket(PChar); } - else + else if (m_PBaseEntity->loc.zone) { m_PBaseEntity->loc.zone->UpdateEntityPacket(m_PBaseEntity, ENTITY_UPDATE, UPDATE_POS); } @@ -6516,7 +6583,7 @@ void CLuaBaseEntity::setAnimationSpeed(uint8 speedVal) auto* PChar = static_cast(m_PBaseEntity); PChar->pushPacket(PChar); } - else + else if (m_PBaseEntity->loc.zone) { m_PBaseEntity->loc.zone->UpdateEntityPacket(m_PBaseEntity, ENTITY_UPDATE, UPDATE_POS); } @@ -11683,7 +11750,10 @@ void CLuaBaseEntity::disableLevelSync() } } - PChar->loc.zone->PushPacket(PChar, CHAR_INRANGE, std::make_unique(PChar)); + if (PChar->loc.zone) + { + PChar->loc.zone->PushPacket(PChar, CHAR_INRANGE, std::make_unique(PChar)); + } } /************************************************************************ @@ -12011,6 +12081,12 @@ auto CLuaBaseEntity::registerBattlefield(const sol::object& arg0, const sol::obj auto CLuaBaseEntity::battlefieldAtCapacity(const int battlefieldID) const -> bool { + if (!m_PBaseEntity->loc.zone) + { + ShowError("battlefieldAtCapacity: loc.zone was null for %s", m_PBaseEntity->getName()); + return true; + } + if (m_PBaseEntity->loc.zone->m_BattlefieldHandler == nullptr) { ShowWarning("m_BattlefieldHandler was null for %s.", m_PBaseEntity->getName()); @@ -12050,6 +12126,12 @@ auto CLuaBaseEntity::battlefieldAtCapacity(const int battlefieldID) const -> boo auto CLuaBaseEntity::enterBattlefield(const sol::object& area) const -> bool { + if (m_PBaseEntity->loc.zone == nullptr) + { + ShowError("CLuaBaseEntity::enterBattlefield() - loc.zone was null for %s", m_PBaseEntity->getName()); + return false; + } + if (m_PBaseEntity->objtype != TYPE_PC || m_PBaseEntity->loc.zone->m_BattlefieldHandler == nullptr) { ShowWarning("CLuaBaseEntity::enterBattlefield() - Non-PC calling function, or Battlefield Handler is null."); @@ -12078,6 +12160,12 @@ auto CLuaBaseEntity::enterBattlefield(const sol::object& area) const -> bool auto CLuaBaseEntity::leaveBattlefield(const uint8 leavecode) const -> bool { + if (m_PBaseEntity->loc.zone == nullptr) + { + ShowError("CLuaBaseEntity::leaveBattlefield() - loc.zone was null for %s", m_PBaseEntity->getName()); + return false; + } + if (m_PBaseEntity->objtype == TYPE_NPC || m_PBaseEntity->loc.zone->m_BattlefieldHandler == nullptr) { ShowWarning("CLuaBaseEntity::leaveBattlefield() - NPC calling function, or Battlefield Handler is null."); @@ -12505,7 +12593,10 @@ void CLuaBaseEntity::enableEntities(const sol::object& obj) ************************************************************************/ void CLuaBaseEntity::independentAnimation(CLuaBaseEntity* PTarget, uint16 animId, uint8 mode) { - m_PBaseEntity->loc.zone->PushPacket(m_PBaseEntity, CHAR_INRANGE_SELF, std::make_unique(m_PBaseEntity, PTarget->GetBaseEntity(), animId, static_cast(mode))); + if (m_PBaseEntity->loc.zone) + { + m_PBaseEntity->loc.zone->PushPacket(m_PBaseEntity, CHAR_INRANGE_SELF, std::make_unique(m_PBaseEntity, PTarget->GetBaseEntity(), animId, static_cast(mode))); + } } /************************************************************************ @@ -18654,7 +18745,10 @@ void CLuaBaseEntity::restoreFromChest(CLuaBaseEntity* PLuaBaseEntity, uint32 res }, }; - PTarget->loc.zone->PushPacket(PTarget, CHAR_INRANGE, std::make_unique(Action)); + if (PTarget->loc.zone) + { + PTarget->loc.zone->PushPacket(PTarget, CHAR_INRANGE, std::make_unique(Action)); + } } } }