Changeset d05c484 in network-game for server/server.cpp


Ignore:
Timestamp:
Jan 19, 2014, 7:40:55 PM (11 years ago)
Author:
dportnoy <dmp1488@…>
Branches:
master
Children:
e5697b1
Parents:
6054f1e
Message:

Some game-specific functions moved from server.cpp to the Game class and a function moved to the MessageProcessor class

File:
1 edited

Legend:

Unmodified
Added
Removed
  • server/server.cpp

    r6054f1e rd05c484  
    4646void processMessage(const NETWORK_MSG& clientMsg, struct sockaddr_in& from, MessageProcessor& msgProcessor, map<unsigned int, Player*>& mapPlayers, map<string, Game*>& mapGames, unsigned int& unusedPlayerId);
    4747
    48 bool handleGameEvents(Game* game, map<unsigned int, Player*>& mapPlayers, MessageProcessor& msgPocessor);
    49 bool handlePlayerEvents(Player* p, Game* game, MessageProcessor& msgProcessor);
    50 
    51 void broadcastMessage(MessageProcessor &msgProcessor, NETWORK_MSG &serverMsg, map<unsigned int, Player*>& players);
    5248void updateUnusedPlayerId(unsigned int& id, map<unsigned int, Player*>& mapPlayers);
    5349Player *findPlayerByName(map<unsigned int, Player*> &m, string name);
    5450Player *findPlayerByAddr(map<unsigned int, Player*> &m, const sockaddr_in &addr);
    55 
    56 void addObjectToMap(WorldMap::ObjectType objectType, int x, int y, WorldMap* gameMap, map<unsigned int, Player*>& mapPlayers, MessageProcessor &msgProcessor);
    5751
    5852void quit(int sig);
     
    7064   map<unsigned int, Projectile> mapProjectiles;
    7165   map<string, Game*> mapGames;
    72    unsigned int unusedPlayerId = 1, unusedProjectileId = 1;
     66   unsigned int unusedPlayerId = 1;
    7367   ofstream outputLog;
    7468
     
    106100
    107101   timespec ts;
    108    int timeLastUpdated = 0, curTime = 0, timeLastBroadcast = 0;
     102   int timeLastUpdated = 0, curTime = 0;
    109103   while (!done)
    110104   {
     
    169163                  p->serialize(serverMsg.buffer);
    170164
    171                   broadcastMessage(msgProcessor, serverMsg, p->currentGame->getPlayers());
     165                  msgProcessor.broadcastMessage(serverMsg, p->currentGame->getPlayers());
    172166               }
    173167
     
    181175                  serverMsg.type = MSG_TYPE_PLAYER;
    182176                  p->serialize(serverMsg.buffer);
    183                   broadcastMessage(msgProcessor, serverMsg, playersInGame);
     177                  msgProcessor.broadcastMessage(serverMsg, playersInGame);
    184178               }
    185179            }
     
    193187
    194188         for (itGames = mapGames.begin(); itGames != mapGames.end();) {
    195             if (handleGameEvents(itGames->second, mapPlayers, msgProcessor)) {
     189            game = itGames->second;
     190            if (game->handleGameEvents()) {
     191               // send a GAME_INFO message with 0 players to force clients to delete the game
     192               int numPlayers = 0;
     193               serverMsg.type = MSG_TYPE_GAME_INFO;
     194               memcpy(serverMsg.buffer, &numPlayers, 4);
     195               strcpy(serverMsg.buffer+4, game->getName().c_str());
     196               msgProcessor.broadcastMessage(serverMsg, mapPlayers);
     197
    196198               delete itGames->second;
    197199               mapGames.erase(itGames++);
     
    218220                  memcpy(serverMsg.buffer, &itProj->second.id, 4);
    219221                  game->removeProjectile(itProj->second.id);
    220                   broadcastMessage(msgProcessor, serverMsg, game->getPlayers());
     222                  msgProcessor.broadcastMessage(serverMsg, game->getPlayers());
    221223
    222224                  Player* target = game->getPlayers()[itProj->second.target];
    223                   target->takeDamage(itProj->second.damage);
    224 
    225                   if (target->isDead)
    226                   {
    227                      WorldMap::ObjectType flagType = WorldMap::OBJECT_NONE;
    228                      if (target->hasBlueFlag)
    229                         flagType = WorldMap::OBJECT_BLUE_FLAG;
    230                      else if (target->hasRedFlag)
    231                         flagType = WorldMap::OBJECT_RED_FLAG;
    232 
    233                      if (flagType != WorldMap::OBJECT_NONE)
    234                         addObjectToMap(flagType, target->pos.x, target->pos.y, game->getMap(), game->getPlayers(), msgProcessor);
    235                   }
    236 
    237                   // send a PLAYER message after dealing damage
    238                   serverMsg.type = MSG_TYPE_PLAYER;
    239                   target->serialize(serverMsg.buffer);
    240                   broadcastMessage(msgProcessor, serverMsg, game->getPlayers());
     225                  game->dealDamageToPlayer(target, itProj->second.damage);
    241226               }
    242227            }
     
    387372            serverMsg.type = MSG_TYPE_PLAYER;
    388373            p->serialize(serverMsg.buffer);
    389             broadcastMessage(msgProcessor, serverMsg, mapPlayers);
     374            msgProcessor.broadcastMessage(serverMsg, mapPlayers);
    390375
    391376            mapPlayers[unusedPlayerId] = p;
     
    421406            memcpy(serverMsg.buffer, &p->id, 4);
    422407
    423             broadcastMessage(msgProcessor, serverMsg, mapPlayers);
     408            msgProcessor.broadcastMessage(serverMsg, mapPlayers);
    424409
    425410            if (p->id < unusedPlayerId)
     
    456441
    457442            strcpy(serverMsg.buffer, oss.str().c_str());
    458             broadcastMessage(msgProcessor, serverMsg, mapPlayers);
     443            msgProcessor.broadcastMessage(serverMsg, mapPlayers);
    459444         }     
    460445
     
    488473               memcpy(serverMsg.buffer+8, &p->target.y, 4);
    489474
    490                broadcastMessage(msgProcessor, serverMsg, mapPlayers);
     475               msgProcessor.broadcastMessage(serverMsg, mapPlayers);
    491476
    492477               validMessage = true;
     
    521506            serverMsg.type = MSG_TYPE_REMOVE_OBJECT;
    522507            memcpy(serverMsg.buffer, &objectId, 4);
    523             broadcastMessage(msgProcessor, serverMsg, players);
     508            msgProcessor.broadcastMessage(serverMsg, players);
    524509
    525510            serverMsg.type = MSG_TYPE_PLAYER;
    526511            p->serialize(serverMsg.buffer);
    527             broadcastMessage(msgProcessor, serverMsg, players);
     512            msgProcessor.broadcastMessage(serverMsg, players);
    528513         }
    529514
     
    550535         map<unsigned int, Player*> players = p->currentGame->getPlayers();
    551536
    552          addObjectToMap(flagType, p->pos.x, p->pos.y, p->currentGame->getMap(), players, msgProcessor);
     537         p->currentGame->addObjectToMap(flagType, p->pos.x, p->pos.y);
    553538
    554539         p->hasBlueFlag = false;
     
    557542         serverMsg.type = MSG_TYPE_PLAYER;
    558543         p->serialize(serverMsg.buffer);
    559          broadcastMessage(msgProcessor, serverMsg, players);
     544         msgProcessor.broadcastMessage(serverMsg, players);
    560545
    561546         break;
     
    581566         memcpy(serverMsg.buffer, &id, 4);
    582567         memcpy(serverMsg.buffer+4, &targetId, 4);
    583          broadcastMessage(msgProcessor, serverMsg, players);
     568         msgProcessor.broadcastMessage(serverMsg, players);
    584569
    585570         break;
     
    597582            serverMsg.type = MSG_TYPE_JOIN_GAME_FAILURE;
    598583         }else {
    599             Game* g = new Game(gameName, "../data/map.txt");
     584            Game* g = new Game(gameName, "../data/map.txt", &msgProcessor);
    600585            mapGames[gameName] = g;
    601586
     
    611596                        m->addObject(WorldMap::OBJECT_RED_FLAG, x*25+12, y*25+12);
    612597                        break;
     598                     case WorldMap::STRUCTURE_NONE:
     599                        break;
    613600                  }
    614601               }
     
    674661                  flagType = WorldMap::OBJECT_RED_FLAG;
    675662
    676                if (flagType != WorldMap::OBJECT_NONE) {
    677                   addObjectToMap(flagType, p->pos.x, p->pos.y, g->getMap(), g->getPlayers(), msgProcessor);
    678                }
     663               if (flagType != WorldMap::OBJECT_NONE)
     664                  g->addObjectToMap(flagType, p->pos.x, p->pos.y);
    679665            }
    680666
     
    685671            memcpy(serverMsg.buffer, &p->id, 4);
    686672            strcpy(serverMsg.buffer+4, g->getName().c_str());
    687             broadcastMessage(msgProcessor, serverMsg, g->getPlayers());
     673            msgProcessor.broadcastMessage(serverMsg, g->getPlayers());
    688674
    689675            int numPlayers = g->getNumPlayers();
     
    692678            memcpy(serverMsg.buffer, &numPlayers, 4);
    693679            strcpy(serverMsg.buffer+4, g->getName().c_str());
    694             broadcastMessage(msgProcessor, serverMsg, mapPlayers);
     680            msgProcessor.broadcastMessage(serverMsg, mapPlayers);
    695681
    696682            // if there are no more players in the game, remove it
     
    751737         p->serialize(serverMsg.buffer);
    752738         cout << "Should be broadcasting the message" << endl;
    753          broadcastMessage(msgProcessor, serverMsg, g->getPlayers());
     739         msgProcessor.broadcastMessage(serverMsg, g->getPlayers());
    754740
    755741         g->addPlayer(p);
     
    777763         memcpy(serverMsg.buffer, &numPlayers, 4);
    778764         strcpy(serverMsg.buffer+4, gameName.c_str());
    779          broadcastMessage(msgProcessor, serverMsg, mapPlayers);
     765         msgProcessor.broadcastMessage(serverMsg, mapPlayers);
    780766
    781767         break;
     
    791777         break;
    792778      }
    793    }
    794 }
    795 
    796 bool handleGameEvents(Game* game, map<unsigned int, Player*>& mapPlayers, MessageProcessor& msgProcessor) {
    797    NETWORK_MSG serverMsg;
    798    map<unsigned int, Player*>::iterator it;
    799    bool gameFinished = false;
    800 
    801    for (it = game->getPlayers().begin(); it != game->getPlayers().end(); it++)
    802    {
    803       gameFinished = gameFinished ||
    804          handlePlayerEvents(it->second, game, msgProcessor);
    805    }
    806 
    807    // set each player's current game to null
    808    if (gameFinished) {
    809       // send a GAME_INFO message with 0 players to force clients to delete the game
    810       int numPlayers = 0;
    811       serverMsg.type = MSG_TYPE_GAME_INFO;
    812       memcpy(serverMsg.buffer, &numPlayers, 4);
    813       strcpy(serverMsg.buffer+4, game->getName().c_str());
    814       broadcastMessage(msgProcessor, serverMsg, mapPlayers);
    815 
    816       for (it = game->getPlayers().begin(); it != game->getPlayers().end(); it++)
    817       {
    818          it->second->currentGame = NULL;
    819       }
    820    }
    821 
    822    return gameFinished;
    823 }
    824 
    825 bool handlePlayerEvents(Player* p, Game* game, MessageProcessor& msgProcessor) {
    826    NETWORK_MSG serverMsg;
    827    WorldMap* gameMap = game->getMap();
    828    map<unsigned int, Player*>& playersInGame = game->getPlayers();
    829    bool gameFinished = false;
    830    FLOAT_POSITION oldPos;
    831 
    832    cout << "moving player" << endl;
    833    bool broadcastMove = false;
    834 
    835    // move player and perform associated tasks
    836    oldPos = p->pos;
    837    if (p->move(gameMap)) {
    838 
    839       cout << "player moved" << endl;
    840       if (game->processPlayerMovement(p, oldPos))
    841          broadcastMove = true;
    842       cout << "player move processed" << endl;
    843 
    844       WorldMap::ObjectType flagType;
    845       POSITION pos;
    846       bool flagTurnedIn = false;
    847       bool flagReturned = false;
    848       bool ownFlagAtBase = false;
    849 
    850       // need to figure out how to move this to a different file
    851       // while still sending back flag type and position
    852       switch(gameMap->getStructure(p->pos.x/25, p->pos.y/25))
    853       {
    854          case WorldMap::STRUCTURE_BLUE_FLAG:
    855          {
    856             if (p->team == 0 && p->hasRedFlag)
    857             {
    858                // check that your flag is at your base
    859                pos = gameMap->getStructureLocation(WorldMap::STRUCTURE_BLUE_FLAG);
    860                            
    861                vector<WorldMap::Object>* vctObjects = gameMap->getObjects();
    862                vector<WorldMap::Object>::iterator itObjects;
    863 
    864                for (itObjects = vctObjects->begin(); itObjects != vctObjects->end(); itObjects++)
    865                {
    866                   if (itObjects->type == WorldMap::OBJECT_BLUE_FLAG)
    867                   {
    868                      if (itObjects->pos.x == pos.x*25+12 && itObjects->pos.y == pos.y*25+12)
    869                      {
    870                         ownFlagAtBase = true;
    871                         break;
    872                      }
    873                   }
    874                }
    875 
    876                if (ownFlagAtBase)
    877                {
    878                   p->hasRedFlag = false;
    879                   flagType = WorldMap::OBJECT_RED_FLAG;
    880                   pos = gameMap->getStructureLocation(WorldMap::STRUCTURE_RED_FLAG);
    881                   flagTurnedIn = true;
    882                   game->setBlueScore(game->getBlueScore()+1);
    883                }
    884             }
    885 
    886             break;
    887          }
    888          case WorldMap::STRUCTURE_RED_FLAG:
    889          {
    890             if (p->team == 1 && p->hasBlueFlag)
    891             {
    892                // check that your flag is at your base
    893                pos = gameMap->getStructureLocation(WorldMap::STRUCTURE_RED_FLAG);
    894                        
    895                vector<WorldMap::Object>* vctObjects = gameMap->getObjects();
    896                vector<WorldMap::Object>::iterator itObjects;
    897 
    898                for (itObjects = vctObjects->begin(); itObjects != vctObjects->end(); itObjects++)
    899                {
    900                   if (itObjects->type == WorldMap::OBJECT_RED_FLAG)
    901                   {
    902                      if (itObjects->pos.x == pos.x*25+12 && itObjects->pos.y == pos.y*25+12)
    903                      {
    904                         ownFlagAtBase = true;
    905                         break;
    906                      }
    907                   }
    908                }
    909 
    910                if (ownFlagAtBase)
    911                {
    912                   p->hasBlueFlag = false;
    913                   flagType = WorldMap::OBJECT_BLUE_FLAG;
    914                   pos = gameMap->getStructureLocation(WorldMap::STRUCTURE_BLUE_FLAG);
    915                   flagTurnedIn = true;
    916                   game->setRedScore(game->getRedScore()+1);
    917                }
    918             }
    919 
    920             break;
    921          }
    922       }
    923 
    924       if (flagTurnedIn)
    925       {
    926          unsigned int blueScore = game->getBlueScore();
    927          unsigned int redScore = game->getRedScore();
    928 
    929          // send an OBJECT message to add the flag back to its spawn point
    930          pos.x = pos.x*25+12;
    931          pos.y = pos.y*25+12;
    932          gameMap->addObject(flagType, pos.x, pos.y);
    933 
    934          serverMsg.type = MSG_TYPE_OBJECT;
    935          gameMap->getObjects()->back().serialize(serverMsg.buffer);
    936          broadcastMessage(msgProcessor, serverMsg, playersInGame);
    937 
    938          serverMsg.type = MSG_TYPE_SCORE;
    939          memcpy(serverMsg.buffer, &blueScore, 4);
    940          memcpy(serverMsg.buffer+4, &redScore, 4);
    941          broadcastMessage(msgProcessor, serverMsg, playersInGame);
    942 
    943          // check to see if the game should end
    944          // move to its own method
    945          if (game->getBlueScore() == 3 || game->getRedScore() == 3) {
    946             gameFinished = true;
    947 
    948             unsigned int winningTeam;
    949             if (game->getBlueScore() == 3)
    950                winningTeam = 0;
    951             else if (game->getRedScore() == 3)
    952                winningTeam = 1;
    953 
    954             serverMsg.type = MSG_TYPE_FINISH_GAME;
    955 
    956             // I should create an instance of the GameSummary object here and just serialize it into this message
    957             memcpy(serverMsg.buffer, &winningTeam, 4);
    958             memcpy(serverMsg.buffer+4, &blueScore, 4);
    959             memcpy(serverMsg.buffer+8, &redScore, 4);
    960             strcpy(serverMsg.buffer+12, game->getName().c_str());
    961             broadcastMessage(msgProcessor, serverMsg, playersInGame);
    962          }
    963 
    964          // this means a PLAYER message will be sent
    965          broadcastMove = true;
    966       }
    967 
    968       // go through all objects and check if the player is close to one and if its their flag
    969       vector<WorldMap::Object>* vctObjects = gameMap->getObjects();
    970       vector<WorldMap::Object>::iterator itObjects;
    971       POSITION structPos;
    972 
    973       for (itObjects = vctObjects->begin(); itObjects != vctObjects->end(); itObjects++)
    974       {
    975          POSITION pos = itObjects->pos;
    976 
    977          if (posDistance(p->pos, pos.toFloat()) < 10)
    978          {
    979             if (p->team == 0 &&
    980                 itObjects->type == WorldMap::OBJECT_BLUE_FLAG)
    981             {
    982                structPos = gameMap->getStructureLocation(WorldMap::STRUCTURE_BLUE_FLAG);
    983                flagReturned = true;
    984                break;
    985             }
    986             else if (p->team == 1 &&
    987                      itObjects->type == WorldMap::OBJECT_RED_FLAG)
    988             {
    989                structPos = gameMap->getStructureLocation(WorldMap::STRUCTURE_RED_FLAG);
    990                flagReturned = true;
    991                break;
    992             }
    993          }
    994       }
    995 
    996       if (flagReturned)
    997       {
    998          itObjects->pos.x = structPos.x*25+12;
    999          itObjects->pos.y = structPos.y*25+12;
    1000 
    1001          serverMsg.type = MSG_TYPE_OBJECT;
    1002          itObjects->serialize(serverMsg.buffer);
    1003          broadcastMessage(msgProcessor, serverMsg, playersInGame);
    1004       }
    1005 
    1006       if (broadcastMove)
    1007       {
    1008          serverMsg.type = MSG_TYPE_PLAYER;
    1009          p->serialize(serverMsg.buffer);
    1010          broadcastMessage(msgProcessor, serverMsg, playersInGame);
    1011       }
    1012    }
    1013 
    1014    cout << "processing player attack" << endl;
    1015 
    1016    // check if the player's attack animation is complete
    1017    if (p->isAttacking && p->timeAttackStarted+p->attackCooldown <= getCurrentMillis())
    1018    {
    1019       p->isAttacking = false;
    1020       cout << "Attack animation is complete" << endl;
    1021 
    1022       //send everyone an ATTACK message
    1023       cout << "about to broadcast attack" << endl;
    1024 
    1025       if (p->attackType == Player::ATTACK_MELEE)
    1026       {
    1027          cout << "Melee attack" << endl;
    1028 
    1029          Player* target = playersInGame[p->targetPlayer];
    1030          target->takeDamage(p->damage);
    1031 
    1032          if (target->isDead)
    1033          {
    1034             WorldMap::ObjectType flagType = WorldMap::OBJECT_NONE;
    1035             if (target->hasBlueFlag)
    1036                flagType = WorldMap::OBJECT_BLUE_FLAG;
    1037             else if (target->hasRedFlag)
    1038                flagType = WorldMap::OBJECT_RED_FLAG;
    1039 
    1040             if (flagType != WorldMap::OBJECT_NONE) {
    1041                addObjectToMap(flagType, target->pos.x, target->pos.y, gameMap, playersInGame, msgProcessor);
    1042             }
    1043          }
    1044 
    1045          serverMsg.type = MSG_TYPE_PLAYER;
    1046          target->serialize(serverMsg.buffer);
    1047       }
    1048       else if (p->attackType == Player::ATTACK_RANGED)
    1049       {
    1050          cout << "Ranged attack" << endl;
    1051 
    1052          Projectile proj(p->pos.x, p->pos.y, p->targetPlayer, p->damage);
    1053          game->assignProjectileId(&proj);
    1054          game->addProjectile(proj);
    1055 
    1056          int x = p->pos.x;
    1057          int y = p->pos.y;
    1058 
    1059          serverMsg.type = MSG_TYPE_PROJECTILE;
    1060          memcpy(serverMsg.buffer, &proj.id, 4);
    1061          memcpy(serverMsg.buffer+4, &x, 4);
    1062          memcpy(serverMsg.buffer+8, &y, 4);
    1063          memcpy(serverMsg.buffer+12, &p->targetPlayer, 4);
    1064       }
    1065       else
    1066          cout << "Invalid attack type: " << p->attackType << endl;
    1067 
    1068       broadcastMessage(msgProcessor, serverMsg, playersInGame);
    1069    }
    1070 
    1071    return gameFinished;
    1072 }
    1073 
    1074 void broadcastMessage(MessageProcessor &msgProcessor, NETWORK_MSG &serverMsg, map<unsigned int, Player*>& players) {
    1075    map<unsigned int, Player*>::iterator it;
    1076    for (it = players.begin(); it != players.end(); it++) {
    1077       msgProcessor.sendMessage(&serverMsg, &(it->second->addr));
    1078779   }
    1079780}
     
    1112813}
    1113814
    1114 void addObjectToMap(WorldMap::ObjectType objectType, int x, int y, WorldMap* gameMap, map<unsigned int, Player*>& mapPlayers, MessageProcessor &msgProcessor) {
    1115    NETWORK_MSG serverMsg;
    1116 
    1117    gameMap->addObject(objectType, x, y);
    1118 
    1119    serverMsg.type = MSG_TYPE_OBJECT;
    1120    gameMap->getObjects()->back().serialize(serverMsg.buffer);
    1121 
    1122    broadcastMessage(msgProcessor, serverMsg, mapPlayers);
    1123 }
    1124 
    1125815void quit(int sig) {
    1126816   done = true;
Note: See TracChangeset for help on using the changeset viewer.