/** Sends a vote for a major vote from a client to the server. Note that even
 *  this client will only store the vote when it is received back from the
 *  server.
 *  \param player_id The global player id of the voting player.
 *  \param major Major mode voted for.
 */
void ClientLobbyRoomProtocol::voteMajor(uint8_t player_id, uint32_t major)
{
    NetworkString *request = getNetworkString(6);
    request->addUInt8(LE_VOTE_MAJOR).addUInt8(player_id)
           .addUInt32(major);
    sendToServer(request, true);
    delete request;
}   // voteMajor
Esempio n. 2
0
// ----------------------------------------------------------------------------
void GameEventsProtocol::sendStartupBoost(uint8_t kart_id)
{
    NetworkString *ns = getNetworkString();
    ns->setSynchronous(true);
    ns->addUInt8(GE_STARTUP_BOOST).addUInt8(kart_id);
    sendToServer(ns, /*reliable*/true);
    delete ns;
}   // sendStartupBoost
/** Sends a vote if a track at a specified place in the list of all tracks
 *  should be played in reverse or not. Note that even this client will only
 *  store the vote when it is received back from the server.
 *  \param player_id Global player id of the voting player.
 *  \param reversed True if the track should be played in reverse.
 *  \param track_nb Index for the track to be voted on in the list of all
 *         tracks.
 */
void ClientLobbyRoomProtocol::voteReversed(uint8_t player_id, bool reversed, 
                                           uint8_t track_nb)
{
    NetworkString *request = getNetworkString(9);
    request->addUInt8(LE_VOTE_REVERSE).addUInt8(player_id).addUInt8(reversed)
            .addUInt8(track_nb);
    sendToServer(request, true);
    delete request;
}   // voteReversed
/** Sends the selection of a kart from this client to the server.
 *  \param player_id The global player id of the voting player.
 *  \param kart_name Name of the selected kart.
 */
void ClientLobbyRoomProtocol::requestKartSelection(uint8_t player_id,
                                                   const std::string &kart_name)
{
    NetworkString *request = getNetworkString(3+kart_name.size());
    request->addUInt8(LE_KART_SELECTION).addUInt8(player_id)
            .encodeString(kart_name);
    sendToServer(request, /*reliable*/ true);
    delete request;
}   // requestKartSelection
/** Vote for the number of laps of the specified track. Note that even this
 *  client will only store the vote when it is received back from the server.
 *  \param player_id Global player id of the voting player.
 *  \param laps Number of laps for the specified track.
 *  \param track_nb Index of the track in the list of all tracks.
 */
void ClientLobbyRoomProtocol::voteLaps(uint8_t player_id, uint8_t laps,
                                       uint8_t track_nb)
{
    NetworkString *request = getNetworkString(10);
    request->addUInt8(LE_VOTE_LAPS).addUInt8(player_id).addUInt8(laps)
            .addUInt8(track_nb);
    sendToServer(request, true);
    delete request;
}   // voteLaps
Esempio n. 6
0
/** This function is called from the server when a kart finishes a race. It
 *  sends a notification to all clients about this event.
 *  \param kart The kart that finished the race.
 *  \param time The time at which the kart finished.
 */
