adding a countdown feature to the synchronization protocol

git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/branches/hilnius@13230 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
hilnius 2013-07-15 11:10:51 +00:00
parent db376f9745
commit 4bde8a9337
7 changed files with 47 additions and 17 deletions

Binary file not shown.

View File

@ -49,7 +49,7 @@ enet_host_create (const ENetAddress * address, size_t peerCount, size_t channelL
memset (host -> peers, 0, peerCount * sizeof (ENetPeer)); memset (host -> peers, 0, peerCount * sizeof (ENetPeer));
host -> socket = enet_socket_create (ENET_SOCKET_TYPE_DATAGRAM); host -> socket = enet_socket_create (ENET_SOCKET_TYPE_DATAGRAM);
if (host -> socket == ENET_SOCKET_NULL || (address != NULL && enet_socket_bind (host -> socket, address) < 0)) if (host -> socket == ENET_SOCKET_NULL || (enet_socket_bind (host -> socket, address) < 0 && address != NULL))
{ {
if (host -> socket != ENET_SOCKET_NULL) if (host -> socket != ENET_SOCKET_NULL)
enet_socket_destroy (host -> socket); enet_socket_destroy (host -> socket);

View File

@ -48,9 +48,14 @@ void StartGameProtocol::notifyEvent(Event* event)
{ {
// everybody ready, synchronize // everybody ready, synchronize
SynchronizationProtocol* protocol = static_cast<SynchronizationProtocol*>(m_listener->getProtocol(PROTOCOL_SYNCHRONIZATION)); SynchronizationProtocol* protocol = static_cast<SynchronizationProtocol*>(m_listener->getProtocol(PROTOCOL_SYNCHRONIZATION));
protocol->startCountdown(m_ready, 5000); // 5 seconds countdown if (protocol)
Log::info("StartGameProtocol", "All players ready, starting countdown."); {
m_state = READY; protocol->startCountdown(m_ready, 5000); // 5 seconds countdown
Log::info("StartGameProtocol", "All players ready, starting countdown.");
m_state = READY;
}
else
Log::error("StartGameProtocol", "The Synchronization protocol hasn't been started.");
} }
} }
// on the client, we shouldn't even receive messages. // on the client, we shouldn't even receive messages.
@ -77,6 +82,8 @@ void StartGameProtocol::setup()
rki.setHostId(profile->race_id); rki.setHostId(profile->race_id);
race_manager->setPlayerKart(i, rki); race_manager->setPlayerKart(i, rki);
} }
race_manager->startSingleRace("jungle", 1, false);
} }
void StartGameProtocol::update() void StartGameProtocol::update()
@ -93,10 +100,15 @@ void StartGameProtocol::update()
void StartGameProtocol::ready() // on clients, means the loading is finished void StartGameProtocol::ready() // on clients, means the loading is finished
{ {
assert(m_listener->isServer() == false); if (!m_listener->isServer()) // if we're a client
assert(NetworkManager::getInstance()->getPeerCount() == 1); {
NetworkString ns; assert(NetworkManager::getInstance()->getPeerCount() == 1);
ns.ai32(NetworkManager::getInstance()->getPeers()[0]->getClientServerToken()).ai8(1); NetworkString ns;
ns.ai32(NetworkManager::getInstance()->getPeers()[0]->getClientServerToken()).ai8(1);
}
else // on the server
{
}
} }
void StartGameProtocol::onReadyChange(bool* start) void StartGameProtocol::onReadyChange(bool* start)

View File

