int Game::addPlayer(Player* p) { if (players.size() < MAX_PLAYERS) { if (referee == NULL) referee = p; players.push_back(p); sendMapInfo(); return (players.size()); } else return (-1); }
void CGameServerState::dataPacketReceived(Net::CPaquete* packet) { // Obtenemos la id de la conexion por la que hemos recibido // el paquete (para identificar al cliente) Net::NetID playerNetId = packet->getConexion()->getId(); // Construimos un buffer para leer los datos que hemos recibido Net::CBuffer inBuffer( packet->getDataLength() ); inBuffer.write( packet->getData(), packet->getDataLength() ); inBuffer.reset(); // Desplazamos el puntero al principio para realizar la lectura // En primer lugar extraemos el tipo del mensaje que hemos recibido Net::NetMessageType msgType; inBuffer.read( &msgType, sizeof(msgType) ); switch(msgType) { case Net::PLAYER_INFO: { // Deserializamos el nombre del player std::string playerNick; inBuffer.deserialize(playerNick); //comprobamos si hay algún jugador con el mismo nombre en la partida, y si es así, //se lo cambiamos para que no haya problemas en el futuro if(_map->getEntityByName(playerNick)){ std::ostringstream convert; convert << playerNetId; std::string nameId = convert.str(); playerNick += nameId; } // Registramos al player en el gestor de jugadores _playersMgr->addPlayer(playerNetId, playerNick); // Enviamos la informacion de carga de mapa al cliente sendMapInfo(playerNetId); break; } case Net::MAP_LOADED: { Net::CBuffer gameSettingsBuffer; Net::NetMessageType msgType = Net::GAME_SETTINGS; gameSettingsBuffer.write(&msgType, sizeof(msgType)); gameSettingsBuffer.write(&_gameMode, sizeof(_gameMode)); gameSettingsBuffer.write(&_gameTime, sizeof(_gameTime)); gameSettingsBuffer.write(&_goalScore, sizeof(_goalScore)); _netMgr->sendTo( playerNetId, gameSettingsBuffer.getbuffer(), gameSettingsBuffer.getSize() ); break; } case Net::GAME_SETTINGS_LOADED: { // Una vez cargado el mapa, comienza la fase de carga de players. // El player que esta siendo conectado deberá cargar a todos los players que ya estaban online. sendWorldState(playerNetId); break; } case Net::WORLD_STATE_LOADED: { Net::NetMessageType startGameMsg = Net::START_GAME; _netMgr->sendTo(playerNetId, &startGameMsg, sizeof(startGameMsg)); break; } case Net::CLASS_SELECTED: { int race; inBuffer.deserialize(race); if(race == 5) { unsigned int nbSpectators = 0; for(auto it = _playersMgr->begin(); it != _playersMgr->end(); ++it) { std::pair<Logic::TEntityID, bool> id = _playersMgr->getPlayerId(playerNetId); if(id.second) { if(Logic::CServer::getSingletonPtr()->getMap()->getEntityByID(id.first)->getType() == "Spectator") ++nbSpectators; } } if(nbSpectators < _maxSpectators) { // Creamos una entidad espectador y la replicamos en el cliente createAndMirrorSpectator(playerNetId); } else { // Mandamos un mensaje de que no existen slots disponibles // para jugar Net::NetMessageType noSlotsMsg = Net::NO_FREE_SPECTATOR_SLOTS; Net::CBuffer errorBuffer( sizeof(noSlotsMsg) ); errorBuffer.write( &noSlotsMsg, sizeof(noSlotsMsg) ); _netMgr->sendTo(playerNetId, errorBuffer.getbuffer(), errorBuffer.getSize()); } } else { // Si quedan slots para conectarse como jugador permitimos que // se conecte, sino le mandamos un mensaje bool isChanging = false; if( _playersMgr->existsByNetId(playerNetId) ) { isChanging = _playersMgr->getPlayer(playerNetId).isSpawned(); } // Si estamos cambiando de clase, consideramos un jugador menos, ya que // nosotros si no contariamos unsigned nbPlayersPlaying = _playersMgr->getNumberOfPlayersSpawned(); if(isChanging) --nbPlayersPlaying; if( nbPlayersPlaying < _maxPlayers) { Logic::TeamFaction::Enum team; if(_autoBalanceTeams) { if(_playersMgr->blueTeamPlayers() < _playersMgr->redTeamPlayers()) { team = Logic::TeamFaction::eBLUE_TEAM; } else { team = Logic::TeamFaction::eRED_TEAM; } } else { if(_gameMode == GameMode::eTEAM_DEATHMATCH || _gameMode == GameMode::eCAPTURE_THE_FLAG) { inBuffer.read(&team, sizeof(team)); } else { team = Logic::TeamFaction::eNONE; } } // Creamos una entidad jugador con la clase que nos hayan dicho // y la replicamos en el cliente createAndMirrorPlayer(race, playerNetId, team); } else { // Mandamos un mensaje de que no existen slots disponibles // para jugar Net::NetMessageType noSlotsMsg = Net::NO_FREE_PLAYER_SLOTS; Net::CBuffer errorBuffer( sizeof(noSlotsMsg) ); errorBuffer.write( &noSlotsMsg, sizeof(noSlotsMsg) ); _netMgr->sendTo(playerNetId, errorBuffer.getbuffer(), errorBuffer.getSize()); } } break; } case Net::PING: { Net::NetMessageType ackMsg = Net::PING; clock_t time = clock(); Net::CBuffer ackBuffer(sizeof(ackMsg) + sizeof(time)); ackBuffer.write(&ackMsg, sizeof(ackMsg)); ackBuffer.write(&time, sizeof(time)); _netMgr->sendTo(playerNetId, ackBuffer.getbuffer(), ackBuffer.getSize()); break; } case Net::LOCAL_PLAYER_LOADED: { Logic::TEntityID id; inBuffer.deserialize(id); Logic::CEntity* player = _map->getEntityByID(id); player->activate(); player->start(); break; } } } // dataPacketReceived