Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorStijn Buys <ingar@osirion.org>2008-02-18 17:52:15 +0000
committerStijn Buys <ingar@osirion.org>2008-02-18 17:52:15 +0000
commit0b8582a9aa825024edbd0a21c6287bfcccec28de (patch)
tree2d9a46c60b028300b1b9133b84764b6c39964c33 /src/core
parent982562fa19bb87a3dab352e562f386f61c171b7b (diff)
core redesign, part II
Diffstat (limited to 'src/core')
-rw-r--r--src/core/Makefile.am6
-rw-r--r--src/core/application.cc202
-rw-r--r--src/core/application.h65
-rw-r--r--src/core/commandbuffer.cc4
-rw-r--r--src/core/core.h12
-rw-r--r--src/core/cvar.cc2
-rw-r--r--src/core/entity.h2
-rw-r--r--src/core/func.cc2
-rw-r--r--src/core/gameinterface.cc80
-rw-r--r--src/core/gameinterface.h52
-rw-r--r--src/core/gameserver.cc206
-rw-r--r--src/core/gameserver.h75
-rw-r--r--src/core/module.cc41
-rw-r--r--src/core/module.h74
-rw-r--r--src/core/netclient.cc1
-rw-r--r--src/core/netgame.cc0
-rw-r--r--src/core/netgame.h12
-rw-r--r--src/core/netserver.cc90
-rw-r--r--src/core/player.h4
19 files changed, 563 insertions, 367 deletions
diff --git a/src/core/Makefile.am b/src/core/Makefile.am
index cbe1efd..6c42468 100644
--- a/src/core/Makefile.am
+++ b/src/core/Makefile.am
@@ -2,13 +2,13 @@ METASOURCES = AUTO
INCLUDES = -I$(top_srcdir)/src
libcore_la_SOURCES = application.cc commandbuffer.cc core.cc cvar.cc entity.cc \
- func.cc gameinterface.cc netclient.cc netconnection.cc netgame.cc netserver.cc \
- player.cc
+ func.cc gameinterface.cc gameserver.cc module.cc netclient.cc netconnection.cc \
+ netserver.cc player.cc
libcore_la_LDFLAGS = -avoid-version -no-undefined
libcore_la_LIBADD = $(top_builddir)/src/math/libmath.la \
$(top_builddir)/src/filesystem/libfilesystem.la $(top_builddir)/src/sys/libsys.la $(top_builddir)/src/net/libnet.la
noinst_LTLIBRARIES = libcore.la
noinst_HEADERS = application.h commandbuffer.h core.h cvar.h entity.h func.h \
- gameinterface.h netconnection.h netgame.h player.h
+ gameinterface.h gameserver.h module.h netconnection.h player.h
diff --git a/src/core/application.cc b/src/core/application.cc
index 5d313ad..9c7620a 100644
--- a/src/core/application.cc
+++ b/src/core/application.cc
@@ -18,17 +18,11 @@
#include "core/cvar.h"
#include "core/entity.h"
#include "core/func.h"
-#include "core/netserver.h"
+#include "core/gameserver.h"
namespace core
{
-// return the global application object
-Application *application()
-{
- return Application::instance();
-}
-
// --------------- engine functions ------------------------------
void func_print(std::string const &args)
{
@@ -61,24 +55,7 @@ void func_disconnect(std::string const &args)
application()->disconnect();
}
-// FIXME this is a game function
-void func_say(std::string const &args)
-{
- if (application()->netserver) {
- std::ostringstream osstream;
- osstream << "msg public " << Player::local.name() << " " << args << "\n";
- application()->netserver->broadcast(osstream.str());
- con_print << Player::local.name() << ": " << args << "\n";
- } else if (application()->netconnection.connected()) {
- std::ostringstream osstream;
- osstream << args << "\n";
- application()->netconnection.send(args);
- } else if (game() && game()->connected) {
- con_print << args << "\n";
- } else
- con_print << "Not connected.";
-}
-
+/*
void func_name(std::string const &args) {
std::istringstream argstream(args);
std::string name;
@@ -113,6 +90,7 @@ void func_name(std::string const &args) {
Player::local.player_name = name;
}
+*/
// --------------- signal_handler -----------------------------------
@@ -151,8 +129,8 @@ Application::Application()
}
application_instance = this;
- netserver = 0;
- gameinterface_preload = 0;
+ application_time = 0;
+ application_game = 0;
sys::signal(SIGHUP, signal_handler);
sys::signal(SIGINT, signal_handler);
@@ -163,22 +141,6 @@ Application::Application()
Application::~Application()
{
application_instance = 0;
- }
-
-Application *Application::instance()
-{
- return application_instance;
-}
-
-float Application::time() const
-{
- return game_time;
-}
-
-bool Application::connected() const
-{
- return (Application::instance()->netconnection.connected() ||
- (GameInterface::instance() && GameInterface::instance()->connected));
}
void Application::init()
@@ -190,24 +152,11 @@ void Application::init()
CommandBuffer::init();
- gameinterface_preload = core::GameInterface::gameinterface_instance;
- core::GameInterface::gameinterface_instance = 0;
- if (gameinterface_preload) {
- con_print << " preloaded game found: " << gameinterface_preload->name() << "\n";
- }
- game_time = 0;
-
- // dedicated server should set this to 1
+ // 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");
- if (Cvar::sv_dedicated->value())
- Player::local.player_name = "Console";
- else
- Player::local.player_name = "Player0";
-
// network settings
Cvar::net_host = Cvar::get("net_host", "0.0.0.0");
Cvar::net_port = Cvar::get("net_port", "8042");
@@ -220,8 +169,7 @@ void Application::init()
Func::add("connect", func_connect);
Func::add("disconnect", func_disconnect);
- Func::add("say", func_say);
- Func::add("name", func_name);
+ //Func::add("name", func_name);
}
void Application::shutdown()
@@ -231,6 +179,11 @@ void Application::shutdown()
if (connected())
disconnect();
+ if (application_game) {
+ delete application_game;
+ application_game = 0;
+ }
+
// remove our engine functions
Func::remove("print");
Func::remove("help");
@@ -238,9 +191,7 @@ void Application::shutdown()
Func::remove("connect");
Func::remove("disconnect");
-
- Func::remove("say");
- Func::remove("name");
+ //Func::remove("name");
CommandBuffer::shutdown();
@@ -252,48 +203,22 @@ void Application::quit(int status)
sys::quit(status);
}
-// clear all game realted objects
-void Application::clear()
-{
- // remove all entities
- for (std::map<unsigned int, Entity*>::iterator it = Entity::registry.begin(); it != Entity::registry.end(); it++) {
- delete (*it).second;
- }
- Entity::registry.clear();
-
- // remove all game functions
- for (std::map<std::string, Func*>::iterator it = Func::registry.begin(); it != Func::registry.end(); it++) {
- if ( ((*it).second->flags() & Func::Game) == Func::Game) {
- delete (*it).second;
- Func::registry.erase(it);
- }
- }
-
- // remove all game cvars
- for (std::map<std::string, Cvar*>::iterator it = Cvar::registry.begin(); it != Cvar::registry.end(); it++) {
- if ( ((*it).second->flags() & Cvar::Game) == Cvar::Game) {
- delete (*it).second;
- Cvar::registry.erase(it);
- }
- }
-}
void Application::connect(std::string const &host)
{
- if (game() && game()->connected || netconnection.connected()) {
+ if (connected()) {
con_warn << "Connected. Disconnect first.\n";
return;
}
+
- if (game()) {
- // unload previous game
- if (game() != gameinterface_preload)
- delete core::GameInterface::gameinterface_instance;
+ if (application_game) {
+ delete application_game;
+ application_game = 0;
}
-
- clear();
-
+
if (host.size()) {
+ /*
// connect to remote core
core::GameInterface::gameinterface_instance = 0;
std::string remotehost(host);
@@ -316,97 +241,58 @@ void Application::connect(std::string const &host)
netconnection.disconnect();
con_warn << "Could not connect to '" << host << "'\n";
}
+ */
+ con_warn << "Can not connect to remote core.... yet!\n";
} else {
- // use preloaded game
- core::GameInterface::gameinterface_instance = gameinterface_preload;
+ application_game = new GameServer();
- // reset everything
- game_time = 0;
-
- if (game()->connected = game()->init()) {
+ if (application_game->running()) {
con_print << "Connected.\n";
} else {
+ delete application_game;
+ application_game = 0;
con_warn << "Could not connect.\n";
- return;
- }
-
- if (!netserver && (Cvar::sv_dedicated->value() || Cvar::sv_private->value())) {
- netserver = new NetServer(Cvar::net_host->str(), (unsigned int)Cvar::net_port->value());
- if (!netserver->valid()) {
- delete netserver;
- if (Cvar::sv_dedicated->value())
- shutdown();
- }
}
}
}
void Application::disconnect()
{
- if (netserver) {
- delete netserver;
- netserver = 0;
+
+ if(application_game) {
+ delete application_game;
+ application_game = 0;
+ con_print << "Disconnected.\n";
}
+ /*
if (netconnection.connected()) {
netconnection.disconnect();
con_print << "Disconnected.\n";
return;
}
-
- if (game()) {
- if (!game()->connected) {
- con_warn << "Not connected.\n";
- return;
- }
-
- game()->shutdown();
- game()->connected = false;
- game_time = 0;
-
- clear();
-
- con_print << "Disconnected.\n";
- }
+ */
}
void Application::frame(float seconds)
{
- if (seconds == 0.0f)
- return;
-
// execute commands in the buffer
CommandBuffer::exec();
- // update entities
- if (connected()) {
- 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);
- }
- }
- }
+ // don't run zero lenght time frames
+ if (seconds == 0.0f)
+ return;
- // netstuff
- if (netconnection.connected()) {
- netconnection.frame(seconds);
- // TODO this should come from server
- game_time += seconds;
- } else {
- if (netserver) {
- // TODO limit netserver frames in local mode
- netserver->frame(seconds);
- }
+ application_time += seconds;
- if (game() && game()->connected) {
- game_time += seconds;
+ if (!connected())
+ return;
+
+ // run a game interface frame
+ application_game->frame(seconds);
- game()->frame(seconds);
- }
- }
+ if (!application_game->running())
+ disconnect();
}
}
-
diff --git a/src/core/application.h b/src/core/application.h
index 0f4c5fa..de0ab35 100644
--- a/src/core/application.h
+++ b/src/core/application.h
@@ -25,35 +25,18 @@ public:
/// default destructor
virtual ~Application();
- /// initialize the application
- virtual void init();
-
- /// shutdown the application
- virtual void shutdown();
-
- /// a pointer to the current application instance
- static Application *instance();
-
- /// time the has been connected, in seconds
- float time() const;
-
- /// preloaded game object
- GameInterface *gameinterface_preload;
-
- /// true if the core is connected to a game module or a remote server
- bool connected() const;
+/*----- inspectors ----------------------------------------------- */
- /// network server instance
- NetServer *netserver;
-
- /// network client to server connection
- NetConnection netconnection;
+ /// time the application has been running
+ inline float time() const { return application_time; }
- /// global application object
- static Application *application_instance;
+ /// true if the core is connected to a running game interface
+ inline bool connected() const { return (application_game && application_game->running()); }
- /// quit the application without proper shutdown
- virtual void quit(int status);
+ /// return the game interface, returns 0 if the pplication is not connected to a game
+ inline GameInterface *game() { return application_game; }
+
+/*----- mutators ------------------------------------------------- */
/// start the server or connect to remote host
void connect(std::string const &host);
@@ -61,20 +44,38 @@ public:
/// disconnect from the game module
void disconnect();
-protected:
- /// clear all game related objects
- void clear();
+/*----- virtual mutators ------------------------------------------ */
+ /// initialize the application
+ virtual void init();
+
+ /// shutdown the application
+ virtual void shutdown();
+
+ /// quit the application without proper shutdown
+ virtual void quit(int status);
+
+/*----- static --------------------------------------------------- */
+
+ /// a pointer to the current application instance
+ static inline Application *instance() { return application_instance; }
+
+protected:
/// run a core frame
virtual void frame(float seconds);
private:
/// time the core has been running
- float game_time;
+ float application_time;
+ GameInterface *application_game;
+ static Application *application_instance;
};
-/// pointer to the current ApplicationInterface
-Application *application();
+/// pointer to the current Application
+inline Application *application() { return Application::instance(); }
+
+/// pointer to the current GameInterface
+inline GameInterface *game() { return Application::instance()->game(); }
} // namespace core
diff --git a/src/core/commandbuffer.cc b/src/core/commandbuffer.cc
index 8f02f71..5ab40e5 100644
--- a/src/core/commandbuffer.cc
+++ b/src/core/commandbuffer.cc
@@ -9,10 +9,10 @@
#include <list>
#include "sys/sys.h"
+#include "core/application.h"
#include "core/commandbuffer.h"
#include "core/func.h"
#include "core/cvar.h"
-#include "core/gameinterface.h"
namespace core
{
@@ -75,7 +75,7 @@ void CommandBuffer::exec(std::string const &cmdline)
args += c;
}
if ((f->flags() & Func::Game)) {
- if (game() && game()->connected) {
+ if (application()->connected()) {
f->exec(&Player::local, args);
}
} else {
diff --git a/src/core/core.h b/src/core/core.h
index 4e2af22..2a23d84 100644
--- a/src/core/core.h
+++ b/src/core/core.h
@@ -7,22 +7,22 @@
#ifndef __INCLUDED_CORE_H__
#define __INCLUDED_CORE_H__
+/// core contains the basic functionality of the engine
+namespace core
+{
+}
+
#include "core/application.h"
#include "core/commandbuffer.h"
#include "core/cvar.h"
#include "core/entity.h"
#include "core/func.h"
#include "core/gameinterface.h"
+#include "core/module.h"
#include "core/netserver.h"
#include "core/netclient.h"
#include "core/netconnection.h"
#include "core/player.h"
-/// core contains the basic functionality of the engine
-namespace core
-{
-
-}
-
#endif // __INCLUDED_CORE_H__
diff --git a/src/core/cvar.cc b/src/core/cvar.cc
index dbe1d30..9419db3 100644
--- a/src/core/cvar.cc
+++ b/src/core/cvar.cc
@@ -159,7 +159,7 @@ void Cvar::list()
else
typeindicator += ' ';
- con_print << std::setw(4) << (*it).second->flags() << " " << typeindicator <<
+ con_print << " " << typeindicator <<
" " << (*it).first << " " << (*it).second->str() << std::endl;
}
con_print << registry.size() << " registered variables" << std::endl;
diff --git a/src/core/entity.h b/src/core/entity.h
index 7b3f200..df16075 100644
--- a/src/core/entity.h
+++ b/src/core/entity.h
@@ -178,14 +178,12 @@ public:
virtual void frame(float seconds);
/* entity_ variables can be set by the module */
-
/// owner of the entity
Player *entity_owner;
/// current thrust
float entity_thrust;
/* target_ variables can be set by the client */
-
/// target thrust as set by the client
float target_thrust;
/// target direction as set by the client
diff --git a/src/core/func.cc b/src/core/func.cc
index 0215ddf..ab3a404 100644
--- a/src/core/func.cc
+++ b/src/core/func.cc
@@ -78,7 +78,7 @@ void Func::list()
typeindicator += 'G';
else
typeindicator += ' ';
- con_print << std::setw(4) << (*it).second->flags() << " " << typeindicator <<
+ con_print << " " << typeindicator <<
" " << (*it).second->name() << std::endl;
}
diff --git a/src/core/gameinterface.cc b/src/core/gameinterface.cc
index 38ea6fe..908ffca 100644
--- a/src/core/gameinterface.cc
+++ b/src/core/gameinterface.cc
@@ -7,81 +7,57 @@
#include <stdlib.h>
#include <iostream>
-class GameInterface;
-
+#include "sys/sys.h"
#include "core/application.h"
+#include "core/cvar.h"
+#include "core/func.h"
#include "core/gameinterface.h"
#include "core/player.h"
-#include "sys/sys.h"
namespace core
{
-GameInterface *game()
-{
- return GameInterface::instance();
-}
-
-GameInterface *GameInterface::gameinterface_instance = 0;
-
-GameInterface::GameInterface(const char *gamename)
+GameInterface::GameInterface()
{
- gameinterface_instance = this;
- connected = false;
- if (gamename)
- game_name.assign(gamename);
+ if (Cvar::sv_dedicated->value())
+ local_player.player_name.assign("Console");
else
- game_name.clear();
+ local_player.player_name.assign("Player0");
+ clear();
}
GameInterface::~GameInterface()
{
- gameinterface_instance = 0;
-}
-
-GameInterface *GameInterface::instance()
-{
- return gameinterface_instance;
+ clear();
}
-std::string const &GameInterface::name()
+// clear all game related objects
+void GameInterface::clear()
{
- return game_name;
-}
+ con_debug << "Clearing game data\n";
-void message_broadcast(std::string const & message, int ignoreplayer)
-{
- // send to console
- con_print << message << std::endl;
-
- // broadcast to remote clients
- if (application()->netserver) {
- std::string netmessage("msg info ");
- netmessage.append(message);
- netmessage += '\n';
-
- application()->netserver->broadcast(netmessage, ignoreplayer);
+ // remove all entities
+ for (std::map<unsigned int, Entity*>::iterator it = Entity::registry.begin(); it != Entity::registry.end(); it++) {
+ delete (*it).second;
}
-}
+ Entity::registry.clear();
-void message_send(Player const *player, const char *protohdr, std::string message)
-{
- // send to console
- if (player == &Player::local) {
- con_print << message << std::endl;
+ // remove all game functions
+ for (std::map<std::string, Func*>::iterator it = Func::registry.begin(); it != Func::registry.end(); it++) {
+ if ( ((*it).second->flags() & Func::Game) == Func::Game) {
+ delete (*it).second;
+ Func::registry.erase(it);
+ }
}
- // send to remote clients
- if (application()->netserver) {
- NetClient *client = application()->netserver->find_client(player);
- if (client) {
- std::string netmessage("msg info ");
- netmessage.append(message);
- netmessage += '\n';
-
- application()->netserver->send(client, message);
+ // remove all game cvars
+ for (std::map<std::string, Cvar*>::iterator it = Cvar::registry.begin(); it != Cvar::registry.end(); it++) {
+ if ( ((*it).second->flags() & Cvar::Game) == Cvar::Game) {
+ delete (*it).second;
+ Cvar::registry.erase(it);
}
}
}
+
} // namespace core
diff --git a/src/core/gameinterface.h b/src/core/gameinterface.h
index 9eb6880..5e1f9be 100644
--- a/src/core/gameinterface.h
+++ b/src/core/gameinterface.h
@@ -12,55 +12,41 @@
namespace core
{
-/// broadcast a network message to all players
-void message_broadcast(std::string const & message, int ignoreplayer=-1);
-
-/// send a message to a player
-void message_send(Player &player, std::string const & message);
-
/// abstract interface from the core to the game-specific code
class GameInterface
{
public:
/// create a new game
- GameInterface(const char *gamename = 0);
+ GameInterface();
+
/// destroy the game
virtual ~GameInterface();
-
- /// a pointer to the current game instance
- static GameInterface * instance();
-
- /// true if the game is ready and running
- bool connected;
-
- /// run one frame of the game
- /// @param sec time since the previous frame, in seconds
- virtual void frame(float seconds) = 0;
- /// initialize the game
- virtual bool init() = 0;
+/*----- inspectors ---------------------------------------------- */
- /// shutdown the game
- virtual void shutdown() = 0;
+ /// return the local player
+ inline Player *localplayer() { return &local_player; }
+
+/*----- virtual inspectors --------------------------------------- */
- /// is called when a player connects
- virtual void player_connect(Player *player) = 0;
+ /// returns true if the game server can run a time frime
+ virtual bool running() = 0;
- /// is called when a player disconnects
- virtual void player_disconnect(Player *player) = 0;
+/*----- mutators ------------------------------------------------- */
- static GameInterface *gameinterface_instance;
+ /// clear all game variables, game functions and entities
+ void clear();
- /// the name of the game
- std::string const & name();
+/*----- virtual mutators ------------------------------------------ */
+
+ /// run one game time frame
+ /// @param sec time since the previous frame, in seconds
+ virtual void frame(float seconds) = 0;
-private:
- std::string game_name;
+protected:
+ Player local_player;
};
-/// pointer to the current GameInterface
-GameInterface *game();
-
}
#endif // __INCLUDED_CORE_GAMEINTERFACE_H__
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;
+ }
+ }
+}
+
+
+}
diff --git a/src/core/gameserver.h b/src/core/gameserver.h
new file mode 100644
index 0000000..ba64f2e
--- /dev/null
+++ b/src/core/gameserver.h
@@ -0,0 +1,75 @@
+/*
+ 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
+*/
+
+#ifndef __INCLUDED_CORE_GAMESERVER_H__
+#define __INCLUDED_CORE_GAMESERVER_H__
+
+#include "core/gameinterface.h"
+#include "core/module.h"
+#include "core/netserver.h"
+
+namespace core
+{
+
+/// the core game server
+/** the core game server runs the game module. Network access is enabled
+ * for the dedicated server or the client with private server enabled.
+ */
+class GameServer : public GameInterface
+{
+public:
+ GameServer();
+ ~GameServer();
+
+/*----- inspectors ------------------------------------------------ */
+
+ /// returns true if the game server can run a time frime
+ bool running();
+
+ /// returns true if the game server can not run a time frime
+ inline bool error() { return !server_running; }
+
+/*----- mutators -------------------------------------------------- */
+
+ /// is called when a player connects to the game server
+ void player_connect(Player *player);
+
+ /// a caleld when a player disconnects from the game server
+ void player_disconnect(Player *player);
+
+ /// run a game server time frame
+ void frame(float seconds);
+
+ /// a player sends a chat message on the public channel
+ void say(Player *player, std::string const &args);
+
+ /// broadcast a message to all players
+ void broadcast(std::string const & message, int ignoreplayer = -1);
+
+ /// send a message to a single player
+ void send(Player const *player, std::string message);
+
+/*----- static ---------------------------------------------------- */
+
+ /// retuen the current game server
+ static inline GameServer *instance() { return server_instance; }
+
+protected:
+ /// abort runing
+ void abort();
+private:
+ bool server_running;
+ Module *server_module;
+ static GameServer *server_instance;
+ NetServer *server_network;
+
+};
+
+inline GameServer *server() { return GameServer::instance(); }
+
+}
+
+#endif // __INCLUDED_CORE_GAMESERVER_H__
diff --git a/src/core/module.cc b/src/core/module.cc
new file mode 100644
index 0000000..45559f2
--- /dev/null
+++ b/src/core/module.cc
@@ -0,0 +1,41 @@
+/*
+ core/module.cc
+ This file is part of the Osirion project and is distributed under
+ the terms of the GNU General Public License version 2
+*/
+
+#include "core/module.h"
+
+namespace core
+{
+
+Module *Module::module_preload;
+
+Module::Module(const char *name)
+{
+ module_running = false;
+ module_name.assign(name);
+ module_preload = 0;
+}
+
+Module::~Module()
+{
+ module_running = false;
+ module_name.clear();
+}
+
+
+void Module::load(Module *module)
+{
+ module_preload = module;
+}
+
+void Module::unload()
+{
+ if (module_preload) {
+ delete module_preload;
+ module_preload = 0;
+ }
+}
+
+}
diff --git a/src/core/module.h b/src/core/module.h
new file mode 100644
index 0000000..053c9e5
--- /dev/null
+++ b/src/core/module.h
@@ -0,0 +1,74 @@
+/*
+ core/module.h
+ This file is part of the Osirion project and is distributed under
+ the terms of the GNU General Public License version 2
+*/
+
+#ifndef __INCLUDED_CORE_MODULE_H__
+#define __INCLUDED_CORE_MODULE_H__
+
+#include <string>
+#include "core/player.h"
+
+namespace core
+{
+
+// a loadable game module
+class Module
+{
+public:
+ Module(const char *name);
+ virtual ~Module();
+
+/*----- inspectors ------------------------------------------------ */
+ /// return true if the game module can run a timeframe
+ inline bool running() const { return module_running; }
+
+ /// return true if the game module can not run a timeframe
+ inline bool error() const { return !module_running; }
+
+ /// return the name of the module
+ inline std::string const & name() const { return module_name; }
+
+/*----- mutators -------------------------------------------------- */
+
+ /// initialize the game module
+ virtual void init() = 0;
+
+ /// shutdown the game module
+ virtual void shutdown() = 0;
+
+ /// run one timeframe
+ virtual void frame(float seconds) = 0;
+
+ /// is called when a player connects
+ virtual void player_connect(Player *player) = 0;
+
+ /// is called when a player disconnects
+ virtual void player_disconnect(Player *player) = 0;
+
+/*----- static ---------------------------------------------------- */
+
+ /// load a game module
+ static void load(Module *module);
+
+ /// unload the preloaded module
+ static void unload();
+
+ /// the preloaded module
+ inline static Module *preload() { return module_preload; };
+
+protected:
+ /// set the disconnected state
+ void abort();
+ bool module_running;
+
+private:
+ static Module *module_preload;
+ std::string module_name;
+
+};
+
+}
+
+#endif // __INCLUDED_CORE_MODULE_H__
diff --git a/src/core/netclient.cc b/src/core/netclient.cc
index 61a3e64..7b5d554 100644
--- a/src/core/netclient.cc
+++ b/src/core/netclient.cc
@@ -26,7 +26,6 @@ NetClient::NetClient(int clientfd, std::string host, int port) :
client_host = host;
client_port = port;
- //con_debug << "NetClient " << fd() << ": starting." << std::endl;
}
NetClient::~NetClient()
diff --git a/src/core/netgame.cc b/src/core/netgame.cc
deleted file mode 100644
index e69de29..0000000
--- a/src/core/netgame.cc
+++ /dev/null
diff --git a/src/core/netgame.h b/src/core/netgame.h
deleted file mode 100644
index e55e8c6..0000000
--- a/src/core/netgame.h
+++ /dev/null
@@ -1,12 +0,0 @@
-/*
- core/netgame.h
- This file is part of the Osirion project and is distributed under
- the terms of the GNU General Public License version 2
-*/
-
-#ifndef __INCLUDED_CORE_GAMEINTERFACE_H__
-#define __INCLUDED_CORE_GAMEINTERFACE_H__
-
-#include "core/player.h"
-
-#endif \ No newline at end of file
diff --git a/src/core/netserver.cc b/src/core/netserver.cc
index 39548dd..ba8510d 100644
--- a/src/core/netserver.cc
+++ b/src/core/netserver.cc
@@ -8,6 +8,7 @@
#include <sstream>
#include "sys/sys.h"
+#include "core/gameserver.h"
#include "core/netclient.h"
#include "core/netserver.h"
#include "core/cvar.h"
@@ -20,6 +21,7 @@ namespace core
NetServer::NetServer(std::string const host, unsigned int const port) :
net::TCPServer(host, port)
{
+ //con_print << "Initializing network server..." << std::endl;
FD_ZERO(&serverset);
// add the listening socket to the file descriptor set
FD_SET(fd(), &serverset);
@@ -29,16 +31,16 @@ NetServer::NetServer(std::string const host, unsigned int const port) :
NetServer::~NetServer()
{
- con_print << "Shutting down network..." << std::endl;
+ con_print << "Shutting down network server..." << std::endl;
// delete all clients
std::list<NetClient *>:: iterator it;
for (it = clients.begin(); it != clients.end(); it++) {
- // notify the game
- if (game() && game()->connected) {
- core::game()->player_disconnect((*it)->player());
- con_print << (*it)->player()->name() << " disconnected."<< std::endl;
- }
+ // notify the game server
+ server()->player_disconnect((*it)->player());
+
+ con_print << " " << (*it)->host() << ":" << (*it)->port() << " disconnected.\n";
+
delete (*it);
}
clients.clear();
@@ -48,8 +50,7 @@ void NetServer::client_connect(int const clientfd, std::string const host, int c
{
NetClient *client = new NetClient(clientfd, host, port);
if (client->error()) {
- con_warn << "Client " << client->fd() << " " <<
- client->host() << ":" << client->port() << " connection failed!" << std::endl;
+ con_warn << client->host() << ":" << client->port() << " connection failed!\n";
delete(client);
return;
}
@@ -57,20 +58,11 @@ void NetServer::client_connect(int const clientfd, std::string const host, int c
clients.push_back(client);
FD_SET(client->fd(), &serverset);
- // TODO send infos
- con_print << client->host() << ":" << client->port() << " " << client->player()->name() << " connected."<< std::endl;
+ con_print << client->host() << ":" << client->port() << " connected.\n";
- // BROADCAST connect message
- std::ostringstream osstream;
- osstream << "msg info " << client->player()->name() << " connected."<< std::endl;
- broadcast(osstream.str(), clientfd);
+ // notify the game server
+ server()->player_connect(client->player());
- // notify the game
- if (game() && game()->connected) {
- core::game()->player_connect(client->player());
- } else {
- // TODO send disconnect message and remove client
- }
}
// remove disconnected clients
@@ -82,16 +74,9 @@ void NetServer::reap()
if (client->error()) {
FD_CLR(client->fd(), &serverset);
- // BROADCAST disconnect message
- std::ostringstream osstream;
- osstream << "msg info " << client->player()->name() << " disconnected."<< std::endl;
- broadcast(osstream.str());
-
- // notify the game
- if (core::game())
- core::game()->player_disconnect(client->player());
-
- con_print << client->player()->name() << " disconnected."<< std::endl;
+ // notify the game server
+ server()->player_disconnect((*it)->player());
+ con_print << client->host() << ":" << client->port() << " disconnected.\n";
// remove the client
clients.erase(it);
@@ -118,7 +103,7 @@ void NetServer::frame(float seconds) {
if (nb == -1) {
con_error << "Network error on select()" << std::endl;
- perror("select");
+ //perror("select");
abort();
}
@@ -244,40 +229,21 @@ void NetServer::parse_incoming_message(NetClient *client, const std::string & me
}
// execute game functions
- if (game() && game()->connected) {
- Func *function = Func::find(command);
- if (function ) {
- std::string args;
- char c;
- if (msgstream >> args)
- while (msgstream >> c)
- args += c;
- if (function ->flags() && Func::Game) {
- function->exec(client->player(), args);
- } else {
- // instant rcon
- //function->exec(args);
- }
+ Func *function = Func::find(command);
+ if (function ) {
+ std::string args;
+ char c;
+ if (msgstream >> args)
+ while (msgstream >> c)
+ args += c;
+ if (function ->flags() && Func::Game) {
+ function->exec(client->player(), args);
+ } else {
+ // FIXME instant rcon
+ function->exec(args);
}
}
-}
-void NetServer::parse_client_variable(NetClient * client, const std::string varname, std::istringstream &istringstream)
-{
- if (varname=="name") {
- std::string name;
- if (istringstream >> name) {
- std::ostringstream osstream;
- if (name.size() > 16)
- name = name.substr(0,16);
- if (name != client->player()->name()) {
- osstream << "msg info " << client->player()->name() << " renamed to " << name << "\n";
- broadcast(osstream.str());
- client->player()->player_name = name;
- }
- }
- return;
- }
}
}
diff --git a/src/core/player.h b/src/core/player.h
index e19b8ae..490515d 100644
--- a/src/core/player.h
+++ b/src/core/player.h
@@ -30,10 +30,10 @@ public:
inline std::string const &name() const { return player_name; }
/// id of the player
- inline unsigned int id() const { return player_id; }
+ inline int id() const { return player_id; }
/// id of the player
- unsigned int player_id;
+ int player_id;
/// name of the player
std::string player_name;