From 1c63cbf204b1d2c667ce9f821ccb197d0ffb0ac3 Mon Sep 17 00:00:00 2001 From: Stijn Buys Date: Wed, 11 May 2011 14:48:17 +0000 Subject: Review of the main loop timer, converted timers from float to unsigned long, corrected a number of timing bugs, improved client framerate stability. --- src/core/gameserver.cc | 83 +++++++++++++++++++++++++++++++++++++------------- 1 file changed, 61 insertions(+), 22 deletions(-) (limited to 'src/core/gameserver.cc') diff --git a/src/core/gameserver.cc b/src/core/gameserver.cc index 85a956d..58367e5 100644 --- a/src/core/gameserver.cc +++ b/src/core/gameserver.cc @@ -39,17 +39,42 @@ void func_who(std::string const &args) void func_time(std::string const &args) { - using namespace std; + using namespace std; - // FIXME unify with dedicated server clock - int minutes = (int) floorf(server()->time() / 60.0f); - int seconds = (int) floorf(server()->time() - (float) minutes * 60.0f); - - int syshours, sysminutes, sysseconds; - sys::get_localtime(syshours, sysminutes, sysseconds); - - con_print << "Uptime " << minutes << ":" << setfill('0') << setw(2) << seconds << - " Local time " << setfill(' ') << setw(2) << syshours << ":" << setfill('0') << setw(2) << sysminutes << ":" << setw(2) << sysseconds << setfill(' ') << std::endl; + // system time + int year = 0, month = 0, day = 0, hour = 0, min = 0, sec = 0, milliseconds = 0; + sys::get_localtime(year, month, day, hour, min, sec, milliseconds); + + con_print << "Local time: " + << std::setw(4) << std::setfill('0') << year << "-" + << std::setw(2) << std::setfill('0') << month << "-" + << std::setw(2) << std::setfill('0') << day << " " + << std::setw(2) << hour << ":" + << std::setw(2) << min << ":" + << std::setw(2) << sec << " " + << std::setw(2) << " "; + + // uptime + float uptime = core::game()->time(); + + const int uptime_days = (int) floorf(uptime / (24.0f * 3600.0f)); + uptime -= uptime_days * 24.0f * 3600.0f; + + const int uptime_hours = (int) floorf(uptime / 3600.0f); + uptime -= uptime_hours * 3600.0f; + + const int uptime_minutes = (int) floorf(uptime / 60.0f); + uptime -= uptime_minutes * 60.0f; + + const int uptime_seconds = (int) floorf(uptime); + + con_print << " Uptime: "; + if (uptime_days > 0) { + con_print << uptime_days << " " << aux::plural("day", uptime_days); + } + con_print << std::setfill('0') << std::setw(2) << uptime_hours << ":" + << std::setfill('0') << std::setw(2) << uptime_minutes << ":" + << std::setfill('0') << std::setw(2) << uptime_seconds << std::endl; } void func_mute(std::string const &args) @@ -126,7 +151,6 @@ GameServer::GameServer() : GameInterface() server_network = 0; server_previoustime = 0; server_maxplayerid = 1; - server_startup = application()->timestamp(); // create the default infotype for entities Entity::set_infotype(new InfoType("entity")); @@ -196,7 +220,10 @@ GameServer::GameServer() : GameInterface() if (!Cvar::sv_dedicated->value()) { player_connect(localplayer()); } - + + set_timestamp(server_timer.timestamp()); + server_previoustime = timestamp(); + set_running(true); } @@ -471,7 +498,7 @@ void GameServer::player_connect(Player *player) // manage player list game_players.push_back(player); - set_playerlist_timestamp(timestamp()); + set_playerlist_timestamp(server_timer.timestamp()); } void GameServer::player_disconnect(Player *player) @@ -489,16 +516,16 @@ void GameServer::player_disconnect(Player *player) // manage player list std::list:: iterator it = game_players.begin(); - while (((*it)->id() != player->id()) && (it != game_players.end())) { + while ((it != game_players.end()) && ((*it)->id() != player->id())) { it++; } if (it != game_players.end()) { game_players.erase(it); } - set_playerlist_timestamp(timestamp()); + set_playerlist_timestamp(server_timer.timestamp()); } -void GameServer::frame(unsigned long timestamp) +void GameServer::frame(const unsigned long timestamp) { if (error()) return; @@ -519,24 +546,36 @@ void GameServer::frame(unsigned long timestamp) /*if (!Cvar::sv_dedicated->value()) { update_clientstate(); }*/ - - Physics::frame(timestamp); if ((Cvar::sv_dedicated->value() || Cvar::sv_private->value())) { if (core::Cvar::sv_framerate->value()) { - float fps = ::floorf(1000.0f / core::Cvar::sv_framerate->value()); - if (server_startup + this->timestamp() + (unsigned long) fps > timestamp) { + + const unsigned long server_framelength = (unsigned long) ::floorf(1000.0f / core::Cvar::sv_framerate->value()); + + if (server_timer.timestamp() < server_previoustime + server_framelength) { return; } } } server_previoustime = this->timestamp(); - set_timestamp(timestamp - server_startup); + set_timestamp(server_timer.timestamp()); + + if (server_network) { + server_network->transmit(); + + if (server_network->error()) { + abort(); + return; + } + } - const float elapsed = (float)(this->timestamp() - server_previoustime) / 1000.0f; + const unsigned long elapsed = (this->timestamp() - server_previoustime); const unsigned long keepalive_timeout = (Cvar::sv_keepalive ? 1000 * (unsigned long) Cvar::sv_keepalive->value() : (unsigned long) 0 ); + // run a physics frame + Physics::frame(elapsed); + // reset zone keepalive state for (Zone::Registry::iterator zit = Zone::registry().begin(); zit != Zone::registry().end(); zit++) { Zone *zone= (*zit).second; -- cgit v1.2.3