diff --git a/src/Client/DefScriptInterface.cpp b/src/Client/DefScriptInterface.cpp index 8ecdc13..50bafda 100644 --- a/src/Client/DefScriptInterface.cpp +++ b/src/Client/DefScriptInterface.cpp @@ -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(); diff --git a/src/Client/GUI/PseuGUI.cpp b/src/Client/GUI/PseuGUI.cpp index 4042d17..21e6348 100644 --- a/src/Client/GUI/PseuGUI.cpp +++ b/src/Client/GUI/PseuGUI.cpp @@ -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) diff --git a/src/Client/GUI/PseuGUI.h b/src/Client/GUI/PseuGUI.h index bfea5a9..b5cc6ae 100644 --- a/src/Client/GUI/PseuGUI.h +++ b/src/Client/GUI/PseuGUI.h @@ -95,6 +95,8 @@ public: // scenes void SetSceneState(SceneState); + bool SetSceneData(uint32, uint32); + inline uint32 GetSceneState(void) { return _scenestate; } // helpers WorldPosition GetWorldPosition(void); diff --git a/src/Client/GUI/Scene.cpp b/src/Client/GUI/Scene.cpp index e7fcc76..0a2edd6 100644 --- a/src/Client/GUI/Scene.cpp +++ b/src/Client/GUI/Scene.cpp @@ -6,6 +6,7 @@ Scene::Scene(PseuGUI *g) { + memset(scenedata, 0, sizeof(uint32) * SCENEDATA_SIZE); gui = g; device = gui->_device; driver = gui->_driver; diff --git a/src/Client/GUI/Scene.h b/src/Client/GUI/Scene.h index a9639e0..74bd417 100644 --- a/src/Client/GUI/Scene.h +++ b/src/Client/GUI/Scene.h @@ -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 _doodads; scene::ISceneNode *sky; + scene::ISceneNode *selectedNode, *oldSelectedNode, *focusedNode, *oldFocusedNode; video::SColor envBasicColor; }; diff --git a/src/Client/GUI/SceneData.h b/src/Client/GUI/SceneData.h new file mode 100644 index 0000000..6af1395 --- /dev/null +++ b/src/Client/GUI/SceneData.h @@ -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 diff --git a/src/Client/GUI/SceneLogin.cpp b/src/Client/GUI/SceneLogin.cpp index 1184413..7b2a4b3 100644 --- a/src/Client/GUI/SceneLogin.cpp +++ b/src/Client/GUI/SceneLogin.cpp @@ -59,13 +59,14 @@ SceneLogin::SceneLogin(PseuGUI *gui) : Scene(gui) background = guienv->addImage(driver->getTexture("data/misc/sky.jpg"), core::position2d(5,5),true,root); background->setRelativePosition(rect(0,0,scrn.Width,scrn.Height)); irrlogo->setScaleImage(true); -guienv->addStaticText(L"Account:",rect((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((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((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((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(scrn.Width-120, scrn.Height-40, scrn.Width-10, scrn.Height-10), 0, 4, L"Quit"); -guienv->addButton(rect(10, scrn.Height-40, 120, scrn.Height-10), 0, 8, L"Community Site"); -guienv->addButton(rect((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((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((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((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((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(scrn.Width-120, scrn.Height-40, scrn.Width-10, scrn.Height-10), 0, 4, L"Quit"); + guienv->addButton(rect(10, scrn.Height-40, 120, scrn.Height-10), 0, 8, L"Community Site"); + guienv->addButton(rect((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(); - 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; + if(accname.size() && accpass.size()) + { + logdebug("Trying to set Logon Data %u, %u", accname.size(), accpass.size()); + // 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!"); + } + } } diff --git a/src/Client/GUI/SceneWorld.cpp b/src/Client/GUI/SceneWorld.cpp index 0f58715..bfb3d04 100644 --- a/src/Client/GUI/SceneWorld.cpp +++ b/src/Client/GUI/SceneWorld.cpp @@ -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); diff --git a/src/Client/PseuWoW.cpp b/src/Client/PseuWoW.cpp index caebdde..d55708a 100644 --- a/src/Client/PseuWoW.cpp +++ b/src/Client/PseuWoW.cpp @@ -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) { - 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 + _creaters = false; + if(_rsession) + delete _rsession; + ConnectToRealm(); } - if((!_rsession) && (!_wsession) && GetConf()->enablegui && login) + + // if we have no active sessions, we may reconnect, if no GUI is active for login + if((!_rsession) && (!_wsession) && GetConf()->reconnect && !_gui) { - logdetail("Disconnected, switching GUI back to Loginscreen."); - _rsession = new RealmSession(this); - _rsession->Connect(); - _gui->SetSceneState(SCENESTATE_LOGINSCREEN); - login=false; + 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 + CreateRealmSession(); + } + } + if((!_rsession) && (!_wsession) && _gui) + { + if(_gui->GetSceneState() != SCENESTATE_LOGINSCREEN) + { + logdetail("Disconnected, switching GUI back to Loginscreen."); + _gui->SetSceneState(SCENESTATE_LOGINSCREEN); + } } // 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; diff --git a/src/Client/PseuWoW.h b/src/Client/PseuWoW.h index 73e4cbb..90efc06 100644 --- a/src/Client/PseuWoW.h +++ b/src/Client/PseuWoW.h @@ -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; diff --git a/src/Client/Realm/RealmSession.cpp b/src/Client/Realm/RealmSession.cpp index d5a711a..a8b0c79 100644 --- a/src/Client/Realm/RealmSession.cpp +++ b/src/Client/Realm/RealmSession.cpp @@ -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) diff --git a/src/Client/Realm/RealmSession.h b/src/Client/Realm/RealmSession.h index 52f2159..10639e8 100644 --- a/src/Client/Realm/RealmSession.h +++ b/src/Client/Realm/RealmSession.h @@ -17,8 +17,7 @@ public: void Update(void); PseuInstance *GetInstance(void); void ClearSocket(void); - void SetLogonData(void); - void SetLogonData(std::string, std::string); + void SetLogonData(void); void SendLogonChallenge(void); bool MustDie(void); void SetMustDie(void); diff --git a/src/Client/World/WorldSession.cpp b/src/Client/World/WorldSession.cpp index d61f1d7..74a6dcd 100644 --- a/src/Client/World/WorldSession.cpp +++ b/src/Client/World/WorldSession.cpp @@ -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()) { @@ -337,6 +345,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) diff --git a/src/Client/World/WorldSession.h b/src/Client/World/WorldSession.h index e5636ec..0878e81 100644 --- a/src/Client/World/WorldSession.h +++ b/src/Client/World/WorldSession.h @@ -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 pktQueue; + ZThread::LockedQueue pktQueue, sendPktQueue; DelayedPacketQueue delayedPktQueue; bool _logged,_mustdie; // world status SocketHandler _sh; // handles the WorldSocket diff --git a/src/PseuWoW.vcproj b/src/PseuWoW.vcproj index 5dd6018..4ad53ea 100644 --- a/src/PseuWoW.vcproj +++ b/src/PseuWoW.vcproj @@ -465,9 +465,15 @@ + + + +