/* core/application.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 #include #include #include #include "sys/sys.h" #include "math/mathlib.h" #include "filesystem/filesystem.h" #include "core/application.h" #include "core/cvar.h" #include "core/entity.h" #include "core/func.h" #include "core/gameconnection.h" #include "core/gameserver.h" namespace core { // --------------- engine functions ------------------------------ void func_print(std::string const &args) { con_print << args << "\n"; } void func_help(std::string const &args) { con_print << "This is the help function\n"; } void func_quit(std::string const &args) { application()->shutdown(); application()->quit(0); } void func_connect(std::string const &args) { std::istringstream argstream(args); std::string host; if (!(argstream >> host)) host.clear(); application()->connect(host); } void func_disconnect(std::string const &args) { application()->disconnect(); } /* void func_name(std::string const &args) { std::istringstream argstream(args); std::string name; if (argstream >> name) { if (name.size() > 16) name = name.substr(0,16); } else { con_print << "name " << Player::local.name() << "\n"; return; } if (name == Player::local.name()) { con_print << "name " << name << "\n"; return; } if (application()->netserver) { std::ostringstream osstream; osstream << "msg info " << Player::local.name() << " renamed to " << name << "\n"; application()->netserver->broadcast(osstream.str()); con_print << "msg info " << Player::local.name() << " renamed to " << name << "\n"; } else if (application()->netconnection.connected()) { std::ostringstream osstream; osstream << "name " << name << "\n"; application()->netconnection.send(osstream.str()); con_print << "name " << name << "\n"; } else { con_print << "name " << name << "\n"; } Player::local.player_name = name; } */ // --------------- signal_handler ----------------------------------- extern "C" void signal_handler(int signum) { switch (signum) { case SIGHUP: case SIGINT: case SIGQUIT: case SIGTERM: if (Application::instance()) { con_warn << "Received signal " << signum << ", shutting down...\n"; application()->shutdown(); application()->quit(0); } else { std::cerr << "Received signal " << signum << ", terminated...\n"; application()->quit(1); } break; default: std::cerr << "Received signal " << signum << ", terminated...\n"; application()->quit(1); break; } } // --------------- Application ----------------------------- Application *Application::application_instance = 0; Application::Application() { if (application_instance) { std::cerr << "multiple core::Application instances!\n"; sys::quit(2); } application_instance = this; application_time = 0; application_game = 0; sys::signal(SIGHUP, signal_handler); sys::signal(SIGINT, signal_handler); sys::signal(SIGQUIT, signal_handler); sys::signal(SIGTERM, signal_handler); } Application::~Application() { application_instance = 0; } void Application::init() { con_debug << "Debug messages enabled\n"; con_print << "Initializing core...\n"; filesystem::init(); CommandBuffer::init(); // dedicated server has set this to 1 Cvar::sv_dedicated = Cvar::get("sv_dedicated", "0", Cvar::ReadOnly); // client can set this to 1 Cvar::sv_private = Cvar::get("sv_private", "0"); // load save cvars load_config(); // framerate settings Cvar::sv_framerate = Cvar::get("sv_framerate", "25"); // network settings Cvar::net_host = Cvar::get("net_host", "0.0.0.0", Cvar::Archive); Cvar::net_port = Cvar::get("net_port", "8042", Cvar::Archive); Cvar::net_maxclients = Cvar::get("net_maxclients", "16", Cvar::Archive); // register our engine functions Func::add("print", func_print); Func::add("help", func_help); Func::add("quit", func_quit); Func::add("connect", func_connect); Func::add("disconnect", func_disconnect); //Func::add("name", func_name); } void Application::shutdown() { con_print << "Shutting down core...\n"; if (connected()) disconnect(); if (application_game) { delete application_game; application_game = 0; } save_config(); // remove our engine functions Func::remove("print"); Func::remove("help"); Func::remove("quit"); Func::remove("connect"); Func::remove("disconnect"); //Func::remove("name"); CommandBuffer::shutdown(); filesystem::shutdown(); } void Application::quit(int status) { sys::quit(status); } void Application::connect(std::string const &host) { if (connected()) { con_warn << "Connected. Disconnect first.\n"; return; } if (application_game) { delete application_game; application_game = 0; } if (host.size()) { application_game = new GameConnection(host); if (!application_game->running()) { delete application_game; application_game = 0; } } else { application_game = new GameServer(); if (application_game->running()) { con_print << "Connected to local game.\n"; } else { delete application_game; application_game = 0; con_warn << "Could not connect to local game!\n"; } } } void Application::disconnect() { if(application_game) { delete application_game; application_game = 0; con_print << "Disconnected.\n"; } } void Application::frame(float seconds) { // execute commands in the buffer CommandBuffer::exec(); application_time += seconds; // don't run zero lenght time frames if (seconds == 0.0f) return; if (!connected()) return; // run a game interface frame application_game->frame(seconds); if (!application_game->running()) disconnect(); } void Application::save_config() { std::string filename(filesystem::writedir); if (!Cvar::sv_dedicated->value()) filename.append("client.cfg"); else filename.append("server.cfg"); std::ofstream ofs(filename.c_str()); if (!ofs.is_open()) { con_warn << "Could not write " << filename << std::endl; return; } std::map::iterator it; for (it = Cvar::registry.begin(); it != Cvar::registry.end(); it++) { if (((*it).second->flags() & Cvar::Archive) == Cvar::Archive) ofs << "set " << (*it).first << " " << (*it).second->str() << std::endl; } ofs.close(); } void Application::load_config() { std::string filename(filesystem::writedir); if (!Cvar::sv_dedicated->value()) filename.append("client.cfg"); else filename.append("server.cfg"); std::ifstream ifs(filename.c_str(), std::ifstream::in); if (!ifs.is_open()) { con_warn << "Could not read " << filename << std::endl; return; } char line[MAXCMDSIZE]; while (ifs.getline(line, MAXCMDSIZE-1)) { cmd() << line << "\n"; } // execute commands in the buffer CommandBuffer::exec(); } }