void NetManager::readSpriteRequest(ENetPacket* packet, ENetPeer* peer, size_t& position) { size_t numSprites; readFromPacket(packet, position, numSprites); std::vector<size_t> requestedSprites(numSprites); for(size_t i = 0; i < numSprites; i++) readFromPacket(packet, position, requestedSprites[i]); std::vector<std::string> paths(numSprites); auto renderer = FARender::Renderer::get(); size_t size = 0; for(size_t i = 0; i < numSprites; i++) { paths[i] = renderer->getPathForIndex(requestedSprites[i]); size += paths[i].size(); size += 1; // null terminator std::cout << "responding to: " << requestedSprites[i] << " " << paths[i] << std::endl; } size += numSprites * sizeof(size_t); size += sizeof(int32_t); // type header size += sizeof(size_t); // numSprites count int32_t typeHeader = ReliableMessageKind::Sprite; ENetPacket* responsePacket = enet_packet_create(NULL, size, ENET_PACKET_FLAG_RELIABLE); size_t writePosition = 0; writeToPacket(responsePacket, writePosition, typeHeader); writeToPacket(responsePacket, writePosition, numSprites); for(size_t i = 0; i < numSprites; i++) { writeToPacket(responsePacket, writePosition, requestedSprites[i]); std::string& path = paths[i]; char c; for(size_t j = 0; j < path.size(); j++) { c = path[j]; writeToPacket(responsePacket, writePosition, c); } c = 0; writeToPacket(responsePacket, writePosition, c); } enet_peer_send(peer, RELIABLE_CHANNEL_ID, responsePacket); }
void NetManager::sendServerPacket() { FAWorld::World& world = *FAWorld::World::get(); size_t packetSize = 512; ENetPacket* packet = enet_packet_create(NULL, packetSize, ENET_PACKET_FLAG_UNSEQUENCED); size_t position = 0; // write header ServerPacketHeader header; header.numPlayers = 0; header.tick = mTick; writeToPacket(packet, position, header); std::vector<FAWorld::Actor*> allActors; world.getAllActors(allActors); std::sort(allActors.begin(), allActors.end(), [](FAWorld::Actor* a, FAWorld::Actor* b) -> bool { return a->getPriority() > b->getPriority(); }); bool packetFull = false; for(auto actor : allActors) { if(((bool)dynamic_cast<FAWorld::Monster*>(actor))) continue; if(!packetFull) { bool fits = writeToPacket(packet, position, actor->getClassId()) && writeToPacket(packet, position, actor->getId()) && actor->writeTo(packet, position); if(!fits) packetFull = true; else header.numPlayers++; } actor->tickDone(!packetFull); } // rewrite packet header with correct object count position = 0; writeToPacket(packet, position, header); enet_host_broadcast(mHost, UNRELIABLE_CHANNEL_ID, packet); }
void NetManager::sendServerPacket() { FAWorld::World& world = *FAWorld::World::get(); size_t bytesPerClient = world.getCurrentPlayer()->getSize() + sizeof(uint32_t); // the uint is for player id size_t packetSize = sizeof(ServerPacketHeader) + bytesPerClient*(mClients.size() +1); // +1 for the local player ENetPacket* packet = enet_packet_create(NULL, packetSize, 0); size_t position = 0; // write header ServerPacketHeader header; header.numPlayers = mClients.size() + 1; header.tick = mTick; writeToPacket(packet, position, header); // write server player writeToPacket<uint32_t>(packet, position, SERVER_PLAYER_ID); position = world.getCurrentPlayer()->writeTo(packet, position); // write all clients for(size_t i = 0; i < mClients.size(); i++) { writeToPacket<uint32_t>(packet, position, mClients[i]->connectID); position = world.getPlayer(mClients[i]->connectID)->writeTo(packet, position); } enet_host_broadcast(mHost, 0, packet); }
void NetManager::sendLevel(size_t levelIndex, ENetPeer *peer) { int32_t typeHeader = ReliableMessageKind::Level; ENetPacket* packet = enet_packet_create(NULL, sizeof(int32_t), ENET_PACKET_FLAG_RELIABLE); size_t position = 0; writeToPacket(packet, position, typeHeader); FAWorld::GameLevel* level = FAWorld::World::get()->getLevel(levelIndex); level->saveToPacket(packet, position); enet_peer_send(peer, RELIABLE_CHANNEL_ID, packet); }
void NetManager::sendSpriteRequest(ENetPeer* peer) { int32_t typeHeader = ReliableMessageKind::Sprite; size_t numSprites = mUnknownServerSprites.size(); ENetPacket* packet = enet_packet_create(NULL, (numSprites+1) * sizeof(size_t) + sizeof(int32_t), ENET_PACKET_FLAG_RELIABLE); size_t position = 0; writeToPacket(packet, position, typeHeader); writeToPacket(packet, position, numSprites); for(size_t index : mUnknownServerSprites) { writeToPacket(packet, position, index); mAlreadySentServerSprites.insert(index); std::cout << "requesting " << index << std::endl; } mUnknownServerSprites.clear(); enet_peer_send(peer, RELIABLE_CHANNEL_ID, packet); }
void NetManager::sendClientPacket() { ENetPacket* packet = enet_packet_create(NULL, sizeof(ClientPacket), 0); auto player = FAWorld::World::get()->getCurrentPlayer(); ClientPacket data; data.destX = player->destination().first; data.destY = player->destination().second; data.levelIndex = mLevelIndexTmp; size_t position = 0; writeToPacket(packet, position, data); enet_peer_send(mServerPeer, UNRELIABLE_CHANNEL_ID, packet); if(mUnknownServerSprites.size()) sendSpriteRequest(mServerPeer); }
void NetManager::update() { mTick++; ENetEvent event; // TODO: remove this block when we handle level switching properly auto player = FAWorld::World::get()->getCurrentPlayer(); if(player->getLevel()) mLevelIndexTmp = player->getLevel()->getLevelIndex(); else mLevelIndexTmp = -1; while(enet_host_service(mHost, &event, 0)) { switch(event.type) { case ENET_EVENT_TYPE_CONNECT: { if(mIsServer) { auto player = spawnPlayer(-1); // send the client its player id auto packet = enet_packet_create(NULL, sizeof(size_t), ENET_PACKET_FLAG_RELIABLE); size_t position = 0; writeToPacket(packet, position, player->getId()); enet_peer_send(event.peer, RELIABLE_CHANNEL_ID, packet); sendLevel(0, event.peer); sendLevel(1, event.peer); mClients.push_back(event.peer); mServerPlayerList[event.peer->connectID] = player; } break; } case ENET_EVENT_TYPE_RECEIVE: { if(mIsServer) readClientPacket(event); else readServerPacket(event); break; } default: { break; } } } if(mIsServer && mClients.size() > 0) sendServerPacket(); else if(mServerPeer != NULL) sendClientPacket(); enet_host_flush(mHost); }