예제 #1
0
    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);
    }
예제 #2
0
    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);
    }
예제 #3
0
    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);
    }
예제 #4
0
    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);
    }
예제 #5
0
    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);
    }
예제 #6
0
    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);
    }
예제 #7
0
    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);
    }