summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorThorbjørn Lindeijer <bjorn@lindeijer.nl>2025-04-01 11:40:37 +0200
committerThorbjørn Lindeijer <bjorn@lindeijer.nl>2025-04-01 11:40:41 +0200
commitce60630c42e232bf81f22019e3499d6036a68f7e (patch)
tree08c7615faf264149229fbc681b708d5bd14d2259 /src
parent1d41d71eff082bb3232962ac6c4c68051f771da0 (diff)
downloadmana-ce60630c42e232bf81f22019e3499d6036a68f7e.tar.gz
mana-ce60630c42e232bf81f22019e3499d6036a68f7e.tar.bz2
mana-ce60630c42e232bf81f22019e3499d6036a68f7e.tar.xz
mana-ce60630c42e232bf81f22019e3499d6036a68f7e.zip
Fixed crash on exit when CharCreateDialog is open
* Displayed Being was deleting its SpeechBubble after the WindowContainer had already deleted it. Resolved by registering a DeathListener. * On dialog deletion, the CharHandler had become a roaming pointer but was still accessed.
Diffstat (limited to 'src')
-rw-r--r--src/being.cpp10
-rw-r--r--src/being.h7
-rw-r--r--src/gui/charcreatedialog.cpp3
-rw-r--r--src/net/net.cpp24
4 files changed, 34 insertions, 10 deletions
diff --git a/src/being.cpp b/src/being.cpp
index bbecf712..d239b9e8 100644
--- a/src/being.cpp
+++ b/src/being.cpp
@@ -70,6 +70,7 @@ Being::Being(int id, Type type, int subtype, Map *map)
setType(type, subtype);
mSpeechBubble = new SpeechBubble;
+ mSpeechBubble->addDeathListener(this);
mMoveSpeed = Net::getPlayerHandler()->getDefaultMoveSpeed();
@@ -82,9 +83,6 @@ Being::~Being()
delete mSpeechBubble;
delete mDispName;
delete mText;
- mSpeechBubble = nullptr;
- mDispName = nullptr;
- mText = nullptr;
}
/**
@@ -1395,6 +1393,12 @@ void Being::event(Event::Channel channel, const Event &event)
}
}
+void Being::death(const gcn::Event &event)
+{
+ if (event.getSource() == mSpeechBubble)
+ mSpeechBubble = nullptr;
+}
+
void Being::setMap(Map *map)
{
for (auto &spriteState : mSpriteStates)
diff --git a/src/being.h b/src/being.h
index 6cc0575f..38f5f149 100644
--- a/src/being.h
+++ b/src/being.h
@@ -31,6 +31,7 @@
#include "utils/time.h"
#include <guichan/color.hpp>
+#include <guichan/deathlistener.hpp>
#include <cstdint>
#include <map>
@@ -61,7 +62,7 @@ enum class Gender
HIDDEN = 3
};
-class Being : public ActorSprite, public EventListener
+class Being : public ActorSprite, public EventListener, public gcn::DeathListener
{
public:
/**
@@ -438,8 +439,12 @@ class Being : public ActorSprite, public EventListener
void talkTo();
+ // EventListener
void event(Event::Channel channel, const Event &event) override;
+ // gcn::DeathListener
+ void death(const gcn::Event &event) override;
+
void setMap(Map *map) final;
/**
diff --git a/src/gui/charcreatedialog.cpp b/src/gui/charcreatedialog.cpp
index fb834933..d5bdf3ca 100644
--- a/src/gui/charcreatedialog.cpp
+++ b/src/gui/charcreatedialog.cpp
@@ -167,7 +167,8 @@ CharCreateDialog::~CharCreateDialog()
delete mPlayer;
// Make sure the char server handler knows that we're gone
- Net::getCharHandler()->setCharCreateDialog(nullptr);
+ if (auto charHandler = Net::getCharHandler())
+ charHandler->setCharCreateDialog(nullptr);
}
void CharCreateDialog::action(const gcn::ActionEvent &event)
diff --git a/src/net/net.cpp b/src/net/net.cpp
index dc86bc89..a2771244 100644
--- a/src/net/net.cpp
+++ b/src/net/net.cpp
@@ -176,11 +176,25 @@ void connectToServer(ServerInfo &server)
void unload()
{
- if (generalHandler)
- {
- generalHandler->unload();
- delete generalHandler;
- }
+ if (!generalHandler)
+ return;
+
+ generalHandler->unload();
+ delete generalHandler;
+
+ adminHandler = nullptr;
+ charHandler = nullptr;
+ chatHandler = nullptr;
+ generalHandler = nullptr;
+ inventoryHandler = nullptr;
+ loginHandler = nullptr;
+ gameHandler = nullptr;
+ guildHandler = nullptr;
+ npcHandler = nullptr;
+ partyHandler = nullptr;
+ playerHandler = nullptr;
+ abilityHandler = nullptr;
+ tradeHandler = nullptr;
}
ServerType getNetworkType()