void GameEventsProtocol::kartFinishedRace(AbstractKart *kart, float time)
{
    NetworkString *ns = getNetworkString(20);
    ns->setSynchronous(true);
    ns->addUInt8(GE_KART_FINISHED_RACE).addUInt8(kart->getWorldKartId())
       .addFloat(time);
    sendMessageToPeers(ns, /*reliable*/true);
    delete ns;
}   // kartFinishedRace
void ClientLobbyRoomProtocol::update(float dt)
{
    switch (m_state)
    {
    case NONE:
        if (STKHost::get()->isConnectedTo(m_server_address))
        {
            m_state = LINKED;
        }
        break;
    case LINKED:
    {
        core::stringw name;
        if(PlayerManager::getCurrentOnlineState()==PlayerProfile::OS_SIGNED_IN)
            name = PlayerManager::getCurrentOnlineUserName();
        else
            name = PlayerManager::getCurrentPlayer()->getName();

        std::string name_u8 = StringUtils::wideToUtf8(name);
        const std::string &password = NetworkConfig::get()->getPassword();
        NetworkString *ns = getNetworkString(6+1+name_u8.size()
                                                 +1+password.size());
        // 4 (size of id), global id
        ns->addUInt8(LE_CONNECTION_REQUESTED).encodeString(name)
          .encodeString(NetworkConfig::get()->getPassword());
        sendToServer(ns);
        delete ns;
        m_state = REQUESTING_CONNECTION;
    }
    break;
    case REQUESTING_CONNECTION:
        break;
    case CONNECTED:
        break;
    case KART_SELECTION:
    {
        NetworkKartSelectionScreen* screen =
                                     NetworkKartSelectionScreen::getInstance();
        screen->push();
        m_state = SELECTING_KARTS;
    }
    break;
    case SELECTING_KARTS:
        break;
    case PLAYING:
        break;
    case RACE_FINISHED:
        break;
    case DONE:
        m_state = EXITING;
        ProtocolManager::getInstance()->requestTerminate(this);
        break;
    case EXITING:
        break;
    }
}   // update
/** Sends the vote about which track to play at which place in the list of
 *  tracks (like a custom GP definition). Note that even this client will only
 *  store the vote when it is received back from the server.
 *  \param player_id The global player id of the voting player.
 *  \param track Name of the track.
 *  \param At which place in the list of tracks this track should be played.
 */
void ClientLobbyRoomProtocol::voteTrack(uint8_t player_id,
                                        const std::string &track,
                                        uint8_t track_nb)
{
    NetworkString *request = getNetworkString(2+1+track.size());
    request->addUInt8(LE_VOTE_TRACK).addUInt8(player_id).addUInt8(track_nb)
            .encodeString(track);
    sendToServer(request, true);
    delete request;
}   // voteTrack
/** Sends a packet to this host.
 *  \param data The data to send.
 *  \param reliable If the data is sent reliable or not.
 */
void STKPeer::sendPacket(NetworkString const& data, bool reliable)
{
    TransportAddress a(m_enet_peer->address);
    Log::verbose("STKPeer", "sending packet of size %d to %s",
                 data.size(), a.toString().c_str());
         
    ENetPacket* packet = enet_packet_create(data.getBytes(), data.size() + 1,
                                    (reliable ? ENET_PACKET_FLAG_RELIABLE
                                              : ENET_PACKET_FLAG_UNSEQUENCED));
    enet_peer_send(m_enet_peer, 0, packet);
}   // sendPacket
/** This function informs each client to start the race, and then starts the
 *  StartGameProtocol.
 */
void ServerLobbyRoomProtocol::startGame()
{
    const std::vector<STKPeer*> &peers = STKHost::get()->getPeers();
    NetworkString *ns = getNetworkString(1);
    ns->addUInt8(LE_START_RACE);
    sendMessageToPeersChangingToken(ns, /*reliable*/true);
    delete ns;
    Protocol *p = new StartGameProtocol(m_setup);
    p->requestStart();
    m_state = RACING;
}   // startGame
/*! \brief Called when a player asks to select a kart.
 *  \param event : Event providing the information.
 *
 *  Format of the data :
 *  Byte 0          1                      2            
 *       ----------------------------------------------
 *  Size |    1     |           1         |     N     |
 *  Data |player id |  N (kart name size) | kart name |
 *       ----------------------------------------------
 */
