* fixed crash when disconnected from server (WorldSession got deleted while SceneWorld still accessing WorldSession members)

This commit is contained in:
false_genesis 2008-04-08 20:58:54 +00:00
parent beb24440ea
commit 23cb869665
7 changed files with 28 additions and 6 deletions

View File

@ -293,6 +293,13 @@ bool PseuGUI::SetSceneData(uint32 index, uint32 value)
return true; return true;
} }
uint32 PseuGUI::GetSceneState(void)
{
if(!_scene)
return SCENESTATE_NOSCENE;
return _scene->GetState();
}
// used to get our current WorldPosition // used to get our current WorldPosition
WorldPosition PseuGUI::GetWorldPosition(void) WorldPosition PseuGUI::GetWorldPosition(void)

View File

@ -12,12 +12,13 @@ class Scene;
enum SceneState enum SceneState
{ {
SCENESTATE_NULL, SCENESTATE_NULL = 0,
SCENESTATE_GUISTART, SCENESTATE_GUISTART,
SCENESTATE_LOGINSCREEN, SCENESTATE_LOGINSCREEN,
SCENESTATE_CHARACTERSELECTION, SCENESTATE_CHARACTERSELECTION,
SCENESTATE_LOADING, SCENESTATE_LOADING,
SCENESTATE_WORLD SCENESTATE_WORLD,
SCENESTATE_NOSCENE = 0xFFFFFFFF
}; };
enum DriverIDs enum DriverIDs
@ -96,7 +97,7 @@ public:
// scenes // scenes
void SetSceneState(SceneState); void SetSceneState(SceneState);
bool SetSceneData(uint32, uint32); bool SetSceneData(uint32, uint32);
inline uint32 GetSceneState(void) { return _scenestate; } uint32 GetSceneState(void);
// helpers // helpers
WorldPosition GetWorldPosition(void); WorldPosition GetWorldPosition(void);

View File

@ -8,6 +8,7 @@ Scene::Scene(PseuGUI *g)
{ {
memset(scenedata, 0, sizeof(uint32) * SCENEDATA_SIZE); memset(scenedata, 0, sizeof(uint32) * SCENEDATA_SIZE);
gui = g; gui = g;
instance = gui->GetInstance();
device = gui->_device; device = gui->_device;
driver = gui->_driver; driver = gui->_driver;
smgr = gui->_smgr; smgr = gui->_smgr;
@ -15,6 +16,7 @@ Scene::Scene(PseuGUI *g)
cursor = new CCursorController(device->getCursorControl(), driver); cursor = new CCursorController(device->getCursorControl(), driver);
cursor->setOSCursorVisible(true); cursor->setOSCursorVisible(true);
cursor->setVisible(false); cursor->setVisible(false);
cursor->render(); // apply above settings
} }
void Scene::OnDraw(void) void Scene::OnDraw(void)

View File

@ -31,7 +31,7 @@ public:
virtual video::SColor GetBackgroundColor(void); virtual video::SColor GetBackgroundColor(void);
virtual void SetData(uint32 index, uint32 value) { scenedata[index] = value; } virtual void SetData(uint32 index, uint32 value) { scenedata[index] = value; }
protected: protected:
PseuInstance *instance;
PseuGUI *gui; PseuGUI *gui;
irr::IrrlichtDevice *device; irr::IrrlichtDevice *device;
irr::video::IVideoDriver* driver; irr::video::IVideoDriver* driver;

View File

@ -94,12 +94,12 @@ void SceneWorld::OnUpdate(s32 timediff)
// object focused - only check if mouse moved, saves CPU // object focused - only check if mouse moved, saves CPU
// TODO: check if camera moved, also (maybe from external source) // TODO: check if camera moved, also (maybe from external source)
if(false && mouse_pos != cursor->getMousePos()) /*if(mouse_pos != cursor->getMousePos())
{ {
focusedNode = smgr->getSceneCollisionManager()->getSceneNodeFromScreenCoordinatesBB(cursor->getMousePos()); focusedNode = smgr->getSceneCollisionManager()->getSceneNodeFromScreenCoordinatesBB(cursor->getMousePos());
if(focusedNode && mouse_pressed_left) if(focusedNode && mouse_pressed_left)
selectedNode = focusedNode; selectedNode = focusedNode;
} }*/ // i'll continue working on this - [FG]
if(eventrecv->key.pressed(KEY_KEY_W) || (mouse_pressed_left && mouse_pressed_right)) if(eventrecv->key.pressed(KEY_KEY_W) || (mouse_pressed_left && mouse_pressed_right))

View File

@ -329,6 +329,8 @@ void PseuInstance::Update()
{ {
logdetail("Disconnected, switching GUI back to Loginscreen."); logdetail("Disconnected, switching GUI back to Loginscreen.");
_gui->SetSceneState(SCENESTATE_LOGINSCREEN); _gui->SetSceneState(SCENESTATE_LOGINSCREEN);
while(_gui->GetSceneState() != SCENESTATE_LOGINSCREEN) // .. and wait until scenestate is set
Sleep(1);
} }
} }

View File

@ -40,6 +40,16 @@ WorldSession::WorldSession(PseuInstance *in)
WorldSession::~WorldSession() WorldSession::~WorldSession()
{ {
if(PseuGUI *gui = GetInstance()->GetGUI())
{
if(gui->GetSceneState() == SCENESTATE_WORLD)
gui->SetSceneState(SCENESTATE_LOGINSCREEN); // kick back to login gui
logdebug("~WorldSession(): Waiting until world GUI is deleted");
while(gui->GetSceneState() == SCENESTATE_GUISTART) // .. and wait until the world gui is really deleted
GetInstance()->Sleep(1); // (it can cause crash otherwise)
logdebug("~WorldSession(): ... world GUI deleted, continuing to close session");
}
_instance->GetScripts()->RunScriptIfExists("_onworldsessiondelete"); _instance->GetScripts()->RunScriptIfExists("_onworldsessiondelete");
logdebug("~WorldSession(): %u packets left unhandled, and %u delayed. deleting.",pktQueue.size(),delayedPktQueue.size()); logdebug("~WorldSession(): %u packets left unhandled, and %u delayed. deleting.",pktQueue.size(),delayedPktQueue.size());