* fixed up logon GUI, works now

* show logon gui when using "gui" command and not connected
* create realmsession only after pressing Login button on gui and not before
* cleaned up some parts of code that creates RealmSessions
* added some code (but not yet used) to exchange status messages between core & gui (threadsafe)
This commit is contained in:
false_genesis 2008-04-08 20:25:07 +00:00
parent c9b2217039
commit beb24440ea
15 changed files with 155 additions and 52 deletions

View File

@ -1016,8 +1016,11 @@ DefReturnResult DefScriptPackage::SCGui(CmdSet &Set)
ZThread::FastMutex mut; ZThread::FastMutex mut;
mut.acquire(); mut.acquire();
// TODO: not sure if this piece of code will work as intended, needs some testing if(!ins->GetWSession() && !ins->GetRSession())
if(ins->GetWSession() && ins->GetWSession()->InWorld()) {
ins->GetGUI()->SetSceneState(SCENESTATE_LOGINSCREEN);
}
else if(ins->GetWSession() && ins->GetWSession()->InWorld())
{ {
ins->GetGUI()->SetSceneState(SCENESTATE_WORLD); ins->GetGUI()->SetSceneState(SCENESTATE_WORLD);
ins->GetWSession()->objmgr.ReNotifyGUI(); ins->GetWSession()->objmgr.ReNotifyGUI();

View File

@ -285,6 +285,14 @@ void PseuGUI::_UpdateSceneState(void)
} }
} }
bool PseuGUI::SetSceneData(uint32 index, uint32 value)
{
if(!_scene)
return false;
_scene->SetData(index, value);
return true;
}
// used to get our current WorldPosition // used to get our current WorldPosition
WorldPosition PseuGUI::GetWorldPosition(void) WorldPosition PseuGUI::GetWorldPosition(void)

View File

@ -95,6 +95,8 @@ public:
// scenes // scenes
void SetSceneState(SceneState); void SetSceneState(SceneState);
bool SetSceneData(uint32, uint32);
inline uint32 GetSceneState(void) { return _scenestate; }
// helpers // helpers
WorldPosition GetWorldPosition(void); WorldPosition GetWorldPosition(void);

View File

@ -6,6 +6,7 @@
Scene::Scene(PseuGUI *g) Scene::Scene(PseuGUI *g)
{ {
memset(scenedata, 0, sizeof(uint32) * SCENEDATA_SIZE);
gui = g; gui = g;
device = gui->_device; device = gui->_device;
driver = gui->_driver; driver = gui->_driver;

View File

@ -2,6 +2,7 @@
#define _SCENE_H #define _SCENE_H
#include "irrlicht/irrlicht.h" #include "irrlicht/irrlicht.h"
#include "SceneData.h"
using namespace irr; using namespace irr;
using namespace core; using namespace core;
@ -28,6 +29,7 @@ public:
virtual void OnDrawBegin(void); virtual void OnDrawBegin(void);
virtual void OnDelete(void); virtual void OnDelete(void);
virtual video::SColor GetBackgroundColor(void); virtual video::SColor GetBackgroundColor(void);
virtual void SetData(uint32 index, uint32 value) { scenedata[index] = value; }
protected: protected:
PseuGUI *gui; PseuGUI *gui;
@ -37,6 +39,7 @@ protected:
irr::gui::IGUIEnvironment* guienv; irr::gui::IGUIEnvironment* guienv;
CCursorController *cursor; CCursorController *cursor;
SceneState _scenestate; SceneState _scenestate;
uint32 scenedata[SCENEDATA_SIZE]; // generic storage for anything the PseuInstance thread wants to tell us
}; };
class SceneGuiStart : public Scene class SceneGuiStart : public Scene
@ -110,6 +113,7 @@ private:
bool debugmode; bool debugmode;
std::map<uint32,SceneNodeWithGridPos> _doodads; std::map<uint32,SceneNodeWithGridPos> _doodads;
scene::ISceneNode *sky; scene::ISceneNode *sky;
scene::ISceneNode *selectedNode, *oldSelectedNode, *focusedNode, *oldFocusedNode;
video::SColor envBasicColor; video::SColor envBasicColor;
}; };