void ServerLobbyRoomProtocol::kartSelectionRequested(Event* event)
{
    if(m_state!=SELECTING)
    {
        Log::warn("Server", "Received kart selection while in state %d.",
                  m_state);
        return;
    }

    if (!checkDataSize(event, 1)) return;

    const NetworkString &data = event->data();
    STKPeer* peer = event->getPeer();

    uint8_t player_id = data.getUInt8();
    std::string kart_name;
    data.decodeString(&kart_name);
    // check if selection is possible
    if (!m_selection_enabled)
    {
        NetworkString *answer = getNetworkString(2);
        // selection still not started
        answer->addUInt8(LE_KART_SELECTION_REFUSED).addUInt8(2);
        peer->sendPacket(answer);
        delete answer;
        return;
    }
    // check if somebody picked that kart
    if (!m_setup->isKartAvailable(kart_name))
    {
        NetworkString *answer = getNetworkString(2);
        // kart is already taken
        answer->addUInt8(LE_KART_SELECTION_REFUSED).addUInt8(0);
        peer->sendPacket(answer);
        delete answer;
        return;
    }
    // check if this kart is authorized
    if (!m_setup->isKartAllowed(kart_name))
    {
        NetworkString *answer = getNetworkString(2);
        // kart is not authorized
        answer->addUInt8(LE_KART_SELECTION_REFUSED).addUInt8(1);
        peer->sendPacket(answer);
        delete answer;
        return;
    }

    // send a kart update to everyone
    NetworkString *answer = getNetworkString(3+kart_name.size());
    // This message must be handled synchronously on the client.
    answer->setSynchronous(true);
    // kart update (3), 1, race id
    answer->addUInt8(LE_KART_SELECTION_UPDATE).addUInt8(player_id)
          .encodeString(kart_name);
    sendMessageToPeersChangingToken(answer);
    delete answer;
    m_setup->setPlayerKart(player_id, kart_name);
}   // kartSelectionRequested
void ServerLobbyRoomProtocol::startSelection()
{
    std::vector<STKPeer*> peers = NetworkManager::getInstance()->getPeers();
    for (unsigned int i = 0; i < peers.size(); i++)
    {
        NetworkString ns;
        ns.ai8(0x05).ai8(4).ai32(peers[i]->getClientServerToken()); // start selection
        m_listener->sendMessage(this, peers[i], ns, true); // reliably
    }
    m_selection_enabled = true;
}
void ServerLobbyRoomProtocol::startGame()
{
    std::vector<STKPeer*> peers = NetworkManager::getInstance()->getPeers();
    for (unsigned int i = 0; i < peers.size(); i++)
    {
        NetworkString ns;
        ns.ai8(0x04).ai8(4).ai32(peers[i]->getClientServerToken()); // start game
        m_listener->sendMessage(this, peers[i], ns, true); // reliably
    }
    m_listener->requestStart(new StartGameProtocol(m_setup));
    m_in_race = true;
}
Esempio n. 14
0
void SynchronizationProtocol::asynchronousUpdate()
{
    static double timer = StkTime::getRealTime();
    double current_time = StkTime::getRealTime();
    if (m_countdown_activated)
    {
        m_countdown -= (current_time - m_last_countdown_update);
        m_last_countdown_update = current_time;
        Log::debug("SynchronizationProtocol", "Update! Countdown remaining : %f", m_countdown);
        if (m_countdown < 0.0 && !m_has_quit)
        {
            m_has_quit = true;
            Log::info("SynchronizationProtocol", "Countdown finished. Starting now.");
            m_listener->requestStart(new KartUpdateProtocol());
            m_listener->requestStart(new ControllerEventsProtocol());
            m_listener->requestStart(new GameEventsProtocol());
            m_listener->requestTerminate(this);
            return;
        }
        static int seconds = -1;
        if (seconds == -1)
        {
            seconds = (int)(ceil(m_countdown));
        }
        else if (seconds != (int)(ceil(m_countdown)))
        {
            seconds = (int)(ceil(m_countdown));
            Log::info("SynchronizationProtocol", "Starting in %d seconds.", seconds);
        }
    }
    if (current_time > timer+0.1)
    {
        std::vector<STKPeer*> peers = NetworkManager::getInstance()->getPeers();
        for (unsigned int i = 0; i < peers.size(); i++)
        {
            NetworkString ns;
            ns.ai8(i).addUInt32(peers[i]->getClientServerToken()).addUInt8(1).addUInt32(m_pings[i].size());
            // now add the countdown if necessary
            if (m_countdown_activated && m_listener->isServer())
            {
                ns.addUInt32((int)(m_countdown*1000.0));
                Log::debug("SynchronizationProtocol", "CNTActivated: Countdown value : %f", m_countdown);
            }
            Log::verbose("SynchronizationProtocol", "Added sequence number %u for peer %d", m_pings[i].size(), i);
            timer = current_time;
            m_pings[i].insert(std::pair<int,double>(m_pings_count[i], timer));
            m_listener->sendMessage(this, peers[i], ns, false);
            m_pings_count[i]++;
        }
    }

}
/** Saves a state on the client. Used to save an initial state at t=0 for each
 *  client in case that we receive an event from another client (which will
 *  trigger a rewind) before a state from the server.
 */
