diff options
| author | Stijn Buys <ingar@osirion.org> | 2008-02-18 17:52:15 +0000 | 
|---|---|---|
| committer | Stijn Buys <ingar@osirion.org> | 2008-02-18 17:52:15 +0000 | 
| commit | 0b8582a9aa825024edbd0a21c6287bfcccec28de (patch) | |
| tree | 2d9a46c60b028300b1b9133b84764b6c39964c33 /src | |
| parent | 982562fa19bb87a3dab352e562f386f61c171b7b (diff) | |
core redesign, part II
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/Makefile.am | 6 | ||||
| -rw-r--r-- | src/core/application.cc | 202 | ||||
| -rw-r--r-- | src/core/application.h | 65 | ||||
| -rw-r--r-- | src/core/commandbuffer.cc | 4 | ||||
| -rw-r--r-- | src/core/core.h | 12 | ||||
| -rw-r--r-- | src/core/cvar.cc | 2 | ||||
| -rw-r--r-- | src/core/entity.h | 2 | ||||
| -rw-r--r-- | src/core/func.cc | 2 | ||||
| -rw-r--r-- | src/core/gameinterface.cc | 80 | ||||
| -rw-r--r-- | src/core/gameinterface.h | 52 | ||||
| -rw-r--r-- | src/core/gameserver.cc | 206 | ||||
| -rw-r--r-- | src/core/gameserver.h | 75 | ||||
| -rw-r--r-- | src/core/module.cc | 41 | ||||
| -rw-r--r-- | src/core/module.h | 74 | ||||
| -rw-r--r-- | src/core/netclient.cc | 1 | ||||
| -rw-r--r-- | src/core/netgame.cc | 0 | ||||
| -rw-r--r-- | src/core/netgame.h | 12 | ||||
| -rw-r--r-- | src/core/netserver.cc | 90 | ||||
| -rw-r--r-- | src/core/player.h | 4 | ||||
| -rw-r--r-- | src/game/game.cc | 48 | ||||
| -rw-r--r-- | src/game/game.h | 7 | ||||
| -rw-r--r-- | src/net/tcpserver.cc | 12 | ||||
| -rw-r--r-- | src/osirion.cc | 7 | ||||
| -rw-r--r-- | src/osiriond.cc | 7 | ||||
| -rw-r--r-- | src/render/tga.cc | 1 | 
25 files changed, 610 insertions, 402 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; diff --git a/src/game/game.cc b/src/game/game.cc index fb0d917..311a696 100644 --- a/src/game/game.cc +++ b/src/game/game.cc @@ -9,7 +9,7 @@  #include "game/game.h"  #include "game/ship.h"  #include "game/star.h" -#include "core/entity.h" +#include "core/gameserver.h"  #include "sys/sys.h"  #include "math/mathlib.h"  #include "filesystem/filesystem.h" @@ -17,6 +17,8 @@  namespace game  { +/*----- engine game functions ------------------------------------- */ +  /// a player joins the game  void func_join(core::Player *player, std::string const &args)  { @@ -25,9 +27,9 @@ void func_join(core::Player *player, std::string const &args)  	player->control = new Ship(player); -	std::ostringstream osstream; -	osstream << player->name() << " joins the game"; -	core::message_broadcast(osstream.str(), player->id()); +	std::string message(player->name()); +	message.append(" joins the game."); +	core::server()->broadcast(message);  }  /// a player joins the spectators @@ -36,9 +38,9 @@ void func_spectate(core::Player *player, std::string const &args)  	if (!player->control)  		return; -	std::ostringstream osstream; -	osstream << player->name() << " spectates"; -	core::message_broadcast(osstream.str(), player->id()); +	std::string message(player->name()); +	message.append(" spectates."); +	core::server()->broadcast(message);  	if (player->control) {  		// player has only ship for now @@ -47,7 +49,9 @@ void func_spectate(core::Player *player, std::string const &args)  	}  } -Game::Game() : core::GameInterface("Project::OSiRiON") +/*----- Game ------------------------------------------------------ */ + +Game::Game() : core::Module("Project::OSiRiON")  {  } @@ -55,19 +59,21 @@ Game::~Game()  {  } -bool Game::init() +void Game::init()  {  	using math::Vector3f;  	using math::Color; -	con_print << "Initializing game..." << std::endl; -	con_print << "  " << name() << std::endl; +	module_running = false; -	// set up some stuff in the game world +	// setup the game world +	 +	// the star  	Star *star = new Star();  	star->entity_location = Vector3f(256.0f, 0.0f, 256.0f);  	star->entity_name = "star: Sabishi Hoshi"; +	// the green cube  	core::Entity *cube = new core::Entity(core::Entity::Solid & core::Entity::Static);  	cube->entity_shape = core::Entity::Cube;  	cube->entity_color = Color(0.0f, 0.8f, 0.0f); @@ -75,6 +81,7 @@ bool Game::init()  	cube->entity_name ="cube: Borg cube green";  	cube->entity_moduletypeid = cube_enttype; +	// the red cube  	cube = new core::Entity(core::Entity::Solid & core::Entity::Static);  	cube->entity_shape = core::Entity::Cube;  	cube->entity_color = Color(1.0f, 0.0f, 0.0f); @@ -82,38 +89,41 @@ bool Game::init()  	cube->entity_name ="cube: Borg cube red";  	cube->entity_moduletypeid = cube_enttype; +	// the yellow sphere  	core::Entity *sphere = new core::Entity(core::Entity::Solid & core::Entity::Static);  	sphere->entity_shape = core::Entity::Sphere;  	sphere->entity_color = Color(0.8f, 0.8f, 0.0f);  	sphere->entity_location = Vector3f(0.0f, 0.0f, -32.0f);  	sphere->entity_name ="sphere: The Sphere"; +	// the galactic origin  	core::Entity *axis = new core::Entity(core::Entity::Static);  	axis->entity_shape = core::Entity::Diamond;  	axis->entity_color = Color(1.0f, 1.0f, 0.0f);  	axis->entity_location = Vector3f(0, 0, 0);  	axis->entity_name = "axis: Origin"; -	// add game functions +	// add engine game functions  	core::Func::add("join", (core::GameFuncPtr) func_join);  	core::Func::add("spectate", (core::GameFuncPtr) func_spectate); -	// add game variables +	// add engine game variables  	core::Cvar::set("g_borgcubes", "2", core::Cvar::Game);  	core::Cvar::set("g_name", name().c_str(), core::Cvar::Game | core::Cvar::ReadOnly); -	return true; +	 +	// indicate the module is ready to run frames +	module_running = true;  }  void Game::shutdown()  { -	con_print << "Shutting down game..." << std::endl; - -	//core::Func::remove("join"); -	//core::Func::remove("spectate"); +	module_running = false;  }  void Game::frame(float seconds)  { +	if (!running()) +		return;  }  void Game::player_connect(core::Player *player) diff --git a/src/game/game.h b/src/game/game.h index f5f0bc0..811de84 100644 --- a/src/game/game.h +++ b/src/game/game.h @@ -30,18 +30,18 @@ const unsigned int cube_enttype = 258;  const unsigned int sphere_enttype = 259;  const unsigned int axis_enttype = 260; -class Game : public core::GameInterface { +class Game : public core::Module {  public:  	Game();  	~Game();  	/// initialize the game -	bool init(); +	void init();  	/// shutdown the game  	void shutdown(); -	/// execute one game grame +	/// run one time frame  	void frame(float seconds);  	/// is called when a player connects @@ -49,7 +49,6 @@ public:  	/// is called when a player disconnects  	void player_disconnect(core::Player *player); -  };  } diff --git a/src/net/tcpserver.cc b/src/net/tcpserver.cc index 3276f87..5b68a65 100644 --- a/src/net/tcpserver.cc +++ b/src/net/tcpserver.cc @@ -28,14 +28,14 @@ TCPServer::TCPServer(std::string const host, unsigned int const port)  	tcpserver_fd = -1;  	tcpserver_error = true; -	con_print << "Initializing network..." << std::endl; +	con_print << "Initializing network server..." << std::endl;  	// initialize socket  	tcpserver_fd = ::socket(PF_INET, SOCK_STREAM, 0);  	if (tcpserver_fd == -1) {  		// FIXME error handling  		con_error << "Network can't create socket!" << std::endl; -		perror("socket"); +		//perror("socket");  		return;  	} @@ -44,7 +44,7 @@ TCPServer::TCPServer(std::string const host, unsigned int const port)  	if (::setsockopt(tcpserver_fd,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(socklen_t)) == -1) {  		// FIXME error handling  		std::cerr << "Network can't set socket options!" << std::endl; -		perror("setsockopt"); +		//perror("setsockopt");  		return;  	} @@ -60,7 +60,7 @@ TCPServer::TCPServer(std::string const host, unsigned int const port)  	if (::bind(tcpserver_fd, (struct sockaddr *) &listen_addr, sizeof(struct sockaddr)) == -1) {  		// FIXME error handling  		con_error << "Network can't bind to local address!" << std::endl; -		perror("bind"); +		//perror("bind");  		return;  	} @@ -68,7 +68,7 @@ TCPServer::TCPServer(std::string const host, unsigned int const port)  	if (::listen(tcpserver_fd, MAXPENDINGCONNECTIONS) == -1) {  		// FIXME error handling  		con_error << "Network failed to listen on socket!" << std::endl; -		perror("listen"); +		//perror("listen");  		return;  	} @@ -119,7 +119,7 @@ void TCPServer::accept()  	if (clientfd == -1) {  		// FIXME error handling  		con_error << "Network accept() error!" << std::endl; -		perror("accept"); +		//perror("accept");  		return;  	} else {  		std::string host(inet_ntoa(client_addr.sin_addr)); diff --git a/src/osirion.cc b/src/osirion.cc index 696104f..6fa2eb3 100644 --- a/src/osirion.cc +++ b/src/osirion.cc @@ -9,12 +9,13 @@  int main(int count, char **arguments)  { -	// preload the game object -	game::Game *game = new game::Game(); +	// preload the game module +	core::Module::load(new game::Game());  	client::main(count, arguments); -	game = 0;	// prevents variable not used warning +	// unload the game module +	core::Module::unload();  	return 0;  } diff --git a/src/osiriond.cc b/src/osiriond.cc index 55bbbf5..0e8f6f7 100644 --- a/src/osiriond.cc +++ b/src/osiriond.cc @@ -9,12 +9,13 @@  int main(int count, char **arguments)  { -	// preload the game object -	game::Game *game = new game::Game(); +	// preload the game module +	core::Module::load(new game::Game());  	server::main(count, arguments); -	game = 0;	// prevents variable not used warning +	// unload the game module +	core::Module::unload();  	return 0;  } diff --git a/src/render/tga.cc b/src/render/tga.cc index 5802edf..18b8870 100644 --- a/src/render/tga.cc +++ b/src/render/tga.cc @@ -64,6 +64,7 @@ TGA::image *TGA::load(const char *filename)  		return 0;  	pImgData = (image*)malloc(sizeof(image)); +	pImgData->data = 0;  	f->read((void *)&length, sizeof(GLubyte));  	f->skip(1); | 