View File

@ -0,0 +1,27 @@
#ifndef SCENEDATA_H
#define SCENEDATA_H
#define SCENEDATA_SIZE 255
// I: index
// D: data value
enum SceneLoginDataIndexes
{
ISCENE_LOGIN_CONN_STATUS,
ISCENE_LOGIN_END
};
enum SceneLoginConnStatus
{
DSCENE_LOGIN_NOT_CONNECTED,
DSCENE_LOGIN_CONN_ATTEMPT,
DSCENE_LOGIN_CONN_FAILED,
DSCENE_LOGIN_LOGGING_IN,
DSCENE_LOGIN_AUTHENTICATING,
DSCENE_LOGIN_AUTH_FAILED,
DSCENE_LOGIN_AUTH_OK
};
#endif

View File

@ -59,6 +59,7 @@ SceneLogin::SceneLogin(PseuGUI *gui) : Scene(gui)
background = guienv->addImage(driver->getTexture("data/misc/sky.jpg"), core::position2d<s32>(5,5),true,root); background = guienv->addImage(driver->getTexture("data/misc/sky.jpg"), core::position2d<s32>(5,5),true,root);
background->setRelativePosition(rect<s32>(0,0,scrn.Width,scrn.Height)); background->setRelativePosition(rect<s32>(0,0,scrn.Width,scrn.Height));
irrlogo->setScaleImage(true); irrlogo->setScaleImage(true);
guienv->addStaticText(L"Account:",rect<s32>((scrn.Width*0.5f)-90, (scrn.Height*0.3f)-10, (scrn.Width*0.5f)+90, (scrn.Height*0.3f)+10), false, false, 0, 0); guienv->addStaticText(L"Account:",rect<s32>((scrn.Width*0.5f)-90, (scrn.Height*0.3f)-10, (scrn.Width*0.5f)+90, (scrn.Height*0.3f)+10), false, false, 0, 0);
guienv->addStaticText(L"Password:", rect<s32>((scrn.Width*0.5f)-90, (scrn.Height*0.3f)+50, (scrn.Width*0.5f)+90, (scrn.Height*0.3f)+70), false, false, 0, 0); guienv->addStaticText(L"Password:", rect<s32>((scrn.Width*0.5f)-90, (scrn.Height*0.3f)+50, (scrn.Width*0.5f)+90, (scrn.Height*0.3f)+70), false, false, 0, 0);
guienv->addEditBox(L"", rect<s32>((scrn.Width*0.5f)-90, (scrn.Height*0.3f)+10, (scrn.Width*0.5f)+90, (scrn.Height*0.3f)+30), true, 0, 1); guienv->addEditBox(L"", rect<s32>((scrn.Width*0.5f)-90, (scrn.Height*0.3f)+10, (scrn.Width*0.5f)+90, (scrn.Height*0.3f)+30), true, 0, 1);
@ -80,17 +81,26 @@ void SceneLogin::OnUpdate(s32 timepassed)
} }
if(eventrecv->buttons & BUTTON_LOGON) if(eventrecv->buttons & BUTTON_LOGON)
{ {
eventrecv->buttons=0;
logdebug("Commencing Logon"); logdebug("Commencing Logon");
core::stringc tmp; core::stringc tmp;
tmp=root->getElementFromId(TEXTBOX_NAME,true)->getText(); tmp=root->getElementFromId(TEXTBOX_NAME,true)->getText();
std::string accname =tmp.c_str(); std::string accname =tmp.c_str();
tmp=root->getElementFromId(TEXTBOX_PASSWORD,true)->getText(); tmp=root->getElementFromId(TEXTBOX_PASSWORD,true)->getText();
std::string accpass=tmp.c_str(); std::string accpass=tmp.c_str();
if(accname.size() && accpass.size())
{
logdebug("Trying to set Logon Data %u, %u", accname.size(), accpass.size()); logdebug("Trying to set Logon Data %u, %u", accname.size(), accpass.size());
_gui->GetInstance()->GetRSession()->SetLogonData(accname,accpass); // we can safely override the conf settings
_gui->GetInstance()->GetRSession()->SendLogonChallenge(); _gui->GetInstance()->GetConf()->accname = accname;
eventrecv->buttons=0; _gui->GetInstance()->GetConf()->accpass = accpass;
_gui->GetInstance()->login=true; _gui->GetInstance()->CreateRealmSession();
}
else
{
guienv->addMessageBox(L"Oh noes!", L"You have to enter account name and password!");
}
} }
} }