void RewindManager::saveLocalState()
{
    int ticks = World::getWorld()->getTimeTicks();

    saveState(/*local_state*/true);
    NetworkString *state = GameProtocol::lock()->getState();

    // Copy the data to a new string, making the buffer in
    // GameProtocol availble for again.
    BareNetworkString *bns =
        new BareNetworkString(state->getCurrentData(),
                              state->size()           );
    m_rewind_queue.addLocalState(bns, /*confirmed*/true, ticks);
}   // saveLocalState
/*! \brief Called when a player votes for a minor race mode.
 *  \param event : Event providing the information.
 *
 *  Format of the data :
 *  Byte 0           1
 *       -------------------------------
 *  Size |      1    |         4       |
 *  Data | player-id | minor mode vote |
 *       -------------------------------
 */
void ServerLobbyRoomProtocol::playerMinorVote(Event* event)
{
    if (!checkDataSize(event, 1)) return;
    NetworkString &data = event->data();
    uint8_t player_id   = data.getUInt8();
    uint32_t minor      = data.getUInt32();
    m_setup->getRaceConfig()->setPlayerMinorVote(player_id, minor);

    // Send the vote to everybody (including the sender)
    NetworkString *other = getNetworkString(3);
    other->addUInt8(LE_VOTE_MINOR).addUInt8(player_id).addUInt8(minor); 
    sendMessageToPeersChangingToken(other);
    delete other;
}   // playerMinorVote
/*! \brief Called when a player votes for a major race mode.
 *  \param event : Event providing the information.
 *
 *  Format of the data :
 *  Byte 0           1      2 
 *       ----------------------------------------
 *  Size |     1     |   1  |       1           |
 *  Data | player id | laps | track number (gp) |
 *       ----------------------------------------
 */
void ServerLobbyRoomProtocol::playerLapsVote(Event* event)
{
    if (!checkDataSize(event, 2)) return;
    NetworkString &data = event->data();
    uint8_t player_id   = data.getUInt8();
    uint8_t lap_count   = data.getUInt8();
    uint8_t track_nb    = data.getUInt8();
    m_setup->getRaceConfig()->setPlayerLapsVote(player_id, lap_count,
                                                track_nb);
    NetworkString *other = getNetworkString(4);
    other->addUInt8(LE_VOTE_LAPS).addUInt8(player_id).addUInt8(lap_count)
          .addUInt8(track_nb);
    sendMessageToPeersChangingToken(other);
    delete other;
}   // playerLapsVote
void ServerLobbyRoomProtocol::kartDisconnected(Event* event)
{
    STKPeer* peer = *(event->peer);
    if (peer->getPlayerProfile() != NULL) // others knew him
    {
        NetworkString msg;
        msg.ai8(0x02).ai8(1).ai8(peer->getPlayerProfile()->race_id);
        m_listener->sendMessage(this, msg);
        Log::info("ServerLobbyRoomProtocol", "Player disconnected : id %d",
                  peer->getPlayerProfile()->race_id);
        m_setup->removePlayer(peer->getPlayerProfile()->race_id);
        NetworkManager::getInstance()->removePeer(peer);
    }
    else
        Log::info("ServerLobbyRoomProtocol", "The DC peer wasn't registered.");
}
/*! \brief Called when a player votes for the reverse mode of a race
 *  \param event : Event providing the information.
 *
 *  Format of the data :
 *  Byte 0           1          2
 *       --------------------------------------------
 *  Size |     1     |     1    |       1           |
 *  Data | player id | reversed | track number (gp) |
 *       --------------------------------------------
 */
