PopBusDispatcher::ClientPtr PopBusDispatcher::GetOrCreateClient(MojObject& accountId, bool sync) { MojLogTrace(s_log); ClientPtr client; ClientMap::iterator it; it = m_clients.find(accountId); if (it == m_clients.end()) { MojLogInfo(s_log, "Creating PopClient"); shared_ptr<DatabaseInterface> databaseInterface(new MojoDatabase(m_dbClient)); client.reset(new PopClient(databaseInterface, this, accountId, &m_service)); m_clients[accountId] = client; client->CreateSession(); MojLogInfo(s_log, "Setting pop client with account id %s", AsJsonString(accountId).c_str()); } else { client = it->second; } assert(client.get()); MojObject payload; if (sync) { client->SyncAccount(payload); } return client; }
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; }