adding a protocol to start a game, added features in the synchronization protocol
git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/branches/hilnius@13215 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
parent
75df500884
commit
c50a24a25d
Binary file not shown.
@ -37,8 +37,6 @@ void* waitInput(void* data)
|
||||
std::string str = "";
|
||||
bool stop = false;
|
||||
int n = 0;
|
||||
bool success = false;
|
||||
uint32_t ping = 0;
|
||||
|
||||
while(!stop)
|
||||
{
|
||||
@ -69,7 +67,7 @@ void* waitInput(void* data)
|
||||
}
|
||||
else if (str == "synchronize")
|
||||
{
|
||||
ProtocolManager::getInstance()->requestStart(new SynchronizationProtocol(&ping, &success));
|
||||
ProtocolManager::getInstance()->requestStart(new SynchronizationProtocol());
|
||||
}
|
||||
else if (NetworkManager::getInstance()->getPeers().size() > 0)
|
||||
{
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "network/protocols/client_lobby_room_protocol.hpp"
|
||||
|
||||
#include "network/network_manager.hpp"
|
||||
#include "network/protocols/start_game_protocol.hpp"
|
||||
#include "online/current_online_user.hpp"
|
||||
#include "utils/log.hpp"
|
||||
|
||||
@ -70,6 +71,8 @@ void ClientLobbyRoomProtocol::notifyEvent(Event* event)
|
||||
disconnectedPlayer(event);
|
||||
else if (message_type == 0x03) // kart selection update
|
||||
kartSelectionUpdate(event);
|
||||
else if (message_type == 0x04) // start race
|
||||
startGame(event);
|
||||
else if (message_type == 0x80) // connection refused
|
||||
connectionRefused(event);
|
||||
else if (message_type == 0x81) // connection accepted
|
||||
@ -357,3 +360,33 @@ void ClientLobbyRoomProtocol::kartSelectionUpdate(Event* event)
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/*! \brief Called when the race needs to be started.
|
||||
* \param event : Event providing the information.
|
||||
*
|
||||
* Format of the data :
|
||||
* Byte 0 1 5
|
||||
* -------------
|
||||
* Size | 1 | 4 |
|
||||
* Data | 4 | token |
|
||||
* -------------
|
||||
*/
|
||||
void ClientLobbyRoomProtocol::startGame(Event* event)
|
||||
{
|
||||
if (event->data.size() < 5 || event->data[0] != 4)
|
||||
{
|
||||
Log::error("ClientLobbyRoomProtocol", "A message notifying a kart "
|
||||
"selection update wasn't formated as expected.");
|
||||
return;
|
||||
}
|
||||
uint8_t token = event->data.gui32(1);
|
||||
if (token == NetworkManager::getInstance()->getPeers()[0]->getClientServerToken())
|
||||
{
|
||||
m_listener->requestStart(new StartGameProtocol(m_setup));
|
||||
}
|
||||
else
|
||||
Log::error("ClientLobbyRoomProtocol", "Bad token when starting game");
|
||||
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -24,6 +24,7 @@ class ClientLobbyRoomProtocol : public LobbyRoomProtocol
|
||||
void connectionRefused(Event* event); //!< Callback function on connection refusal
|
||||
void kartSelectionRefused(Event* event);
|
||||
void kartSelectionUpdate(Event* event);
|
||||
void startGame(Event* event);
|
||||
|
||||
TransportAddress m_server_address;
|
||||
STKPeer* m_server;
|
||||
|
@ -159,6 +159,19 @@ void ServerLobbyRoomProtocol::update()
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void ServerLobbyRoomProtocol::kartDisconnected(Event* event)
|
||||
|
@ -13,6 +13,8 @@ class ServerLobbyRoomProtocol : public LobbyRoomProtocol
|
||||
virtual void setup();
|
||||
virtual void update();
|
||||
|
||||
void startGame();
|
||||
|
||||
protected:
|
||||
void kartDisconnected(Event* event);
|
||||
void connectionRequested(Event* event);
|
||||
|
@ -1,6 +1,12 @@
|
||||
#include "network/protocols/start_game_protocol.hpp"
|
||||
|
||||
#include "network/network_manager.hpp"
|
||||
#include "network/protocol_manager.hpp"
|
||||
#include "network/game_setup.hpp"
|
||||
#include "network/protocols/synchronization_protocol.hpp"
|
||||
#include "race/race_manager.hpp"
|
||||
#include "utils/log.hpp"
|
||||
#include "utils/time.hpp"
|
||||
|
||||
StartGameProtocol::StartGameProtocol(GameSetup* game_setup) :
|
||||
Protocol(NULL, PROTOCOL_START_GAME)
|
||||
@ -9,8 +15,10 @@ StartGameProtocol::StartGameProtocol(GameSetup* game_setup) :
|
||||
std::vector<NetworkPlayerProfile*> players = m_game_setup->getPlayers();
|
||||
for (unsigned int i = 0; i < players.size(); i++)
|
||||
{
|
||||
m_player_states.push_back(std::pair<NetworkPlayerProfile*, STATE>(players[i], LOADING));
|
||||
m_player_states.insert(std::pair<NetworkPlayerProfile*, STATE>(players[i], LOADING));
|
||||
}
|
||||
m_ready_count = 0;
|
||||
m_ready = NULL;
|
||||
}
|
||||
|
||||
StartGameProtocol::~StartGameProtocol()
|
||||
@ -19,19 +27,78 @@ StartGameProtocol::~StartGameProtocol()
|
||||
|
||||
void StartGameProtocol::notifyEvent(Event* event)
|
||||
{
|
||||
if (event->data.size() < 5)
|
||||
{
|
||||
Log::error("StartGameProtocol", "Too short message.");
|
||||
return;
|
||||
}
|
||||
uint32_t token = event->data.gui32(0);
|
||||
uint8_t ready = event->data.gui8(4);
|
||||
STKPeer* peer = (*(event->peer));
|
||||
if (peer->getClientServerToken() != token)
|
||||
{
|
||||
Log::error("StartGameProtocol", "Bad token received.");
|
||||
return;
|
||||
}
|
||||
if (m_listener->isServer() && ready) // on server, player 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));
|
||||
protocol->startCountdown(m_ready, 5000); // 5 seconds countdown
|
||||
Log::info("StartGameProtocol", "All players ready, starting countdown.");
|
||||
m_state = READY;
|
||||
}
|
||||
}
|
||||
// on the client, we shouldn't even receive messages.
|
||||
}
|
||||
|
||||
void StartGameProtocol::setup()
|
||||
{
|
||||
m_state = LOADING;
|
||||
race_manager->setNumKarts(m_game_setup->getPlayerCount());
|
||||
race_manager->setNumPlayers(m_game_setup->getPlayerCount());
|
||||
race_manager->setNumLocalPlayers(1);
|
||||
std::vector<NetworkPlayerProfile*> players = m_game_setup->getPlayers();
|
||||
for (unsigned int i = 0; i < players.size(); i++)
|
||||
{
|
||||
NetworkPlayerProfile* profile = players[i];
|
||||
RemoteKartInfo rki(profile->race_id, profile->kart_name, profile->user_profile->getUserName(), profile->race_id);
|
||||
rki.setGlobalPlayerId(profile->race_id);
|
||||
rki.setLocalPlayerId(profile->race_id);
|
||||
rki.setHostId(profile->race_id);
|
||||
race_manager->setPlayerKart(i, rki);
|
||||
}
|
||||
// if no synchronization protocol exists, create one
|
||||
SynchronizationProtocol* protocol = static_cast<SynchronizationProtocol*>(m_listener->getProtocol(PROTOCOL_SYNCHRONIZATION));
|
||||
if (!protocol)
|
||||
m_listener->requestStart(new SynchronizationProtocol());
|
||||
}
|
||||
|
||||
void StartGameProtocol::update()
|
||||
{
|
||||
if (m_state == LOADING)
|
||||
{
|
||||
|
||||
}
|
||||
else if (m_state == READY)
|
||||
{
|
||||
m_listener->requestTerminate(this);
|
||||
}
|
||||
}
|
||||
|
||||
void StartGameProtocol::ready() // on clients, means the loading is finished
|
||||
{
|
||||
assert(m_listener->isServer() == false);
|
||||
assert(NetworkManager::getInstance()->getPeerCount() == 1);
|
||||
NetworkString ns;
|
||||
ns.ai32(NetworkManager::getInstance()->getPeers()[0]->getClientServerToken()).ai8(1);
|
||||
}
|
||||
|
||||
void StartGameProtocol::onReadyChange(bool* start)
|
||||
{
|
||||
m_ready = start;
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
#define START_GAME_PROTOCOL_HPP
|
||||
|
||||
#include "network/protocol.hpp"
|
||||
#include <map>
|
||||
|
||||
class GameSetup;
|
||||
class NetworkPlayerProfile;
|
||||
@ -10,9 +11,12 @@ class StartGameProtocol : public Protocol
|
||||
{
|
||||
protected:
|
||||
enum STATE { LOADING, READY };
|
||||
std::vector<std::pair<NetworkPlayerProfile*, STATE> > m_player_states;
|
||||
std::map<NetworkPlayerProfile*, STATE> m_player_states;
|
||||
|
||||
GameSetup* m_game_setup;
|
||||
bool* m_ready; //!< Set to true when the game can start
|
||||
int m_ready_count;
|
||||
double m_sending_time;
|
||||
|
||||
STATE m_state;
|
||||
|
||||
@ -24,6 +28,9 @@ class StartGameProtocol : public Protocol
|
||||
virtual void setup();
|
||||
virtual void update();
|
||||
|
||||
void ready();
|
||||
void onReadyChange(bool* start);
|
||||
|
||||
};
|
||||
|
||||
#endif // START_GAME_PROTOCOL_HPP
|
||||
|
@ -5,14 +5,19 @@
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
SynchronizationProtocol::SynchronizationProtocol(uint32_t* ping, bool* successed) : Protocol(NULL, PROTOCOL_SYNCHRONIZATION)
|
||||
SynchronizationProtocol::SynchronizationProtocol() : Protocol(NULL, PROTOCOL_SYNCHRONIZATION)
|
||||
{
|
||||
m_average_ping = ping;
|
||||
m_successed = successed;
|
||||
m_pings.resize(NetworkManager::getInstance()->getPeerCount(), std::vector<std::pair<double,double> >(0));
|
||||
m_pings_count = 0;
|
||||
m_successed_pings = 0;
|
||||
m_total_diff = 0;
|
||||
unsigned int size = NetworkManager::getInstance()->getPeerCount();
|
||||
m_pings.resize(size, std::map<uint32_t,double>());
|
||||
m_pings_count.resize(size);
|
||||
for (unsigned int i = 0; i < size; i++)
|
||||
{
|
||||
m_pings_count[i] = 0;
|
||||
}
|
||||
m_successed_pings.resize(size);
|
||||
m_total_diff.resize(size);
|
||||
m_average_ping.resize(size);
|
||||
m_ready = NULL;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -69,16 +74,14 @@ void SynchronizationProtocol::notifyEvent(Event* event)
|
||||
Log::warn("SynchronizationProtocol", "The sequence# %u isn't known.", sequence);
|
||||
return;
|
||||
}
|
||||
m_pings[peer_id][sequence].second = Time::getRealTime();
|
||||
m_total_diff += (m_pings[peer_id][sequence].second - m_pings[peer_id][sequence].first);
|
||||
Log::verbose("SynchronizationProtocol", "InstantPing is %u", (unsigned int)((m_pings[peer_id][sequence].second - m_pings[peer_id][sequence].first)*1000));
|
||||
m_successed_pings++;
|
||||
*m_average_ping = (int)((m_total_diff/m_successed_pings)*1000.0);
|
||||
if ( *m_successed == false && m_successed_pings > 5)
|
||||
{
|
||||
*m_successed = true; // success after 5 pings (we have good idea of ping)
|
||||
}
|
||||
Log::verbose("SynchronizationProtocol", "Ping is %u", *m_average_ping);
|
||||
double current_time = Time::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::verbose("SynchronizationProtocol", "Ping is %u", m_average_ping[peer_id]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -93,7 +96,7 @@ void SynchronizationProtocol::setup()
|
||||
void SynchronizationProtocol::update()
|
||||
{
|
||||
static double timer = Time::getRealTime();
|
||||
if (Time::getRealTime() > timer+0.1 && m_pings_count < 100) // max 100 pings (10 seconds)
|
||||
if (Time::getRealTime() > timer+0.1)
|
||||
{
|
||||
std::vector<STKPeer*> peers = NetworkManager::getInstance()->getPeers();
|
||||
for (unsigned int i = 0; i < peers.size(); i++)
|
||||
@ -102,11 +105,17 @@ void SynchronizationProtocol::update()
|
||||
ns.ai8(i).addUInt32(peers[i]->getClientServerToken()).addUInt8(1).addUInt32(m_pings[i].size());
|
||||
Log::verbose("SynchronizationProtocol", "Added sequence number %u", m_pings[i].size());
|
||||
timer = Time::getRealTime();
|
||||
m_pings[i].push_back(std::pair<double, double>(timer, 0.0));
|
||||
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]++;
|
||||
}
|
||||
m_pings_count++;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SynchronizationProtocol::startCountdown(bool* ready, uint32_t ms_countdown)
|
||||
{
|
||||
m_ready = ready;
|
||||
|
||||
}
|
||||
|
@ -2,27 +2,28 @@
|
||||
#define SYNCHRONIZATION_PROTOCOL_HPP
|
||||
|
||||
#include "network/protocol.hpp"
|
||||
#include <list>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
class SynchronizationProtocol : public Protocol
|
||||
{
|
||||
public:
|
||||
SynchronizationProtocol(uint32_t* ping, bool* successed);
|
||||
SynchronizationProtocol();
|
||||
virtual ~SynchronizationProtocol();
|
||||
|
||||
virtual void notifyEvent(Event* event);
|
||||
virtual void setup();
|
||||
virtual void update();
|
||||
|
||||
void startCountdown(bool* ready, uint32_t ms_countdown);
|
||||
|
||||
protected:
|
||||
//!< stores the start time / arrival time of packets for each peer
|
||||
std::vector<std::vector<std::pair<double, double> > > m_pings;
|
||||
uint32_t* m_average_ping;
|
||||
uint32_t m_pings_count;
|
||||
uint32_t m_successed_pings;
|
||||
double m_total_diff;
|
||||
bool* m_successed;
|
||||
std::vector<std::map<uint32_t, double> > m_pings;
|
||||
std::vector<uint32_t> m_average_ping;
|
||||
std::vector<uint32_t> m_pings_count;
|
||||
std::vector<uint32_t> m_successed_pings;
|
||||
std::vector<double> m_total_diff;
|
||||
bool* m_ready;
|
||||
};
|
||||
|
||||
#endif // SYNCHRONIZATION_PROTOCOL_HPP
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "network/protocols/get_peer_address.hpp"
|
||||
#include "network/protocols/connect_to_server.hpp"
|
||||
#include "network/protocols/stop_server.hpp"
|
||||
#include "network/protocols/server_lobby_room_protocol.hpp"
|
||||
|
||||
#include "main_loop.hpp"
|
||||
#include "utils/log.hpp"
|
||||
@ -49,6 +50,12 @@ void* waitInput2(void* data)
|
||||
{
|
||||
ServerNetworkManager::getInstance()->kickAllPlayers();
|
||||
}
|
||||
else if (str == "start")
|
||||
{
|
||||
ServerLobbyRoomProtocol* protocol = static_cast<ServerLobbyRoomProtocol*>(ProtocolManager::getInstance()->getProtocol(PROTOCOL_LOBBY_ROOM));
|
||||
assert(protocol);
|
||||
protocol->startGame();
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t id = ProtocolManager::getInstance()->requestStart(new StopServer());
|
||||
|
@ -42,6 +42,8 @@
|
||||
#include "modes/world.hpp"
|
||||
#include "modes/three_strikes_battle.hpp"
|
||||
#include "modes/soccer_world.hpp"
|
||||
#include "network/protocol_manager.hpp"
|
||||
#include "network/protocols/start_game_protocol.hpp"
|
||||
#include "states_screens/grand_prix_lose.hpp"
|
||||
#include "states_screens/grand_prix_win.hpp"
|
||||
#include "states_screens/kart_selection.hpp"
|
||||
@ -460,6 +462,17 @@ void RaceManager::startNextRace()
|
||||
m_kart_status[i].m_last_time = 0;
|
||||
}
|
||||
|
||||
StartGameProtocol* protocol = static_cast<StartGameProtocol*>(
|
||||
ProtocolManager::getInstance()->getProtocol(PROTOCOL_START_GAME));
|
||||
if (protocol) // if this protocol exists, that's that we play online
|
||||
{
|
||||
bool ready = false;
|
||||
protocol->ready();
|
||||
protocol->onReadyChange(&ready);
|
||||
while(!ready) // wait the protocol to say we can start
|
||||
{
|
||||
}
|
||||
}
|
||||
} // startNextRace
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -775,23 +788,23 @@ void RaceManager::startSingleRace(const std::string &track_ident,
|
||||
*/
|
||||
void RaceManager::setupPlayerKartInfo()
|
||||
{
|
||||
std::vector<RemoteKartInfo> m_kart_info;
|
||||
std::vector<RemoteKartInfo> kart_info;
|
||||
|
||||
// Get the local kart info
|
||||
for(unsigned int i=0; i<getNumLocalPlayers(); i++)
|
||||
m_kart_info.push_back(getLocalKartInfo(i));
|
||||
kart_info.push_back(getLocalKartInfo(i));
|
||||
|
||||
// Now sort by (hostid, playerid)
|
||||
std::sort(m_kart_info.begin(), m_kart_info.end());
|
||||
std::sort(kart_info.begin(), kart_info.end());
|
||||
|
||||
// Set the player kart information
|
||||
setNumPlayers(m_kart_info.size());
|
||||
setNumPlayers(kart_info.size());
|
||||
|
||||
// Set the global player ID for each player
|
||||
for(unsigned int i=0; i<m_kart_info.size(); i++)
|
||||
for(unsigned int i=0; i<kart_info.size(); i++)
|
||||
{
|
||||
m_kart_info[i].setGlobalPlayerId(i);
|
||||
setPlayerKart(i, m_kart_info[i]);
|
||||
kart_info[i].setGlobalPlayerId(i);
|
||||
setPlayerKart(i, kart_info[i]);
|
||||
}
|
||||
|
||||
computeRandomKartList();
|
||||
|
Loading…
Reference in New Issue
Block a user