void ServerLobbyRoomProtocol::playerReversedVote(Event* event)
{
    if (!checkDataSize(event, 3)) return;

    NetworkString &data = event->data();
    uint8_t player_id   = data.getUInt8();
    uint8_t reverse     = data.getUInt8();
    uint8_t nb_track    = data.getUInt8();
    m_setup->getRaceConfig()->setPlayerReversedVote(player_id,
                                                    reverse!=0, nb_track);
    // Send the vote to everybody (including the sender)
    NetworkString *other = getNetworkString(4);
    other->addUInt8(LE_VOTE_REVERSE).addUInt8(player_id).addUInt8(reverse)
          .addUInt8(nb_track);
    sendMessageToPeersChangingToken(other);
    delete other;
}   // playerReversedVote
Esempio n. 20
0
void StartGameProtocol::ready() // on clients, means the loading is finished
{
    if (!m_listener->isServer()) // if we're a client
    {
        assert(NetworkManager::getInstance()->getPeerCount() == 1);
        NetworkString ns;
        ns.ai32(NetworkManager::getInstance()->getPeers()[0]->getClientServerToken()).ai8(1);
        Log::info("StartGameProtocol", "Player ready, notifying server.");
        m_listener->sendMessage(this, ns, true);
        m_state = READY;
        m_ready = true;
        return;
    }
    else // on the server
    {
    }
}
/** Checks if the race is finished, and if so informs the clients and switches
 *  to state RESULT_DISPLAY, during which the race result gui is shown and all
 *  clients can click on 'continue'.
 */
 void ServerLobbyRoomProtocol::checkRaceFinished()
{
    assert(RaceEventManager::getInstance()->isRunning());
    assert(World::getWorld());
    if(!RaceEventManager::getInstance()->isRaceOver()) return;

    m_player_ready_counter = 0;
    // Set the delay before the server forces all clients to exit the race
    // result screen and go back to the lobby
    m_timeout = (float)(StkTime::getRealTime()+15.0f);
    m_state = RESULT_DISPLAY;

    // calculate karts ranks :
    int num_karts = race_manager->getNumberOfKarts();
    std::vector<int> karts_results;
    std::vector<float> karts_times;
    for (int j = 0; j < num_karts; j++)
    {
        float kart_time = race_manager->getKartRaceTime(j);
        for (unsigned int i = 0; i < karts_times.size(); i++)
        {
            if (kart_time < karts_times[i])
            {
                karts_times.insert(karts_times.begin() + i, kart_time);
                karts_results.insert(karts_results.begin() + i, j);
                break;
            }
        }
    }

    const std::vector<STKPeer*> &peers = STKHost::get()->getPeers();

    NetworkString *total = getNetworkString(1 + karts_results.size());
    total->setSynchronous(true);
    total->addUInt8(LE_RACE_FINISHED);
    for (unsigned int i = 0; i < karts_results.size(); i++)
    {
        total->addUInt8(karts_results[i]); // kart pos = i+1
        Log::info("ServerLobbyRoomProtocol", "Kart %d finished #%d",
            karts_results[i], i + 1);
    }
    sendMessageToPeersChangingToken(total, /*reliable*/ true);
    delete total;
    Log::info("ServerLobbyRoomProtocol", "End of game message sent");
        
}   // checkRaceFinished
Esempio n. 22
0
void STKPeer::sendPacket(NetworkString const& data, bool reliable)
{
    TransportAddress a(m_peer->address);
    Log::verbose("STKPeer", "sending packet of size %d to %s",
                 a.toString().c_str());

    ENetPacket* packet = enet_packet_create(data.getBytes(), data.size() + 1,
                                            (reliable ? ENET_PACKET_FLAG_RELIABLE : ENET_PACKET_FLAG_UNSEQUENCED));
    /* to debug the packet output
    printf("STKPeer: ");
    for (unsigned int i = 0; i < data.size(); i++)
    {
        printf("%d ", (uint8_t)(data[i]));
    }
    printf("\n");
    */
    enet_peer_send(m_peer, 0, packet);
}
Esempio n. 23
0
/** This function is called on a client when it receives a kartFinishedRace
 *  event from the server. It updates the game with this information.
 *  \param ns The message from the server.
 */
