/* core/gameconnection.cc This file is part of the Osirion project and is distributed under the terms of the GNU General Public License version 2 */ #include #include #include "sys/sys.h" #include "core/cvar.h" #include "core/gameconnection.h" #include "core/net.h" namespace core { const unsigned long INFOTIMEOUT = 2500; // 2500ms info request timeout GameConnection* GameConnection::connection_instance = 0; GameConnection::GameConnection(std::string const &connectionstr) { connection_instance = this; connection_network = 0; connection_running = false; connection_timestamp = 0; connection_netframe = 0; unsigned int port = DEFAULTPORT; std::string host(connectionstr); size_t found = host.find(':'); if (found != std::string::npos) { std::istringstream str(host.substr(found + 1)); if (str >> port) { host.erase(found, std::string::npos); } else { con_print << "Invalid hostname '" << host << "'\n"; abort(); return; } } connection_network = new NetConnection(); connection_network->connect(host, port); if (!connection_network->connected()) { abort(); return; } // send connect request connection_network->send_connect(); connection_network->transmit(); if (!connection_network->connected()) { abort(); return; } game_players.push_back(localplayer()); connection_running = true; } GameConnection::~GameConnection() { if (connection_network) { connection_network->disconnect(); delete connection_network; } connection_instance = 0; } unsigned long GameConnection::timestamp() const { return connection_timestamp; } float GameConnection::time() const { return ((float)(connection_timestamp) / 1000.0f); } bool GameConnection::interactive() const { return true; } Info *GameConnection::info(unsigned int id) { if (!id) { con_warn << "Information requested for illegal id 0!" << std::endl; return 0; } // find the info record Info *info = Info::find(id); if (!info) { info = new Info(id); } if ( !info->timestamp() || (connection_timestamp < info->timestamp() + INFOTIMEOUT) ) return info; // send an information request to the server if (connection_network) { info->set_timestamp(connection_timestamp); connection_network->send_info_request(info); connection_network->transmit(); } else { info->add_text("^RNot connected."); info->set_timestamp(0); } return info; } /* Info *GameConnection::info(const std::string &type, const std::string &label) { if (!type.size()) { con_warn << "Information requested with empty type label!" << std::endl; return 0; } if (!label.size()) { con_warn << "Information requested with empty label!" << std::endl; return 0; } // find the info record type InfoType *infotype = InfoType::find(type); if (!infotype) { // create a new info record type and set the label infotype = new InfoType(type.c_str()); } // find the info record Info *info = Info::find(infotype, label); if (info) { if (!info->timestamp() || (connection_timestamp - info->timestamp()) < INFOTIMEOUT) return info; } else { // create a new info record and set the label info = new Info(infotype, label); info->add_text("Requesting information..."); } // send an information request to the server if (connection_network) { //con_debug << "Requesting info for " << info->type()->label() << ":" << info->label() << std::endl; info->set_timestamp(connection_timestamp); connection_network->send_info_request(info); connection_network->transmit(); } else { info->add_text("^RNot connected."); info->set_timestamp(0); } return info; } */ void GameConnection::abort() { connection_running = false; } void GameConnection::forward(std::string const &cmdline) { if (!connection_network->connected()) return; connection_network->send_command(cmdline); } void GameConnection::rcon(std::string const &cmdline) { if (!connection_network->connected()) return; connection_network->send_rcon(cmdline); } void GameConnection::say(std::string const &args) { if (!connection_network->connected()) return; connection_network->send_say(args); } void GameConnection::private_message(std::string const &args) { if (!connection_network->connected()) return; connection_network->send_private_message(args); } void GameConnection::frame(unsigned long timestamp) { if (!running()) return; if (!connection_network->connected()) { abort(); return; } //update_clientstate(); // get incoming messages connection_network->frame(); float f = 0; if (core::Cvar::net_framerate->value()) { f = 1000.0f / core::Cvar::net_framerate->value(); if (connection_netframe + f > timestamp) { return; } } connection_netframe = timestamp; if (connection_network->state() == NetConnection::Connected) { if (localcontrol() && localcontrol()->dirty()) { connection_network->send_client_update(localcontrol()); localcontrol()->set_dirty(false); } if (localplayer()->dirty()) { connection_network->send_playerinfo(); } } connection_timestamp = connection_network->timestamp(); connection_network->transmit(); } }