void CMessageHoundCharge::deserialize(Net::CBuffer& buffer) { buffer.read( &_isActive, sizeof(_isActive) ); // Solo si la habilidad esta activa se mandan el resto // de los atributos if(_isActive) { buffer.read( &_filterMask, sizeof(_filterMask) ); buffer.read( &_force, sizeof(_force) ); } }
Net::CBuffer CMessageHoundCharge::serialize() { Net::CBuffer buffer; buffer.serialize( std::string("CMessageHoundCharge"), true ); buffer.write( &_isActive, sizeof(_isActive) ); // El resto de los atributos nos interesan solo si se // activa la habilidad if(_isActive) { buffer.write( &_filterMask, sizeof(_filterMask) ); buffer.write( &_force, sizeof(_force) ); } return buffer; }//
void CMessageInt::deserialize(Net::CBuffer &data) { CMessage::deserialize(data); data.read(&_int, sizeof(_int)); } // deserialize
void CMessageBool::serialize(Net::CBuffer &data) { CMessage::serialize(data); data.write((void*) (&_bool), sizeof(_bool)); } // serialize
void CMessageSetOwner::deserialize(Net::CBuffer& buffer) { TEntityID id; // Por problemas con enumerados utilizamos directamente // el read en vez del deserialize buffer.read( &id, sizeof(id) ); _entity = Logic::CServer::getSingletonPtr()->getMap()->getEntityByID(id); }
void CMessageBool::deserialize(Net::CBuffer &data) { CMessage::deserialize(data); data.read(&_bool, sizeof(_bool)); } // deserialize
// TODO FRS no es necesario enviar todo el transform siempre -> solo posicion / rotacion en eje vertical void CMessageTF::serialize(Net::CBuffer &data) { CMessage::serialize(data); for(int i = 0; i < 4; ++i) for(int j = 0; j < 4; ++j) data.write((void*)&_transform[i][j], sizeof(_transform[i][j])); } // serialize
void CMessageTF::deserialize(Net::CBuffer &data) { CMessage::deserialize(data); for(int i = 0; i < 4; ++i) for(int j = 0; j < 4; ++j) data.read(&_transform[i][j], sizeof(_transform[i][j])); } // deserialize
void CGameServerState::disconnectionPacketReceived(Net::CPaquete* packet) { // Obtenemos el puntero al gestor de jugadores y el id de red del cliente que se quiere desconectar Net::NetID playerNetId = packet->getConexion()->getId(); // Eliminamos la entidad manejada por el cliente que se quiere desconectar. // Para ello comprobamos si tiene asignado un id de entidad. Si no lo tiene, es que // no ha sido creada ninguna entidad (podria estar conectandose). if( _playersMgr->existsByNetId(playerNetId) ) { std::pair<Logic::TEntityID, bool> logicIdPair = _playersMgr->getPlayerId(playerNetId); if(logicIdPair.second) { Logic::CEntity* entityToBeDeleted = _map->getEntityByID(logicIdPair.first); Logic::CEntityFactory::getSingletonPtr()->deferredDeleteEntity(entityToBeDeleted, true); // A nivel logico, conviene que los clientes sepan quien se desconecta, // especialmente para eliminar cosas del hud Net::NetMessageType ackMsg = Net::PLAYER_OFF_MATCH; Net::CBuffer disconnectMsg; disconnectMsg.write(&ackMsg, sizeof(ackMsg)); disconnectMsg.write(&playerNetId, sizeof(playerNetId)); disconnectMsg.serialize(entityToBeDeleted->getName(), false); _netMgr->broadcast(disconnectMsg.getbuffer(), disconnectMsg.getSize()); } // Eliminamos el jugador que se desconecta del manager de jugadores _playersMgr->removePlayer(playerNetId); } } // disconnexionPacketReceived
void CMessageAudio::serialize(Net::CBuffer &data) { CMessage::serialize(data); unsigned int size = _path.size(); data.write(&size,sizeof(size)); data.write((void*)_path.c_str(),size); size = _id.size(); data.write(&size,sizeof(size)); data.write((void*)_id.c_str(),size); data.write((void*)(&_position.x), sizeof(_position.x)); data.write((void*)(&_position.y), sizeof(_position.y)); data.write((void*)(&_position.z), sizeof(_position.z)); data.write((void*) (&_notIfPlay), sizeof(_notIfPlay)); data.write((void*) (&_isPlayer), sizeof(_isPlayer)); }
void CMessageAudio::deserialize(Net::CBuffer &data) { unsigned int size; data.read(&size, sizeof(size)); char* aux = new char[size]; data.read(aux, size); _path.assign(aux,size); delete[] aux; unsigned int size1; data.read(&size1, sizeof(size1)); char* aux1 = new char[size1]; data.read(aux1, size1); _id.assign(aux1,size1); delete[] aux1; data.read(&_position.x, sizeof(_position.x)); data.read(&_position.y, sizeof(_position.y)); data.read(&_position.z, sizeof(_position.z)); data.read(&_notIfPlay, sizeof(_notIfPlay)); data.read(&_isPlayer, sizeof(_isPlayer)); }
void CMessageControl::deserialize(Net::CBuffer& buffer) { buffer.deserialize(_seq); buffer.read(&_controlType, sizeof(_controlType)); }
void CMessagePrimarySpell::deserialize(Net::CBuffer& buffer) { buffer.deserialize(_spell); }
void CMessagePrimaryShoot::deserialize(Net::CBuffer& buffer) { buffer.deserialize(_shoot); }
void CMessageMouse::deserialize(Net::CBuffer& buffer) { _controlType = Control::MOUSE; buffer.deserialize(_seq); buffer.deserialize(_mouse[0]); buffer.deserialize(_mouse[1]); }
void CMessageHudShield::deserialize(Net::CBuffer& buffer) { buffer.deserialize(_shield); }
Net::CBuffer CMessageParticleStop::serialize() { Net::CBuffer buffer; buffer.serialize( std::string("CMessageParticleStop"), true ); return buffer; }//
void CMessagePlayerSpawn::deserialize(Net::CBuffer& buffer) { buffer.deserialize(_position); buffer.deserialize(_orientation); }
void CMessageInt::serialize(Net::CBuffer &data) { CMessage::serialize(data); data.write((void*) (&_int), sizeof(_int)); } // serialize
void CGameServerState::createAndMirrorSpectator(Net::NetID playerNetId) { // Primero comprobamos si habia una entidad correspondiente a este jugador // ya que durante el juego tambien podemos cambiar de clase. // En caso de que la haya la eliminamos para crear la nueva std::pair<Logic::TEntityID, bool> id = _playersMgr->getPlayerId(playerNetId); if(id.second) { // Si el id devuelto es valido Logic::CEntity* deletePlayer = _map->getEntityByID( id.first ); if(deletePlayer) { Logic::CEntityFactory::getSingletonPtr()->deleteEntity(deletePlayer, true); } } // Obtenemos el nickname del jugador que quiere espectar std::string nickname = _playersMgr->getPlayerNickname(playerNetId); // Creamos la entidad espectador con el nombre del jugador Logic::CEntity* spectator = _map->createPlayer(nickname, "Spectator"); // Obtenemos la id logica de la entidad espectador Logic::TEntityID spectatorId = spectator->getEntityID(); // Seteamos la id logica del jugador en el gestor de jugadores _playersMgr->setEntityID(playerNetId, spectatorId); // Escribimos el tipo de mensaje de red a enviar Net::NetMessageType netMsg = Net::LOAD_PLAYERS; int nbPlayers = 1; // Serializamos toda la información que se necesita para la creación de la entidad Net::CBuffer buffer; buffer.write(&netMsg, sizeof(netMsg)); buffer.write(&nbPlayers, sizeof(nbPlayers)); buffer.write(&playerNetId, sizeof(playerNetId)); buffer.write(&spectatorId, sizeof(spectatorId)); buffer.serialize(nickname, false); // Nombre del player buffer.serialize("Spectator", false); // Clase del player // Enviamos la entidad nueva al resto de jugadores _netMgr->broadcastIgnoring(playerNetId, buffer.getbuffer(), buffer.getSize()); buffer.reset(); // Enviamos la entidad nueva al jugador local netMsg = Net::LOAD_LOCAL_PLAYER; // Serializamos toda la información que se necesita para la creación de la entidad buffer.write(&netMsg, sizeof(netMsg)); buffer.write(&playerNetId, sizeof(playerNetId)); buffer.write(&spectatorId, sizeof(spectatorId)); buffer.serialize(nickname, false); // Nombre del player buffer.serialize("Spectator", false); // Clase del player spectator->activate(); spectator->start(); _netMgr->sendTo(playerNetId, buffer.getbuffer(), buffer.getSize()); _playersMgr->setPlayerState(playerNetId, false); _playersMgr->setPlayerTeam(playerNetId, Logic::TeamFaction::eNONE); }
void CGameServerState::sendWorldState(Net::NetID playerNetId) { Net::CBuffer worldBuffer = Logic::CWorldState::getSingletonPtr()->serialize(); Net::CBuffer scoreboardBuffer = _playersMgr->serializeScoreboardInfo(); Net::CBuffer sendWorldState; Net::NetMessageType loadPlayersMsg = Net::LOAD_WORLD_STATE; sendWorldState.write( &loadPlayersMsg,sizeof(loadPlayersMsg) ); sendWorldState.write( worldBuffer.getbuffer(), worldBuffer.getSize() ); sendWorldState.write( scoreboardBuffer.getbuffer(), scoreboardBuffer.getSize() ); // Enviamos los datos asociados a los players online al nuevo player _netMgr->sendTo(playerNetId, sendWorldState.getbuffer(), sendWorldState.getSize()); }
void CMessageHudDebugData::deserialize(Net::CBuffer& buffer) { buffer.deserialize(_key); buffer.deserialize(_value); }
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
void CGameServerState::createAndMirrorPlayer(int race, Net::NetID playerNetId, Logic::TeamFaction::Enum team) { // Primero comprobamos si habia una entidad correspondiente a este jugador // ya que durante el juego tambien podemos cambiar de clase. // En caso de que la haya la eliminamos para crear la nueva std::pair<Logic::TEntityID, bool> id = _playersMgr->getPlayerId(playerNetId); if(id.second) { // Si el id devuelto es valido Logic::CEntity* deletePlayer = _map->getEntityByID( id.first ); if(deletePlayer) { Logic::CEntityFactory::getSingletonPtr()->deleteEntity(deletePlayer, true); } } std::string name = _playersMgr->getPlayerNickname(playerNetId); // Obtenemos el nombre de la clase a la que pertenece el player std::string playerClass; switch(race) { case 1: playerClass = "Screamer"; break; case 2: playerClass = "Hound"; break; case 3: playerClass = "Archangel"; break; case 4: playerClass = "Shadow"; break; } // Creamos el player Logic::CEntity* player = _map->createPlayer(name, playerClass); // Seteamos la id logica asociada al player Logic::TEntityID playerId = player->getEntityID(); _playersMgr->setEntityID(playerNetId, playerId); // Escribimos el tipo de mensaje de red a enviar Net::NetMessageType netMsg = Net::LOAD_PLAYERS; int nbPlayers = 1; // Serializamos toda la información que se necesita para la creación de la entidad Net::CBuffer buffer; buffer.write(&netMsg, sizeof(netMsg)); buffer.write(&nbPlayers, sizeof(nbPlayers)); buffer.write(&playerNetId, sizeof(playerNetId)); buffer.write(&playerId, sizeof(playerId)); buffer.serialize(player->getName(), false); // Nombre del player buffer.serialize(player->getType(), false); // Clase del player buffer.write(&team, sizeof(team)); // Enviamos la entidad nueva al resto de jugadores _netMgr->broadcastIgnoring(playerNetId, buffer.getbuffer(), buffer.getSize()); buffer.reset(); // Enviamos la entidad nueva al jugador local netMsg = Net::LOAD_LOCAL_PLAYER; // Serializamos toda la información que se necesita para la creación de la entidad buffer.write(&netMsg, sizeof(netMsg)); buffer.write(&playerNetId, sizeof(playerNetId)); buffer.write(&playerId, sizeof(playerId)); buffer.serialize(player->getName(), false); // Nombre del player buffer.serialize(player->getType(), false); // Clase del player buffer.write(&team, sizeof(team)); std::cout << "el equipo que estoy enviando es ... " << team << std::endl; player->activate(); player->start(); _netMgr->sendTo(playerNetId, buffer.getbuffer(), buffer.getSize()); _playersMgr->setPlayerState(playerNetId, true); _playersMgr->setPlayerTeam(playerNetId, team); }