* 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;
mut.acquire();
// TODO: not sure if this piece of code will work as intended, needs some testing
if(ins->GetWSession() && ins->GetWSession()->InWorld())
if(!ins->GetWSession() && !ins->GetRSession())
{
ins->GetGUI()->SetSceneState(SCENESTATE_LOGINSCREEN);
}
else if(ins->GetWSession() && ins->GetWSession()->InWorld())
{
ins->GetGUI()->SetSceneState(SCENESTATE_WORLD);
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
WorldPosition PseuGUI::GetWorldPosition(void)

View File

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

View File

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

View File

@ -2,6 +2,7 @@
#define _SCENE_H
#include "irrlicht/irrlicht.h"
#include "SceneData.h"
using namespace irr;
using namespace core;
@ -28,6 +29,7 @@ public:
virtual void OnDrawBegin(void);
virtual void OnDelete(void);
virtual video::SColor GetBackgroundColor(void);
virtual void SetData(uint32 index, uint32 value) { scenedata[index] = value; }
protected:
PseuGUI *gui;
@ -37,6 +39,7 @@ protected:
irr::gui::IGUIEnvironment* guienv;
CCursorController *cursor;
SceneState _scenestate;
uint32 scenedata[SCENEDATA_SIZE]; // generic storage for anything the PseuInstance thread wants to tell us
};
class SceneGuiStart : public Scene
@ -110,6 +113,7 @@ private:
bool debugmode;
std::map<uint32,SceneNodeWithGridPos> _doodads;
scene::ISceneNode *sky;
scene::ISceneNode *selectedNode, *oldSelectedNode, *focusedNode, *oldFocusedNode;
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,13 +59,14 @@ SceneLogin::SceneLogin(PseuGUI *gui) : Scene(gui)
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));
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"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)+70, (scrn.Width*0.5f)+90, (scrn.Height*0.3f)+90), true, 0, 2)->setPasswordBox(true);
guienv->addButton(rect<s32>(scrn.Width-120, scrn.Height-40, scrn.Width-10, scrn.Height-10), 0, 4, L"Quit");
guienv->addButton(rect<s32>(10, scrn.Height-40, 120, scrn.Height-10), 0, 8, L"Community Site");
guienv->addButton(rect<s32>((scrn.Width*0.5f)-60, (scrn.Height*0.3f)+100, (scrn.Width*0.5f)+60, (scrn.Height*0.3f)+130), 0, 16, L"Logon");
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->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)+70, (scrn.Width*0.5f)+90, (scrn.Height*0.3f)+90), true, 0, 2)->setPasswordBox(true);
guienv->addButton(rect<s32>(scrn.Width-120, scrn.Height-40, scrn.Width-10, scrn.Height-10), 0, 4, L"Quit");
guienv->addButton(rect<s32>(10, scrn.Height-40, 120, scrn.Height-10), 0, 8, L"Community Site");
guienv->addButton(rect<s32>((scrn.Width*0.5f)-60, (scrn.Height*0.3f)+100, (scrn.Width*0.5f)+60, (scrn.Height*0.3f)+130), 0, 16, L"Logon");
}
@ -80,17 +81,26 @@ void SceneLogin::OnUpdate(s32 timepassed)
}
if(eventrecv->buttons & BUTTON_LOGON)
{
eventrecv->buttons=0;
logdebug("Commencing Logon");
core::stringc tmp;
tmp=root->getElementFromId(TEXTBOX_NAME,true)->getText();
std::string accname =tmp.c_str();
tmp=root->getElementFromId(TEXTBOX_PASSWORD,true)->getText();
std::string accpass=tmp.c_str();
if(accname.size() && accpass.size())
{
logdebug("Trying to set Logon Data %u, %u", accname.size(), accpass.size());
_gui->GetInstance()->GetRSession()->SetLogonData(accname,accpass);
_gui->GetInstance()->GetRSession()->SendLogonChallenge();
eventrecv->buttons=0;
_gui->GetInstance()->login=true;
// we can safely override the conf settings
_gui->GetInstance()->GetConf()->accname = accname;
_gui->GetInstance()->GetConf()->accpass = accpass;
_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
sky = NULL;
selectedNode = oldSelectedNode = NULL;
//sky = smgr->addSkyDomeSceneNode(driver->getTexture("data/misc/sky.jpg"),64,64,1.0f,2.0f);
/* // 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.
@ -91,6 +92,15 @@ void SceneWorld::OnUpdate(s32 timediff)
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))
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)
camera->turnUp(90);

View File

@ -14,6 +14,7 @@
#include "GUI/PseuGUI.h"
#include "RemoteController.h"
#include "Cli.h"
#include "GUI/SceneData.h"
//###### Start of program code #######
@ -60,6 +61,7 @@ PseuInstance::PseuInstance(PseuInstanceRunnable *run)
_fastquit=false;
_startrealm=true;
_createws=false;
_creaters=false;
_error=false;
_initialized=false;
@ -157,8 +159,6 @@ bool PseuInstance::Init(void)
return false;
}
login=false;//No GUI Login attempted yet
log("Init complete.");
_initialized=true;
return true;
@ -224,18 +224,11 @@ void PseuInstance::Run(void)
}
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");
_rsession->SetLogonData();
_rsession->SendLogonChallenge();
CreateRealmSession();
}
else
{
@ -307,24 +300,36 @@ void PseuInstance::Update()
_wsession->Start();
}
// if we have no active sessions, we may reconnect, if no GUI is active for login
if((!_rsession) && (!_wsession) && GetConf()->reconnect && !(login||GetConf()->enablegui))
if(_creaters)
{
_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);
for(uint32 t = 0; t < GetConf()->reconnect && !this->Stopped(); t+=100) Sleep(100);
this->Sleep(1000); // wait 1 sec before reconnecting
_rsession = new RealmSession(this);
_rsession->Connect();
_rsession->SetLogonData();
_rsession->SendLogonChallenge(); // and login again
CreateRealmSession();
}
if((!_rsession) && (!_wsession) && GetConf()->enablegui && login)
}
if((!_rsession) && (!_wsession) && _gui)
{
if(_gui->GetSceneState() != SCENESTATE_LOGINSCREEN)
{
logdetail("Disconnected, switching GUI back to Loginscreen.");
_rsession = new RealmSession(this);
_rsession->Connect();
_gui->SetSceneState(SCENESTATE_LOGINSCREEN);
login=false;
}
}
// 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
}
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()
{
enablecli=false;

View File

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

View File

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

View File

@ -18,7 +18,6 @@ public:
PseuInstance *GetInstance(void);
void ClearSocket(void);
void SetLogonData(void);
void SetLogonData(std::string, std::string);
void SendLogonChallenge(void);
bool MustDie(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(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)
{

View File

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

View File

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