void Gamefield::onStart(ClientPtr client, PacketPtr packet) { auto p = std::dynamic_pointer_cast<StartPacket >(packet); String color = mOptions.player.color[rand()%mOptions.player.color.size()]; printf("Player %s joind the game\n", p->Name.c_str()); PlayerPtr ply = std::make_shared<Player>(shared_from_this(), client, color, p->Name); mPlayer[client->getId()] = ply; ply->addBall(createBall(ply)); ply->updateClient(); client->emit(std::make_shared<EmptyPacket<PID_Start> >()); }
void Gamefield::onDisconnected(ClientPtr client) { auto it = mPlayer.find(client->getId()); if(it != mPlayer.end()) { for(BallPtr ball : it->second->getBalls()) destroyElement(ball); mPlayer.erase(it); } mClients.remove(client); if(mClients.empty()) mUpdaterRunning = false; }
std::vector<ClientPtr> GameWorld::processClients() { std::vector<ClientPtr> toRemove(0); // process clients for(ClientList::const_iterator itor = _clients.begin(); itor != _clients.end(); ){ ClientPtr client = *itor; TCPMessagePtr result = client->processClient(); if (result->type == TCPMessage::MSG_QUIT || result->type == TCPMessage::MSG_DISCONNECT) { std::cout << "Client " << client->getId() << " quit " << ( result->type == TCPMessage::MSG_DISCONNECT ? "abnormally" : "" ) << "\n"; toRemove.push_back(client); // broadcast to clients if they saw it before if (client->isLoggedIn()){ broadcastMessage( TCPMessage( TCPMessage::MSG_PLAYER_LEFT, client->getCurrentCharacter()->getName() ), client.get() ); } // save the account data client->save(); // remove from list itor = _clients.erase(itor); } else{ // send message to other clients if (result->type == TCPMessage::MSG_CHAT){ broadcastMessage(result); } else if (result->type == TCPMessage::MSG_SELECT_CHAR){ // character selected { // send the map to the player int mapSizes[] = { MAP_MAX_WIDTH, MAP_MAX_HEIGHT }; TCPMessagePtr msg = TCPMessage::createMessage(TCPMessage::MSG_MAP, mapSizes, 2, std::string(_mapData.contents().begin(), _mapData.contents().end())); msg->sendToSocket(client->getSocket()); } if ( _clients.size() > 1 ) { // send the existing players list (except us) std::string playerStr; playerStr += ( _clients.size() - 1 ); for ( ClientList::const_iterator it = _clients.begin(); it != _clients.end(); ++it) { ClientPtr other = *it; if ( other != client && other->isLoggedIn() ) { int data[] = { other->getCurrentCharacter()->position().x, other->getCurrentCharacter()->position().y, other->getCurrentCharacter()->level() }; std::string tmpStr; tmpStr += other->getCurrentCharacter()->getClass(); tmpStr += other->getCurrentCharacter()->getName(); playerStr += TCPMessage::createMessage(TCPMessage::MSG_LIST_PLAYERS, data, 3, tmpStr)->data; playerStr += '\0'; } } TCPMessage playersMsg( TCPMessage::MSG_LIST_PLAYERS, playerStr ); playersMsg.sendToSocket( client->getSocket() ); } { // announce the players about the new player miniui::vec2 position = client->getCurrentCharacter()->position(); std::string tmpStr; tmpStr += client->getCurrentCharacter()->getClass(); tmpStr += client->getCurrentCharacter()->getName(); int data[] = { position.x, position.y, client->getCurrentCharacter()->level() }; TCPMessagePtr joinMsg = TCPMessage::createMessage(TCPMessage::MSG_PLAYER_JOINED, data, 3, tmpStr); broadcastMessage(joinMsg, client.get()); } } ++itor; } } return toRemove; }