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; }
bool SynchronizationProtocol::notifyEventAsynchronous(Event* event) { if (event->type != EVENT_TYPE_MESSAGE) return true; NetworkString data = event->data(); if (data.size() < 10) { Log::warn("SynchronizationProtocol", "Received a message too short."); return true; } uint8_t talk_id = data.gui8(); uint32_t token = data.gui32(1); uint32_t request = data.gui8(5); uint32_t sequence = data.gui32(6); std::vector<STKPeer*> peers = NetworkManager::getInstance()->getPeers(); assert(peers.size() > 0); if (m_listener->isServer()) { if (talk_id > peers.size()) { Log::warn("SynchronizationProtocol", "The ID isn't known."); return true; } } uint8_t peer_id = 0; for (unsigned int i = 0; i < peers.size(); i++) { if (peers[i]->isSamePeer(*event->peer)) { peer_id = i; } } if (peers[peer_id]->getClientServerToken() != token) { Log::warn("SynchronizationProtocol", "Bad token from peer %d", talk_id); return true; } if (request) { NetworkString response; response.ai8(data.gui8(talk_id)).ai32(token).ai8(0).ai32(sequence); m_listener->sendMessage(this, peers[peer_id], response, false); Log::verbose("SynchronizationProtocol", "Answering sequence %u", sequence); if (data.size() == 14 && !m_listener->isServer()) // countdown time in the message { uint32_t time_to_start = data.gui32(10); Log::debug("SynchronizationProtocol", "Request to start game in %d.", time_to_start); if (!m_countdown_activated) startCountdown(time_to_start); else m_countdown = (double)(time_to_start/1000.0); } else Log::verbose("SynchronizationProtocol", "No countdown for now."); } else // response { if (sequence >= m_pings[peer_id].size()) { Log::warn("SynchronizationProtocol", "The sequence# %u isn't known.", sequence); return true; } double current_time = StkTime::getRealTime(); m_total_diff[peer_id] += current_time - m_pings[peer_id][sequence]; Log::verbose("SynchronizationProtocol", "InstantPing is %u", (unsigned int)((current_time - m_pings[peer_id][sequence])*1000)); m_successed_pings[peer_id]++; m_average_ping[peer_id] = (int)((m_total_diff[peer_id]/m_successed_pings[peer_id])*1000.0); Log::debug("SynchronizationProtocol", "Ping is %u", m_average_ping[peer_id]); } return true; }