void GameEventsProtocol::kartFinishedRace(const NetworkString &ns)
{
    if (ns.size() < 5)
    {
        Log::warn("GameEventsProtocol", "kartFinisheRace: Too short message.");
        return;
    }

    uint8_t kart_id = ns.getUInt8();
    float time      = ns.getFloat();
    if (race_manager->modeHasLaps())
    {
        World::getWorld()->getKart(kart_id)
            ->setPosition(m_last_finished_position++);
    }
    World::getWorld()->getKart(kart_id)->finishedRace(time,
                                                      /*from_server*/true);
}   // kartFinishedRace
Esempio n. 24
0
bool StartGameProtocol::notifyEventAsynchronous(Event* event)
{
    NetworkString data = event->data();
    if (data.size() < 5)
    {
        Log::error("StartGameProtocol", "Too short message.");
        return true;
    }
    uint32_t token = data.gui32();
    uint8_t ready = data.gui8(4);
    STKPeer* peer = (*(event->peer));
    if (peer->getClientServerToken() != token)
    {
        Log::error("StartGameProtocol", "Bad token received.");
        return true;
    }
    if (m_listener->isServer() && ready) // on server, player is ready
    {
        Log::info("StartGameProtocol", "One of the players is ready.");
        m_player_states[peer->getPlayerProfile()] = READY;
        m_ready_count++;
        if (m_ready_count == m_game_setup->getPlayerCount())
        {
            // everybody ready, synchronize
            SynchronizationProtocol* protocol = static_cast<SynchronizationProtocol*>(m_listener->getProtocol(PROTOCOL_SYNCHRONIZATION));
            if (protocol)
            {
                protocol->startCountdown(5000); // 5 seconds countdown
                Log::info("StartGameProtocol", "All players ready, starting countdown.");
                m_ready = true;
                return true;
            }
            else
                Log::error("StartGameProtocol", "The Synchronization protocol hasn't been started.");
        }
    }
    else // on the client, we shouldn't even receive messages.
    {
        Log::error("StartGameProtocol", "Received a message with bad format.");
    }
    return true;
}
/*! \brief Called when a player votes for a track.
 *  \param event : Event providing the information.
 *
 *  Format of the data :
 *  Byte 0           1                    2  3
 *       --------------------------------------------------
 *  Size |     1     |        1          | 1 |      N     |
 *  Data | player id | track number (gp) | N | track name |
 *       --------------------------------------------------
 */
void ServerLobbyRoomProtocol::playerTrackVote(Event* event)
{
    if (!checkDataSize(event, 3)) return;
    NetworkString &data  = event->data();
    uint8_t player_id    = data.getUInt8();
    // As which track this track should be used, e.g. 1st track: Sandtrack
    // 2nd track Mathclass, ...
    uint8_t track_number = data.getUInt8();
    std::string track_name;
    int N = data.decodeString(&track_name);
    m_setup->getRaceConfig()->setPlayerTrackVote(player_id, track_name,
                                                 track_number);
    // Send the vote to everybody (including the sender)
    NetworkString *other = getNetworkString(3+1+data.size());
    other->addUInt8(LE_VOTE_TRACK).addUInt8(player_id).addUInt8(track_number)
          .encodeString(track_name);
    sendMessageToPeersChangingToken(other);
    delete other;
    if(m_setup->getRaceConfig()->getNumTrackVotes()==m_setup->getPlayerCount())
        startGame();
}   // playerTrackVote
/** Instructs all clients to start the kart selection. If event is not NULL,
 *  the command comes from a client (which needs to be authorised).
 */
void ServerLobbyRoomProtocol::startSelection(const Event *event)
{
    if(event && !event->getPeer()->isAuthorised())
    {
        Log::warn("ServerLobby", 
                  "Client %lx is not authorised to start selection.",
                  event->getPeer());
        return;
    }
    const std::vector<STKPeer*> &peers = STKHost::get()->getPeers();
    NetworkString *ns = getNetworkString(1);
    // start selection
    ns->addUInt8(LE_START_SELECTION);
    sendMessageToPeersChangingToken(ns, /*reliable*/true);
    delete ns;

    m_selection_enabled = true;

    m_state = SELECTING;
    WaitingForOthersScreen::getInstance()->push();
}   // startSelection
/** Called when a client disconnects.
 *  \param event The disconnect event.
 */
