lobbyMgr.cpp

Go to the documentation of this file.
00001 /*
00002  * lobbyMgr.cpp
00003  *
00004  */
00005 #include <GraphicsInteractionManager.h>
00006 #include <lobbyMgr.h>
00007 
00008 #include "SoundMgr.h"
00009 
00010 OgreGFX::LobbyMgr::LobbyMgr(FastEcslent::Engine *eng, GraphicsInteractionManager *gim, OIS::Mouse *m, OIS::Keyboard *k)
00011                                                         : GFXMgr(gim), engine(eng), mouse(m), keyboard(k){
00012         mouse->setEventCallback(this);
00013         keyboard->setEventCallback(this);
00014 
00015         startTime = getCurrentTime();
00016         state = GAMEMENU;
00017 
00018         init();
00019 }
00020 
00021 bool OgreGFX::LobbyMgr::frameStarted(const Ogre::FrameEvent& evt){
00022     keyboard->capture();
00023     mouse->capture();
00024 
00025         //This is set by remote server, lauch by the same thread
00026     if(engine->gameState == FastEcslent::GAME){
00027         loadGame();
00028     }
00029 
00030         return true;
00031 }
00032 
00033 bool OgreGFX::LobbyMgr::frameRenderingQueued(const Ogre::FrameEvent& evt){
00034         this->refreshServerAndSlots();
00035     return true;
00036 }
00037 
00038 bool OgreGFX::LobbyMgr::frameEnded(const Ogre::FrameEvent& evt){
00039         return true;
00040 }
00041 
00045 bool OgreGFX::LobbyMgr::keyPressed( const OIS::KeyEvent &arg ){
00046         return true;
00047 }
00048 bool OgreGFX::LobbyMgr::keyReleased( const OIS::KeyEvent &arg ){
00049     return true;
00050 }
00051 bool OgreGFX::LobbyMgr::mouseMoved( const OIS::MouseEvent &arg ){
00052         mTrayMgr->injectMouseMove(arg);
00053     return true;
00054 }
00055 bool OgreGFX::LobbyMgr::mousePressed( const OIS::MouseEvent &arg, OIS::MouseButtonID id ){
00056         mTrayMgr->injectMouseDown(arg,id);
00057         return true;
00058 }
00059 bool OgreGFX::LobbyMgr::mouseReleased( const OIS::MouseEvent &arg, OIS::MouseButtonID id ){
00060         mTrayMgr->injectMouseUp(arg,id);
00061     return true;
00062 }
00063 
00064 void OgreGFX::LobbyMgr::init(){
00065         exitQuestion = "Are you sure you want to exit?";
00066         engine->gameState = FastEcslent::LOBBY;
00067         LOBBY_TOLERANCE = 4000; //4 seconds
00068 
00069         initGUIGameMenu();
00070         loadOptions();
00071 
00072         netLobby = new FastEcslent::NetLobby(engine);
00073         netLobby->run();
00074 
00075         mTrayMgr->showBackdrop("FESdkTrays/FEShade");
00076         mTrayMgr->showAll();
00077 }
00078 
00079 void OgreGFX::LobbyMgr::initialize(){
00080 
00081 }
00082 
00083 void OgreGFX::LobbyMgr::buttonHit(OgreBites::Button* button){
00084         if (button == lobbyStartBt){   //start game button clicked
00085                 this->startGame(netLobby->myIPAddress, engine->options.networkPort);
00086         }else if(button == createBt){   //create a lobby button clicked
00087                 this->clearPlayerLabel();
00088 
00089                 this->mTrayMgr->getTrayContainer(OgreBites::TL_CENTER)->hide();
00090                 this->mTrayMgr->getTrayContainer(OgreBites::TL_RIGHT)->hide();
00091                 this->mTrayMgr->getTrayContainer(OgreBites::TL_NONE)->show();
00092 
00093                 std::string lobbyMsg = this->getLobbyString("Lobby", netLobby->myIPAddress,  engine->options.networkPort);
00094                 lobbyLb->setCaption(lobbyMsg);
00095 
00096                 this->addNode("ServerName", netLobby->myIPAddress, engine->options.networkPort, FastEcslent::RED, 0, 0, true);
00097 
00098                 this->switchState();
00099         }else if(button == joinBt){    //join a lobby button clicked
00100                 //nothing in the server list.
00101                 if(remoteServerMenu->getNumItems() <= 0){
00102                         return;
00103                 }
00104                 this->joinGame();
00105                 this->switchState();
00106         }else if(button == lobbyExitBt){  //exit lobby button clicked
00107                 this->handleExitButton();
00108         }else if(button == exitBt){     //Exit system
00109                 mTrayMgr->showYesNoDialog("Exit", exitQuestion);
00110         }
00111 }
00112 
00113 void OgreGFX::LobbyMgr::itemSelected(OgreBites::SelectMenu* menu){
00114         std::string menuCaption = menu->getCaption().substr(0,4);
00115         if(menuCaption == "Side" && menu->getSelectedItem().length() > 0){
00116                 int index = menu->getSelectionIndex();
00117                 std::string number = menu->getName().substr(4,1);
00118                 int slot = atoi(number.c_str());
00119                 nodeMap[slots[slot]]->side = index == 0?FastEcslent::RED:FastEcslent::BLUE;
00120                 int slotNew = this->getEmptySlot((int)(nodeMap[slots[slot]]->side));
00121                 if(slotNew != -1 && engine->options.isServer){
00122                         this->slotSwap(slot, slotNew);
00123                 }else{
00124                         std::pair<std::string, int> host = this->getLobbyHost();
00125                         int side = slotNew/2 > 0?FastEcslent::BLUE:FastEcslent::RED;
00126                         int player = slotNew;
00127                         netLobby->lobbySlotSwapReq(host.first, host.second, slotNew, slot, side, player);
00128                 }
00129         }
00130 }
00131 
00132 void OgreGFX::LobbyMgr::labelHit(OgreBites::Label* label){
00133 }
00134 
00135 void OgreGFX::LobbyMgr::sliderMoved(OgreBites::Slider* slider){
00136 }
00137 
00138 void OgreGFX::LobbyMgr::checkBoxToggled(OgreBites::CheckBox* box){
00139         if(box == serverCB){
00140                 if(box->isChecked()){
00141                         engine->options.isServer = true;
00142                         remoteServerMenu->clearItems();
00143                         this->mTrayMgr->getTrayContainer(OgreBites::TL_RIGHT)->hide();
00144                         this->createBt->show();
00145                 }else{
00146                         engine->options.isServer = false;
00147                         remoteServerMenu->clearItems();
00148                         this->mTrayMgr->getTrayContainer(OgreBites::TL_RIGHT)->show();
00149                         this->createBt->hide();
00150                 }
00151         }else if(box == soundCB){
00152                 if(box->isChecked()){
00153                     engine->gfx->gimPtr->soundMgr->enable();
00154                 }else{
00155                     engine->gfx->gimPtr->soundMgr->disable();
00156                 }
00157         }
00158 }
00159 void OgreGFX::LobbyMgr::okDialogClosed(const Ogre::DisplayString& message) {
00160 }
00161 void OgreGFX::LobbyMgr::yesNoDialogClosed(const Ogre::DisplayString& question, bool yesHit){
00162         if(question == exitQuestion && yesHit){
00163                 exit(0);
00164         }
00165 }
00166 
00167 void OgreGFX::LobbyMgr::loadGame(){
00168         this->configureGame();
00169         mTrayMgr->hideAll();
00170 
00171         gfx->mRoot->removeFrameListener(this);
00172 
00173         //launch clients
00174         if(engine->options.isServer) {
00175                 netLobby->lobbyStart();
00176         }
00177 
00178         //gfx thread start to render its own frame
00179         gfx->loadGameGFX();
00180 
00181         netLobby->quit = true;
00182 }
00183 
00184 void OgreGFX::LobbyMgr::joinGame(){
00185         this->lobbyStartBt->hide();
00186 
00187         std::string ip = remoteServerMenu->getSelectedItem();
00188         int port = remoteServerMap[ip]->port;
00189         netLobby->lobbyJoinGame(ip, port);
00190 }
00191 
00192 void OgreGFX::LobbyMgr::initGUIGameMenu(){
00193         mTrayMgr = new OgreBites::SdkTrayManager("Game Menu", gfx->mWindow, mouse, this);
00194         Ogre::FontManager::getSingleton().getByName("SdkTrays/Caption")->load();
00195 
00196         //Lobby, None Tray
00197         this->initGUILobby();
00198         //Calculate the positions of all the components in None Tray.
00199         this->setNoneTrayPosition();
00200 
00201         //Center Tray
00202         logo = mTrayMgr->createDecorWidget(OgreBites::TL_CENTER, "DebugRTTPanel", "FESdkTrays/FELogo");
00203         separatorCenter = mTrayMgr->createSeparator(OgreBites::TL_CENTER, "SeparatorCenter", GameNemuWidth);
00204         soundCB = mTrayMgr->createCheckBox(OgreBites::TL_CENTER, "SoundCB", "Sound", GameNemuWidth);
00205         serverCB = mTrayMgr->createCheckBox(OgreBites::TL_CENTER, "ServerCB", "Server", GameNemuWidth);
00206         createBt = mTrayMgr->createButton(OgreBites::TL_CENTER, "CreateButton", "Create", GameNemuWidth);
00207         exitBt = mTrayMgr->createButton(OgreBites::TL_CENTER, "ExitButton", "Exit",GameNemuWidth);
00208 
00209         //remote server menu, Right Tray
00210         remoteServerMenu = mTrayMgr->createThickSelectMenu(OgreBites::TL_RIGHT, "LobbyServer", "SERVER",GameNemuWidth,10);
00211         joinBt = mTrayMgr->createButton(OgreBites::TL_RIGHT, "JoinButton", "Join");
00212 
00213         //Hide None tray, none tray contains player slots
00214         this->mTrayMgr->getTrayContainer(OgreBites::TL_NONE)->hide();
00215         
00216         //default value for sound is "enabled"
00217         soundCB->setChecked(true);
00218 }
00219 
00220 void OgreGFX::LobbyMgr::initGUILobby(){
00221         lobbyLb = mTrayMgr->createLabel(OgreBites::TL_NONE, "LobbyName", "LobbyName", LobbyTitleWidth);
00222         separatorTop = mTrayMgr->createSeparator(OgreBites::TL_NONE, "SeparatorTop", LobbySepWidth);
00223 
00224         for(int i=0; i< FastEcslent::MaxPlayers; i++){
00225                 std::string player = "Player";
00226                 std::string side = "Side";
00227                 playerLb[i] = mTrayMgr->createLabel(OgreBites::TL_NONE, player.append(int_to_string(i)), "", LobbyPlayerWidth);
00228                 playerSide[i] = mTrayMgr->createLongSelectMenu(OgreBites::TL_NONE, side.append(int_to_string(i)), "Side :", LobbyPlayerSideWidth,10 );
00229                 playerSide[i]->addItem("RED");
00230                 playerSide[i]->addItem("BLUE");
00231         }
00232 
00233         lobbyStartBt = mTrayMgr->createButton(OgreBites::TL_NONE, "LobbyStartButton", "Start Game", LobbyBtnWidth);
00234         lobbyExitBt = mTrayMgr->createButton(OgreBites::TL_NONE, "LobbyExitButton", "Exit Lobby", LobbyBtnWidth);
00235 }
00236 
00237 void OgreGFX::LobbyMgr::setNoneTrayPosition(){
00238         int height = gfx->mWindow->getHeight();
00239         int width = gfx->mWindow->getWidth();
00240 
00241         int gapVinit = (height - LobbyGapV * 10)/2;
00242         lobbyLb->getOverlayElement()->setPosition((width - LobbyTitleWidth)/2, gapVinit+LobbyGapV);
00243         separatorTop->getOverlayElement()->setPosition((width - LobbySepWidth)/2, gapVinit+LobbyGapV*2);
00244 
00245         for(int i=0; i< FastEcslent::MaxPlayers; i++){
00246                 int left = (width - LobbyPlayerWidth - LobbyPlayerSideWidth*2 - LobbyGapH)/2;
00247                 int top = (i <= 1)?(gapVinit+LobbyGapV*2+LobbyGapV*(i+1)):(gapVinit+LobbyGapV*3+LobbyGapV*(i+1));
00248                 playerLb[i]->getOverlayElement()->setPosition(left, top);
00249                 playerSide[i]->getOverlayElement()->setPosition(left+LobbyPlayerWidth+ LobbyGapH, top);
00250         }
00251 
00252         lobbyStartBt->getOverlayElement()->setPosition((width- LobbyBtnWidth*2 - LobbyGapH)/2, gapVinit+LobbyGapV*9);
00253         lobbyExitBt->getOverlayElement()->setPosition((width + LobbyGapH)/2 , gapVinit+LobbyGapV*9);
00254 }
00255 
00256 void OgreGFX::LobbyMgr::loadOptions(){
00257         if(engine->options.isServer){
00258                 serverCB->setChecked(true);
00259                 this->mTrayMgr->getTrayContainer(OgreBites::TL_RIGHT)->hide();
00260         }else{
00261                 serverCB->setChecked(false);
00262                 this->mTrayMgr->getTrayContainer(OgreBites::TL_RIGHT)->show();
00263         }
00264 }
00265 
00266 void OgreGFX::LobbyMgr::addRemoteServer(const std::string &gName, const std::string &ip, int port){
00267         LobbyNode *ln = new LobbyNode();
00268         ln->name = gName;
00269         ln->ip = ip;
00270         ln->port = port;
00271 
00272         ln->time = (getCurrentTime() - startTime).total_milliseconds();
00273         remoteServerMap[ip] = ln;
00274 }
00275 
00276 void OgreGFX::LobbyMgr::addNode(const std::string &gName, const std::string &clientip, int port, int side, int player, int slot, bool isHost){
00277         //already in position
00278         if(nodeMap.find(clientip)!=nodeMap.end() ){
00279                 if(nodeMap[clientip]->slot == slot){
00280                         return;
00281                 }else{
00282                         this->removeNodeFromSlot(clientip);
00283                 }
00284         }
00285 
00286         LobbyNode *lci = new LobbyNode();
00287         lci->name = gName;
00288         lci->ip = clientip;
00289         lci->port = port;
00290         lci->side = (FastEcslent::Side)side;
00291         lci->player =  (FastEcslent::Player)player;
00292         lci->isHost = isHost;
00293         lci->slot = slot;
00294 
00295         lci->time = (getCurrentTime() - startTime).total_milliseconds();
00296         nodeMap[clientip] = lci;
00297         slots[slot] = clientip;
00298 }
00299 
00300 void OgreGFX::LobbyMgr::removeNodeFromSlot(const std::string &clientip){
00301         LobbyNode *l = nodeMap[clientip];
00302         int slot = l->slot;
00303         nodeMap.erase(clientip);
00304         delete l;
00305         slots[slot] = "";
00306 }
00307 
00308 void OgreGFX::LobbyMgr::handleJoinRequest(const std::string &clientName, const std::string &clientip, int port){
00309         LobbyNode *lci = new LobbyNode();
00310         lci->name = clientName;
00311         lci->ip = clientip;
00312         lci->port = port;
00313         lci->time = (getCurrentTime() - startTime).total_milliseconds();
00314 
00315         nodeMap[clientip] = lci;
00316 
00317         int slot = this->getEmptySlot();
00318         if(slot != -1){
00319                 //assign a new side and player
00320                 lci->side = (slot < FastEcslent::MaxPlayers/2)? (FastEcslent::RED):(FastEcslent::BLUE);
00321                 lci->player = (FastEcslent::Player)slot;
00322                 lci->slot = slot;
00323                 slots[slot] = lci->ip;
00324                 netLobby->sendLobbyClientResponse(clientip, port, lci->side, lci->player );
00325         }
00326 }
00327 
00328 void OgreGFX::LobbyMgr::lobbyEnter(const std::string &serverip, int port, int side, int player){
00329         mTrayMgr->getTrayContainer(OgreBites::TL_CENTER)->hide();
00330         mTrayMgr->getTrayContainer(OgreBites::TL_RIGHT)->hide();
00331         mTrayMgr->getTrayContainer(OgreBites::TL_NONE)->show();
00332         std::string txt = this->getLobbyString(remoteServerMap[serverip]->name, serverip, port);
00333         lobbyLb->setCaption(txt);
00334 
00335         engine->options.side = (FastEcslent::Side)side;
00336         engine->options.player = (FastEcslent::Player)player;
00337 }
00338 
00339 void OgreGFX::LobbyMgr::swapNodeSlot(int newslot, int oldslot, int newside, int newplayer){
00340         this->nodeMap[this->slots[oldslot]]->side = (FastEcslent::Side)newside;
00341         this->nodeMap[this->slots[oldslot]]->player = (FastEcslent::Player)newplayer;
00342         this->slotSwap(newslot, oldslot);
00343 }
00344 
00345 void OgreGFX::LobbyMgr::lobbyExit(const std::string &clientip, int port){
00346         if(engine->options.isServer){
00347                 for(int i=0;i<FastEcslent::MaxPlayers;i++){
00348                         if(slots[i] == clientip){
00349                                 slots[i] = "";
00350                         }
00351                 }
00352 
00353                 LobbyNode *info = nodeMap[clientip];
00354                 nodeMap.erase(clientip);
00355                 delete info;
00356         }else if(state == LOBBY){
00357                 this->handleExitButton();
00358         }
00359 }
00360 
00361 void OgreGFX::LobbyMgr::startGame(const std::string &ip, int port){
00362         std::pair<std::string, int> host = this->getLobbyHost();
00363         if(host.first.size() > 0 && host.first == ip && host.second == port){
00364                 engine->gameState = FastEcslent::GAME;
00365         }
00366 }
00367 
00368 std::pair<std::string, int> OgreGFX::LobbyMgr::getLobbyHost(){
00369         std::string hostip = "";
00370         int port = 0;
00371         for(std::map<std::string, LobbyNode*>::iterator i = nodeMap.begin(); i!= nodeMap.end();i++){
00372                 LobbyNode *info = i->second;
00373                 if (info && info->isHost) {
00374                         hostip = info->ip;
00375                         port = info->port;
00376                         break;
00377                 }
00378         }
00379         return std::pair<std::string, int>(hostip, port);
00380 }
00381 std::string OgreGFX::LobbyMgr::getLobbyString(const std::string &lobbyName, const std::string &ip, int port){
00382         std::string txt = lobbyName;
00383         txt.append(" - ").append(ip).append(" : ").append(int_to_string(port));
00384         return txt;
00385 }
00386 
00387 void OgreGFX::LobbyMgr::clearServerMap(){
00388         for(std::map<std::string, LobbyNode*>::iterator i = remoteServerMap.begin(); i!= remoteServerMap.end();i++){
00389                 LobbyNode *info = i->second;
00390                 remoteServerMap.erase(i);
00391                 delete info;
00392         }
00393 }
00394 
00395 void OgreGFX::LobbyMgr::clearNodeMap(){
00396         for(int i=0; i< FastEcslent::MaxPlayers;i++){
00397                 slots[i] = "";
00398         }
00399 
00400         for(std::map<std::string, LobbyNode*>::iterator i = nodeMap.begin(); i!= nodeMap.end();i++){
00401                 LobbyNode *info = i->second;
00402                 nodeMap.erase(i);
00403                 delete info;
00404         }
00405 }
00406 
00407 std::string OgreGFX::LobbyMgr::getPlayerString(const std::string &playerName, const std::string &ip){
00408         std::string txt = playerName;
00409         txt.append(" - ").append(ip);
00410         return txt;
00411 }
00412 
00413 void OgreGFX::LobbyMgr::refreshServerAndSlots(){
00414         if(state == GAMEMENU){
00415                 //client needs to update server list
00416                 if(!engine->options.isServer){
00417                         //refresh server map, remove the timeout node
00418                         for(std::map<std::string, LobbyNode*>::iterator i = remoteServerMap.begin(); i!= remoteServerMap.end();i++){
00419                                 LobbyNode *info = i->second;
00420                                 if((getCurrentTime() - startTime).total_milliseconds() - info->time >= LOBBY_TOLERANCE ){
00421                                         remoteServerMap.erase(i);
00422                                         delete info;
00423                                         remoteServerMenu->clearItems();
00424                                         break;
00425                                 }
00426                         }
00427 
00428                         if(remoteServerMenu->getNumItems() != remoteServerMap.size()){
00429                                 for(std::map<std::string, LobbyNode*>::iterator i = remoteServerMap.begin(); i!= remoteServerMap.end();i++){
00430                                         remoteServerMenu->addItem(i->first);
00431                                 }
00432                         }
00433                 }
00434         }else if(state == LOBBY){
00435                 for(int i=0; i<FastEcslent::MaxPlayers; i++){
00436                         if(slots.find(i) != slots.end() && slots[i].length() > 0){
00437                                 if(nodeMap.find(slots[i]) != nodeMap.end()){
00438                                         std::string cap = this->getPlayerString(nodeMap[slots[i]]->name, nodeMap[slots[i]]->ip);
00439                                         playerLb[i]->setCaption(cap);
00440                                         FastEcslent::Side s = nodeMap[slots[i]]->side;
00441                                         playerSide[i]->selectItem(s==FastEcslent::RED?"RED":"BLUE", false);
00442                                         playerSide[i]->show();
00443                                 }
00444                         }else{
00445                                 playerLb[i]->setCaption("");
00446                                 playerSide[i]->hide();
00447                         }
00448                 }
00449         }
00450 }
00451 
00452 int OgreGFX::LobbyMgr::getEmptySlot(){
00453         for(int i=0;i<FastEcslent::MaxPlayers;i++){
00454                 if(slots.find(i) == slots.end() || slots[i].length() == 0){
00455                         return i;
00456                 }
00457         }
00458         return -1;
00459 }
00460 
00461 int OgreGFX::LobbyMgr::getEmptySlot(int side){
00462         for(int i=0; i< FastEcslent::MaxPlayers/2;i++){
00463                 if(!(slots.find((side-1)*FastEcslent::MaxPlayers/2+i) != slots.end() && slots[(side-1)*FastEcslent::MaxPlayers/2+i].length() > 0)){
00464                         return (side-1)*FastEcslent::MaxPlayers/2+i;
00465                 }
00466         }
00467         return -1;
00468 }
00469 
00470 void OgreGFX::LobbyMgr::slotSwap(int slot1,int slot2){
00471         std::string p1 = slots[slot1];
00472         std::string p2 = slots[slot2];
00473         if(nodeMap[p1]){
00474                 nodeMap[p1]->slot = slot2;
00475         }
00476         if(nodeMap[p2]){
00477                 nodeMap[p2]->slot = slot1;
00478         }
00479 
00480         slots[slot2] = p1;
00481         slots[slot1] = p2;
00482 }
00483 
00484 void OgreGFX::LobbyMgr::clearPlayerLabel(){
00485         for(int i=0; i< FastEcslent::MaxPlayers;i++){
00486                 playerLb[i]->setCaption("");
00487         }
00488 }
00489 
00490 void  OgreGFX::LobbyMgr::configureGame(){
00491         int slot = -1;
00492         for(int i=0;i<FastEcslent::MaxPlayers;i++){
00493                 if(slots[i] == this->netLobby->myIPAddress){
00494                         slot = i;
00495                         break;
00496                 }
00497         }
00498 
00499         engine->options.side = ((slot+1) / (FastEcslent::MaxPlayers/2)==0?FastEcslent::RED:FastEcslent::BLUE);
00500         engine->options.player = (FastEcslent::Player)slot;
00501 }
00502 
00503 void OgreGFX::LobbyMgr::switchState(){
00504         if(state == GAMEMENU){
00505                 state = LOBBY;
00506         }else{
00507                 state = GAMEMENU;
00508         }
00509 }
00510 
00511 void OgreGFX::LobbyMgr::handleExitButton(){
00512         this->mTrayMgr->getTrayContainer(OgreBites::TL_NONE)->hide();
00513         this->mTrayMgr->getTrayContainer(OgreBites::TL_CENTER)->show();
00514         if(!engine->options.isServer){
00515                 this->mTrayMgr->getTrayContainer(OgreBites::TL_RIGHT)->show();
00516         }
00517 
00518         this->lobbyStartBt->show();
00519 
00520         //Send exit lobby to server
00521         std::pair<std::string, int> hostNode = this->getLobbyHost();
00522         if(hostNode.first.length() > 0){
00523                 netLobby->lobbyExitGame(hostNode.first, hostNode.second);
00524         }
00525         this->clearServerMap();
00526         this->clearNodeMap();
00527 
00528         this->switchState();
00529 }
00530 
00531 OgreGFX::LobbyMgr::~LobbyMgr(){
00532         delete mTrayMgr;
00533 
00534         mTrayMgr = 0;
00535 
00536         delete netLobby;
00537 }
00538 
00539 
00540 

Generated on Fri Dec 13 14:54:17 2013 for FastECSLent by  doxygen 1.5.4