diff options
Diffstat (limited to 'src/core/gameserver.cc')
-rw-r--r-- | src/core/gameserver.cc | 206 |
1 files changed, 206 insertions, 0 deletions
diff --git a/src/core/gameserver.cc b/src/core/gameserver.cc new file mode 100644 index 0000000..6c84d3e --- /dev/null +++ b/src/core/gameserver.cc @@ -0,0 +1,206 @@ +/* + 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 <<player->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<unsigned int, Entity *>::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; + } + } +} + + +} |