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

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