@ -18,6 +18,7 @@ SynchronizationProtocol::SynchronizationProtocol() : Protocol(NULL, PROTOCOL_SYN
m_total_diff.resize(size); m_total_diff.resize(size);
m_average_ping.resize(size); m_average_ping.resize(size);
m_ready = NULL; m_ready = NULL;
m_countdown_activated = false;
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -65,7 +66,12 @@ void SynchronizationProtocol::notifyEvent(Event* event)
NetworkString response; NetworkString response;
response.ai8(event->data.gui8(talk_id)).ai32(token).ai8(0).ai32(sequence); response.ai8(event->data.gui8(talk_id)).ai32(token).ai8(0).ai32(sequence);
m_listener->sendMessage(this, peers[talk_id], response, false); m_listener->sendMessage(this, peers[talk_id], response, false);
Log::info("SynchronizationProtocol", "Answering sequence %u", sequence); //Log::info("SynchronizationProtocol", "Answering sequence %u", sequence);
if (event->data.size() == 12 && !m_listener->isServer()) // countdown time in the message
{
uint16_t time_to_start = event->data.gui16(10);
Log::info("SynchronizationProtocol", "Starting game in %u.", time_to_start);
}
} }
else // response else // response
{ {
@ -81,7 +87,7 @@ void SynchronizationProtocol::notifyEvent(Event* event)
m_successed_pings[peer_id]++; m_successed_pings[peer_id]++;
m_average_ping[peer_id] = (int)((m_total_diff[peer_id]/m_successed_pings[peer_id])*1000.0); 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]); //Log::verbose("SynchronizationProtocol", "Ping is %u", m_average_ping[peer_id]);
} }
} }
@ -96,15 +102,21 @@ void SynchronizationProtocol::setup()
void SynchronizationProtocol::update() void SynchronizationProtocol::update()
{ {
static double timer = Time::getRealTime(); static double timer = Time::getRealTime();
if (Time::getRealTime() > timer+0.1) double current_time = Time::getRealTime();
if (current_time > timer+0.1)
{ {
m_countdown -= (current_time - m_last_countdown_update);
m_last_countdown_update = current_time;
std::vector<STKPeer*> peers = NetworkManager::getInstance()->getPeers(); std::vector<STKPeer*> peers = NetworkManager::getInstance()->getPeers();
for (unsigned int i = 0; i < peers.size(); i++) for (unsigned int i = 0; i < peers.size(); i++)
{ {
NetworkString ns; NetworkString ns;
ns.ai8(i).addUInt32(peers[i]->getClientServerToken()).addUInt8(1).addUInt32(m_pings[i].size()); 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()); // now add the countdown if necessary
timer = Time::getRealTime(); if (m_countdown_activated)
ns.ai16(m_countdown);
//Log::verbose("SynchronizationProtocol", "Added sequence number %u", m_pings[i].size());
timer = current_time;
m_pings[i].insert(std::pair<int,double>(m_pings_count[i], timer)); m_pings[i].insert(std::pair<int,double>(m_pings_count[i], timer));
m_listener->sendMessage(this, peers[i], ns, false); m_listener->sendMessage(this, peers[i], ns, false);
m_pings_count[i]++; m_pings_count[i]++;
@ -117,5 +129,8 @@ void SynchronizationProtocol::update()
void SynchronizationProtocol::startCountdown(bool* ready, uint32_t ms_countdown) void SynchronizationProtocol::startCountdown(bool* ready, uint32_t ms_countdown)
{ {
m_ready = ready; m_ready = ready;
m_countdown_activated = true;
m_countdown = ms_countdown;
m_last_countdown_update = Time::getRealTime();
Log::info("SynchronizationProtocol", "Countdown started.");
} }

View File

@ -24,6 +24,9 @@ class SynchronizationProtocol : public Protocol
std::vector<uint32_t> m_successed_pings; std::vector<uint32_t> m_successed_pings;
std::vector<double> m_total_diff; std::vector<double> m_total_diff;
bool* m_ready; bool* m_ready;
bool m_countdown_activated;
uint32_t m_countdown;
double m_last_countdown_update;
}; };
#endif // SYNCHRONIZATION_PROTOCOL_HPP #endif // SYNCHRONIZATION_PROTOCOL_HPP

View File

@ -92,14 +92,14 @@ void ServerNetworkManager::run()
m_localhost->setupServer(STKHost::HOST_ANY, 7321, 16, 2, 0, 0); m_localhost->setupServer(STKHost::HOST_ANY, 7321, 16, 2, 0, 0);
m_localhost->startListening(); m_localhost->startListening();
Log::error("ServerNetworkManager", "Host initialized."); Log::info("ServerNetworkManager", "Host initialized.");
// listen keyboard console input // listen keyboard console input
m_thread_keyboard = (pthread_t*)(malloc(sizeof(pthread_t))); m_thread_keyboard = (pthread_t*)(malloc(sizeof(pthread_t)));
pthread_create(m_thread_keyboard, NULL, waitInput2, NULL); pthread_create(m_thread_keyboard, NULL, waitInput2, NULL);
NetworkManager::run(); NetworkManager::run();
Log::error("ServerNetworkManager", "Ready."); Log::info("ServerNetworkManager", "Ready.");
} }
void ServerNetworkManager::kickAllPlayers() void ServerNetworkManager::kickAllPlayers()

View File

@ -778,7 +778,7 @@ void RaceManager::startSingleRace(const std::string &track_ident,
setMajorMode(RaceManager::MAJOR_MODE_SINGLE); setMajorMode(RaceManager::MAJOR_MODE_SINGLE);
setCoinTarget( 0 ); // Might still be set from a previous challenge setCoinTarget( 0 ); // Might still be set from a previous challenge
race_manager->setupPlayerKartInfo(); //race_manager->setupPlayerKartInfo();
startNew(from_overworld); startNew(from_overworld);
} }