Skip to content

Commit

Permalink
fix: PetComponent crashing due to nullptr access
Browse files Browse the repository at this point in the history
Resolves an issue where item is null but is accessed but not doing that code and instead consulting the EntityManager for a valid Entity, alongside nullifying the m_Owner objectID should the pet be destroyed and timer still exist.

Update PetComponent.cpp

Add nullptr check

Add back timer

Update PetComponent.cpp

speculative fix for a different crash

Why are we accessing something before checking if its null
  • Loading branch information
EmosewaMC committed Oct 27, 2024
1 parent 33a8efd commit 0d218fc
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 18 deletions.
35 changes: 18 additions & 17 deletions dGame/dComponents/PetComponent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -795,8 +795,6 @@ void PetComponent::Wander() {
}

void PetComponent::Activate(Item* item, bool registerPet, bool fromTaming) {
AddDrainImaginationTimer(item, fromTaming);

m_ItemId = item->GetId();
m_DatabaseId = item->GetSubKey();

Expand All @@ -807,6 +805,7 @@ void PetComponent::Activate(Item* item, bool registerPet, bool fromTaming) {
inventoryComponent->DespawnPet();

m_Owner = inventoryComponent->GetParent()->GetObjectID();
AddDrainImaginationTimer(fromTaming);

auto* owner = GetOwner();

Expand Down Expand Up @@ -859,17 +858,14 @@ void PetComponent::Activate(Item* item, bool registerPet, bool fromTaming) {
}
}

void PetComponent::AddDrainImaginationTimer(Item* item, bool fromTaming) {
void PetComponent::AddDrainImaginationTimer(bool fromTaming) {
if (Game::config->GetValue("pets_take_imagination") != "1") return;

auto playerInventory = item->GetInventory();
if (!playerInventory) return;

auto playerInventoryComponent = playerInventory->GetComponent();
if (!playerInventoryComponent) return;

auto playerEntity = playerInventoryComponent->GetParent();
if (!playerEntity) return;
auto* playerEntity = Game::entityManager->GetEntity(m_Owner);
if (!playerEntity) {
LOG("owner was null or didnt exist!");
return;
}

auto playerDestroyableComponent = playerEntity->GetComponent<DestroyableComponent>();
if (!playerDestroyableComponent) return;
Expand All @@ -878,12 +874,16 @@ void PetComponent::AddDrainImaginationTimer(Item* item, bool fromTaming) {
if (!fromTaming) playerDestroyableComponent->Imagine(-1);

// Set this to a variable so when this is called back from the player the timer doesn't fire off.
m_Parent->AddCallbackTimer(m_PetInfo.imaginationDrainRate, [playerDestroyableComponent, this, item]() {
if (!playerDestroyableComponent) {
LOG("No petComponent and/or no playerDestroyableComponent");
m_Parent->AddCallbackTimer(m_PetInfo.imaginationDrainRate, [this]() {
const auto* owner = Game::entityManager->GetEntity(m_Owner);
if (!owner) {
LOG("owner was null or didnt exist!");
return;
}

const auto* playerDestroyableComponent = owner->GetComponent<DestroyableComponent>();
if (!playerDestroyableComponent) return;

// If we are out of imagination despawn the pet.
if (playerDestroyableComponent->GetImagination() == 0) {
this->Deactivate();
Expand All @@ -893,15 +893,13 @@ void PetComponent::AddDrainImaginationTimer(Item* item, bool fromTaming) {
GameMessages::SendUseItemRequirementsResponse(playerEntity->GetObjectID(), playerEntity->GetSystemAddress(), eUseItemResponse::NoImaginationForPet);
}

this->AddDrainImaginationTimer(item);
this->AddDrainImaginationTimer();
});
}

void PetComponent::Deactivate() {
GameMessages::SendPlayFXEffect(m_Parent->GetObjectID(), -1, u"despawn", "", LWOOBJID_EMPTY, 1, 1, true);

GameMessages::SendMarkInventoryItemAsActive(m_Owner, false, eUnequippableActiveType::PET, m_ItemId, GetOwner()->GetSystemAddress());

activePets.erase(m_Owner);

m_Parent->Kill();
Expand All @@ -910,6 +908,8 @@ void PetComponent::Deactivate() {

if (owner == nullptr) return;

GameMessages::SendMarkInventoryItemAsActive(m_Owner, false, eUnequippableActiveType::PET, m_ItemId, owner->GetSystemAddress());

GameMessages::SendAddPetToPlayer(m_Owner, 0, u"", LWOOBJID_EMPTY, LOT_NULL, owner->GetSystemAddress());

GameMessages::SendRegisterPetID(m_Owner, LWOOBJID_EMPTY, owner->GetSystemAddress());
Expand Down Expand Up @@ -1034,6 +1034,7 @@ Entity* PetComponent::GetParentEntity() const {
}

PetComponent::~PetComponent() {
m_Owner = LWOOBJID_EMPTY;
}

void PetComponent::SetPetNameForModeration(const std::string& petName) {
Expand Down
2 changes: 1 addition & 1 deletion dGame/dComponents/PetComponent.h
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ class PetComponent final : public Component
*
* @param item The item that represents this pet in the inventory.
*/
void AddDrainImaginationTimer(Item* item, bool fromTaming = false);
void AddDrainImaginationTimer(bool fromTaming = false);

private:

Expand Down

0 comments on commit 0d218fc

Please sign in to comment.