View File

@ -49,6 +49,7 @@ SceneWorld::SceneWorld(PseuGUI *g) : Scene(g)
smgr->setShadowColor(); // set shadow to default color smgr->setShadowColor(); // set shadow to default color
sky = NULL; sky = NULL;
selectedNode = oldSelectedNode = NULL;
//sky = smgr->addSkyDomeSceneNode(driver->getTexture("data/misc/sky.jpg"),64,64,1.0f,2.0f); //sky = smgr->addSkyDomeSceneNode(driver->getTexture("data/misc/sky.jpg"),64,64,1.0f,2.0f);
/* // TODO: for now let irrlicht draw the skybox /* // TODO: for now let irrlicht draw the skybox
sky->grab(); // if the camera clip is set too short, the sky will not be rendered properly. sky->grab(); // if the camera clip is set too short, the sky will not be rendered properly.
@ -91,6 +92,15 @@ void SceneWorld::OnUpdate(s32 timediff)
cursor->setVisible(true); cursor->setVisible(true);
} }
// object focused - only check if mouse moved, saves CPU
// TODO: check if camera moved, also (maybe from external source)
if(false && mouse_pos != cursor->getMousePos())
{
focusedNode = smgr->getSceneCollisionManager()->getSceneNodeFromScreenCoordinatesBB(cursor->getMousePos());
if(focusedNode && mouse_pressed_left)
selectedNode = focusedNode;
}
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))
camera->moveForward(50 * timediff_f); camera->moveForward(50 * timediff_f);
@ -151,6 +161,7 @@ void SceneWorld::OnUpdate(s32 timediff)
} }
} }
// this fixes the camera getting screwed up by noob user; resets it back to a usable position if someone managed to flip it over
if(camera->getPitch() < 270 && camera->getPitch() > 90) if(camera->getPitch() < 270 && camera->getPitch() > 90)
camera->turnUp(90); camera->turnUp(90);

View File

@ -14,6 +14,7 @@
#include "GUI/PseuGUI.h" #include "GUI/PseuGUI.h"
#include "RemoteController.h" #include "RemoteController.h"
#include "Cli.h" #include "Cli.h"
#include "GUI/SceneData.h"
//###### Start of program code ####### //###### Start of program code #######
@ -60,6 +61,7 @@ PseuInstance::PseuInstance(PseuInstanceRunnable *run)
_fastquit=false; _fastquit=false;
_startrealm=true; _startrealm=true;
_createws=false; _createws=false;
_creaters=false;
_error=false; _error=false;
_initialized=false; _initialized=false;
@ -157,8 +159,6 @@ bool PseuInstance::Init(void)
return false; return false;
} }
login=false;//No GUI Login attempted yet
log("Init complete."); log("Init complete.");
_initialized=true; _initialized=true;
return true; return true;
@ -224,18 +224,11 @@ void PseuInstance::Run(void)
} }
else else
{ {
// for now: create the realmsession only on startup.
// may be extended to a script command later on.
// then try to connect
_rsession = new RealmSession(this);
_rsession->Connect();
if(!GetConf()->enablegui || !(GetConf()->accname.empty() || GetConf()->accpass.empty()) ) if(!GetConf()->enablegui || !(GetConf()->accname.empty() || GetConf()->accpass.empty()) )
{ {
logdebug("GUI not active or Login data pre-entered, skipping Login GUI"); logdebug("GUI not active or Login data pre-entered, skipping Login GUI");
CreateRealmSession();
_rsession->SetLogonData();
_rsession->SendLogonChallenge();
} }
else else
{ {
@ -307,24 +300,36 @@ void PseuInstance::Update()
_wsession->Start(); _wsession->Start();
} }
// if we have no active sessions, we may reconnect, if no GUI is active for login if(_creaters)
if((!_rsession) && (!_wsession) && GetConf()->reconnect && !(login||GetConf()->enablegui))
{ {
_creaters = false;
if(_rsession)
delete _rsession;
ConnectToRealm();
}
// if we have no active sessions, we may reconnect, if no GUI is active for login
if((!_rsession) && (!_wsession) && GetConf()->reconnect && !_gui)
{
if(GetConf()->accname.empty() || GetConf()->accpass.empty())
{
logdev("Skipping reconnect, acc name or password not set");
}
else
{ // everything fine, we have all data
logdetail("Waiting %u ms before reconnecting.",GetConf()->reconnect); logdetail("Waiting %u ms before reconnecting.",GetConf()->reconnect);
for(uint32 t = 0; t < GetConf()->reconnect && !this->Stopped(); t+=100) Sleep(100); for(uint32 t = 0; t < GetConf()->reconnect && !this->Stopped(); t+=100) Sleep(100);
this->Sleep(1000); // wait 1 sec before reconnecting this->Sleep(1000); // wait 1 sec before reconnecting
_rsession = new RealmSession(this); CreateRealmSession();
_rsession->Connect();
_rsession->SetLogonData();
_rsession->SendLogonChallenge(); // and login again
} }
if((!_rsession) && (!_wsession) && GetConf()->enablegui && login) }
if((!_rsession) && (!_wsession) && _gui)
{
if(_gui->GetSceneState() != SCENESTATE_LOGINSCREEN)
{ {
logdetail("Disconnected, switching GUI back to Loginscreen."); logdetail("Disconnected, switching GUI back to Loginscreen.");
_rsession = new RealmSession(this);
_rsession->Connect();
_gui->SetSceneState(SCENESTATE_LOGINSCREEN); _gui->SetSceneState(SCENESTATE_LOGINSCREEN);
login=false; }
} }
// update currently existing/active sessions // update currently existing/active sessions
@ -400,6 +405,24 @@ void PseuInstance::DeleteGUI(void)
AddCliCommand("_onguiclose"); // since this func is called from another thread, use threadsafe variant via CLI AddCliCommand("_onguiclose"); // since this func is called from another thread, use threadsafe variant via CLI
} }
bool PseuInstance::ConnectToRealm(void)
{
_rsession = new RealmSession(this);
_rsession->SetLogonData(); // get accname & accpass from PseuInstanceConfig and set it in the realm session
_rsession->Connect();
if(_rsession->MustDie()) // something failed. it will be deleted in next Update() call
{
logerror("Connecting to Realm failed!");
if(_gui)
_gui->SetSceneData(ISCENE_LOGIN_CONN_STATUS, DSCENE_LOGIN_CONN_FAILED);
return false;
}
_rsession->SendLogonChallenge();
return true;
}
PseuInstanceConf::PseuInstanceConf() PseuInstanceConf::PseuInstanceConf()
{ {
enablecli=false; enablecli=false;

View File

@ -81,6 +81,7 @@ public:
inline PseuInstanceRunnable *GetRunnable(void) { return _runnable; } inline PseuInstanceRunnable *GetRunnable(void) { return _runnable; }
inline PseuGUI *GetGUI(void) { return _gui; } inline PseuGUI *GetGUI(void) { return _gui; }
void DeleteGUI(void); void DeleteGUI(void);
bool ConnectToRealm(void);
inline void SetConfDir(std::string dir) { _confdir = dir; } inline void SetConfDir(std::string dir) { _confdir = dir; }
inline std::string GetConfDir(void) { return _confdir; } inline std::string GetConfDir(void) { return _confdir; }
@ -101,10 +102,10 @@ public:
void Sleep(uint32 msecs); void Sleep(uint32 msecs);
inline void CreateWorldSession(void) { _createws = true; } inline void CreateWorldSession(void) { _createws = true; }
inline void CreateRealmSession(void) { _creaters = true; }
void ProcessCliQueue(void); void ProcessCliQueue(void);
void AddCliCommand(std::string); void AddCliCommand(std::string);
bool login;//Set when GUI attempts to login
private: private:
@ -118,7 +119,7 @@ private:
bool _stop,_fastquit; bool _stop,_fastquit;
bool _startrealm; bool _startrealm;
bool _error; bool _error;
bool _createws; bool _createws, _creaters; // must create world/realm session?
BigNumber _sessionkey; BigNumber _sessionkey;
char *_ver,*_ver_short; char *_ver,*_ver_short;
SocketHandler _sh; SocketHandler _sh;

View File

@ -301,13 +301,6 @@ void RealmSession::SetLogonData(void)
_accpass=GetInstance()->GetConf()->accpass; _accpass=GetInstance()->GetConf()->accpass;
} }
void RealmSession::SetLogonData(std::string accname, std::string accpass)
{
_accname=accname;
_accpass=accpass;
logdebug("Data Set");
}
void RealmSession::SendLogonChallenge(void) void RealmSession::SendLogonChallenge(void)
{ {
if(!_socket) if(!_socket)

View File

@ -18,7 +18,6 @@ public:
PseuInstance *GetInstance(void); PseuInstance *GetInstance(void);
void ClearSocket(void); void ClearSocket(void);
void SetLogonData(void); void SetLogonData(void);
void SetLogonData(std::string, std::string);
void SendLogonChallenge(void); void SendLogonChallenge(void);
bool MustDie(void); bool MustDie(void);
void SetMustDie(void); void SetMustDie(void);

View File

@ -133,6 +133,14 @@ void WorldSession::Update(void)
} }
} }
// process the send queue and send packets buffered by other threads
while(sendPktQueue.size())
{
WorldPacket *pkt = sendPktQueue.next();
SendWorldPacket(*pkt);
delete pkt;
}
// while there are packets on the queue, handle them // while there are packets on the queue, handle them
while(pktQueue.size()) while(pktQueue.size())
{ {
@ -338,6 +346,12 @@ void WorldSession::_HandleDelayedPackets(void)
} }
} }
// use this func to send packets from other threads
void WorldSession::AddSendWorldPacket(WorldPacket *pkt)
{
sendPktQueue.add(pkt);
}
void WorldSession::SetTarget(uint64 guid) void WorldSession::SetTarget(uint64 guid)
{ {

View File

@ -60,6 +60,7 @@ public:
inline bool MustDie(void) { return _mustdie; } inline bool MustDie(void) { return _mustdie; }
void SetMustDie(void); void SetMustDie(void);
void SendWorldPacket(WorldPacket&); void SendWorldPacket(WorldPacket&);
void AddSendWorldPacket(WorldPacket *pkt);
inline bool InWorld(void) { return _logged; } inline bool InWorld(void) { return _logged; }
inline uint32 GetLagMS(void) { return _lag_ms; } inline uint32 GetLagMS(void) { return _lag_ms; }
@ -148,7 +149,7 @@ private:
PseuInstance *_instance; PseuInstance *_instance;
WorldSocket *_socket; WorldSocket *_socket;
ZThread::LockedQueue<WorldPacket*,ZThread::FastMutex> pktQueue; ZThread::LockedQueue<WorldPacket*,ZThread::FastMutex> pktQueue, sendPktQueue;
DelayedPacketQueue delayedPktQueue; DelayedPacketQueue delayedPktQueue;
bool _logged,_mustdie; // world status bool _logged,_mustdie; // world status
SocketHandler _sh; // handles the WorldSocket SocketHandler _sh; // handles the WorldSocket

View File

@ -465,9 +465,15 @@
<File <File
RelativePath=".\Client\Gui\Scene.h"> RelativePath=".\Client\Gui\Scene.h">
</File> </File>
<File
RelativePath=".\Client\Gui\SceneData.h">
</File>
<File <File
RelativePath=".\Client\Gui\SceneGuiStart.cpp"> RelativePath=".\Client\Gui\SceneGuiStart.cpp">
</File> </File>
<File
RelativePath=".\Client\Gui\SceneLogin.cpp">
</File>
<File <File
RelativePath=".\Client\Gui\SceneWorld.cpp"> RelativePath=".\Client\Gui\SceneWorld.cpp">
</File> </File>