/* core/gameserver.h This file is part of the Osirion project and is distributed under the terms of the GNU General Public License version 2 */ #include "sys/sys.h" #include "core/cvar.h" #include "core/func.h" #include "core/gameserver.h" #include "core/netserver.h" namespace core { void func_say(Player *player, std::string const &args) { server()->say(player, args); } GameServer *GameServer::server_instance = 0; GameServer::GameServer() : GameInterface() { con_print << "Initializing game server...\n"; server_instance = this; server_network = 0; server_module = Module::preload(); if (!server_module) { con_error << "No module loaded.\n"; abort(); return; } server_module->init(); if (!server_module->running()) { con_error << "Could not initialize module '" << server_module->name() << "'\n"; abort(); return; } con_print << " module '" << server_module->name() << "'\n"; if ((Cvar::sv_dedicated->value() || Cvar::sv_private->value())) { server_network = new NetServer(Cvar::net_host->str(), (unsigned int) Cvar::net_port->value()); if (!server_network->valid()) { delete server_network; server_network = 0; con_error << "Could not initialize network server\n"; abort(); return; } } else { con_debug << "Network server disabled.\n"; server_network = 0; } Func::add("say", (GameFuncPtr) func_say); if (!Cvar::sv_dedicated->value()) player_connect(localplayer()); server_running = true; } GameServer::~GameServer() { server_running = false; con_print << "Shutting down game server...\n"; if (server_network) { delete server_network; server_network = 0; } if (!Cvar::sv_dedicated->value()) player_disconnect(localplayer()); if (server_module) { server_module->shutdown(); if (server_module != Module::preload()) delete server_module; } Func::remove("say"); server_instance = 0; } bool GameServer::running() { return server_running; } void GameServer::abort() { server_running = false; } void GameServer::say(Player *player, std::string const &message) { // send to console con_print <name() << " " << message << "\n"; // broadcast to remote clients if (server_network != 0 ) { std::string netmessage("msg public "); netmessage.append(player->name()); netmessage += ' '; netmessage.append(message); netmessage += '\n'; server_network->broadcast(netmessage); } } void GameServer::broadcast(std::string const & message, int ignoreplayer) { // send to console con_print << message << "\n"; // broadcast to remote clients if (server_network) { std::string netmessage("msg info "); netmessage.append(message); netmessage += '\n'; server_network->broadcast(netmessage, ignoreplayer); } } void GameServer::send(Player const *player, std::string message) { // send to console if (player->id() == localplayer()->id()) { con_print << message << "\n"; } // send to remote clients if (server_network) { NetClient *client = server_network->find_client(player); if (client) { std::string netmessage("msg info "); netmessage.append(message); netmessage += '\n'; server_network->send(client, netmessage); } } } void GameServer::player_connect(Player *player) { std::string message(player->name()); message.append(" connects."); broadcast(message, player->id()); // TODO transferplayer info, transfer entities // notify the game module server_module->player_connect(player); } void GameServer::player_disconnect(Player *player) { std::string message(player->name()); message.append(" disconnects."); broadcast(message, player->id()); // notify the game module server_module->player_disconnect(player); } void GameServer::frame(float seconds) { if (error()) return; // process incoming network messages if (server_network != 0 ) { server_network->frame(seconds); if (server_network->error()) { abort(); return; } } // update entities std::map::iterator it; for (it=Entity::registry.begin(); it != Entity::registry.end(); it++) { Entity *entity = (*it).second; if ((entity->type() == Entity::Controlable) || (entity->type() == Entity::Dynamic)) { entity->frame(seconds); } } if (server_module) { server_module->frame(seconds); if (server_module->error()) { abort(); return; } } } }