void ServerLobbyRoomProtocol::clientDisconnected(Event* event)
{
    std::vector<NetworkPlayerProfile*> players_on_host = 
                                      event->getPeer()->getAllPlayerProfiles();

    NetworkString *msg = getNetworkString(2);
    msg->addUInt8(LE_PLAYER_DISCONNECTED);

    for(unsigned int i=0; i<players_on_host.size(); i++)
    {
        msg->addUInt8(players_on_host[i]->getGlobalPlayerId());
        Log::info("ServerLobbyRoomProtocol", "Player disconnected : id %d",
                  players_on_host[i]->getGlobalPlayerId());
        m_setup->removePlayer(players_on_host[i]);
    }

    sendMessageToPeersChangingToken(msg, /*reliable*/true);
    // Remove the profile from the peer (to avoid double free)
    STKHost::get()->removePeer(event->getPeer());
    delete msg;
    
}   // clientDisconnected
bool ServerLobbyRoomProtocol::notifyEventAsynchronous(Event* event)
{
    assert(m_setup); // assert that the setup exists
    if (event->type == EVENT_TYPE_MESSAGE)
    {
        NetworkString data = event->data();
        assert(data.size()); // message not empty
        uint8_t message_type;
        message_type = data[0];
        event->removeFront(1);
        Log::info("ServerLobbyRoomProtocol", "Message received with type %d.", message_type);
        if (message_type == 0x01) // player requesting connection
            connectionRequested(event);
        else if (message_type == 0x02) // player requesting kart selection
            kartSelectionRequested(event);
        else if (message_type == 0xc0) // vote for major mode
            playerMajorVote(event);
        else if (message_type == 0xc1) // vote for race count
            playerRaceCountVote(event);
        else if (message_type == 0xc2) // vote for minor mode
            playerMinorVote(event);
        else if (message_type == 0xc3) // vote for track
            playerTrackVote(event);
        else if (message_type == 0xc4) // vote for reversed mode
            playerReversedVote(event);
        else if (message_type == 0xc5) // vote for laps
            playerLapsVote(event);
    } // if (event->type == EVENT_TYPE_MESSAGE)
    else if (event->type == EVENT_TYPE_CONNECTED)
    {
    } // if (event->type == EVENT_TYPE_CONNECTED)
    else if (event->type == EVENT_TYPE_DISCONNECTED)
    {
        kartDisconnected(event);
    } // if (event->type == EVENT_TYPE_DISCONNECTED)
    return true;
}
/** \brief Log packets into a file
 *  \param ns : The data in the packet
 *  \param incoming : True if the packet comes from a peer.
 *  False if it's sent to a peer.
 */
void Network::logPacket(const NetworkString &ns, bool incoming)
{
    if (m_log_file.getData() == NULL) // read only access, no need to lock
        return;

    const char *arrow = incoming ? "<--" : "-->";

    m_log_file.lock();
    fprintf(m_log_file.getData(), "[%d\t]  %s  ",
            (int)(StkTime::getRealTime()), arrow);

    for (int i = 0; i < ns.size(); i++)
    {
        fprintf(m_log_file.getData(), "%d.", ns[i]);
    }
    fprintf(m_log_file.getData(), "\n");
    m_log_file.unlock();
}   // logPacket
Esempio n. 30
0
// ----------------------------------------------------------------------------
void STKHost::handleLANRequests()
{
    const int LEN=2048;
    char buffer[LEN];

    TransportAddress sender;
    int len = m_lan_network->receiveRawPacket(buffer, LEN, &sender, 1);
    if(len<=0) return;

    if (std::string(buffer, len) == "stk-server")
    {
        Log::verbose("STKHost", "Received LAN server query");
        std::string name = 
            StringUtils::wideToUtf8(NetworkConfig::get()->getServerName());
        // Avoid buffer overflows
        if (name.size() > 255)
            name = name.substr(0, 255);

        // Send the answer, consisting of server name, max players, 
        // current players, and the client's ip address and port
        // number (which solves the problem which network interface
        // might be the right one if there is more than one).
        NetworkString s;
        s.encodeString(name);
        s.addUInt8(NetworkConfig::get()->getMaxPlayers());
        s.addUInt8(0);   // FIXME: current number of connected players
        s.addUInt32(sender.getIP());
        s.addUInt16(sender.getPort());
        m_lan_network->sendRawPacket(s.getBytes(), s.size(), sender);
    }   // if message is server-requested
    else if (std::string(buffer, len) == "connection-request")
    {
        Protocol *c = new ConnectToPeer(sender);
        c->requestStart();
    }
    else
        Log::info("STKHost", "Received unknown command '%s'",
                  std::string(buffer, len).c_str());

}   // handleLANRequests