From 41ad1e4c9e2a70d0a8811f4b035f0d3018045e61 Mon Sep 17 00:00:00 2001 From: Stijn Buys Date: Tue, 19 Feb 2008 17:37:01 +0000 Subject: client-to-server connection --- ROADMAP | 39 ++++--------------- TODO | 34 +++++++++++++++-- configure.in | 2 +- osirion.kdevelop.pcs | Bin 420253 -> 429232 bytes osirion.kdevses | 15 +++++++- src/Makefile.am | 1 - src/client/client.cc | 3 +- src/core/Makefile.am | 6 +-- src/core/application.cc | 42 +++++--------------- src/core/commandbuffer.cc | 7 +++- src/core/core.cc | 18 +++++++++ src/core/core.h | 17 +++++++-- src/core/func.cc | 2 +- src/core/gameconnection.cc | 93 +++++++++++++++++++++++++++++++++++++++++++++ src/core/gameconnection.h | 59 ++++++++++++++++++++++++++++ src/core/gameserver.cc | 40 +++++++++++++++---- src/core/gameserver.h | 8 +++- src/core/netclient.h | 4 +- src/core/netserver.cc | 39 ++++++++----------- src/core/netserver.h | 3 -- src/net/net.h | 2 + src/net/tcpconnection.cc | 2 +- src/server/server.cc | 3 +- 23 files changed, 317 insertions(+), 122 deletions(-) create mode 100644 src/core/gameconnection.cc create mode 100644 src/core/gameconnection.h diff --git a/ROADMAP b/ROADMAP index 6a3deb8..a3ca777 100644 --- a/ROADMAP +++ b/ROADMAP @@ -1,33 +1,4 @@ -SUBSYSTEMS - -filesystem:: - write vfile and vpath implementation - handles file reading/loading - -core:: - Cvar (ok) - must be possible to mark a Cvar cvar::Game - Func (ok) - must be possible to mark a Func func::Game - CommandBuffer (ok) - Entity - seperate client:: and game:: - Cvar/Func info text - -network:: - connections - protocol - chat, channels - rcon, commands - -client:: - keymap (ok) - input handler switching (ok) - console chars (ok) - -render:: - render pipelines - pipeline for Lines AlphaLines Quads AlphaQuads Characters +ROADMAP * VERSION 0.1 @@ -42,12 +13,18 @@ Description: Requires: Network subsystem - Ship instances + Ship instances + Entities + * VERSION 0.2 Players can shoot at each other. They can crash into the star or the planet. +Requires: + weapons + collision detection + * VERSION 0.3 Players can dock at the space station. diff --git a/TODO b/TODO index c62f1df..57d33b4 100644 --- a/TODO +++ b/TODO @@ -1,5 +1,31 @@ -* Fix win32 issues - server/timer.h - server/tmer.cc - sys/sys.cc +TODO +filesystem:: + write a filesystem based on streams + write handlers for zip + +core:: + connection to remote game + read/write configuration file + parse command line options + +network:: + protocol + chat, channels + rcon, commands + zlib compression + +client:: + keyboard handler, must be able to handle keyboard layouts + decent input handling implementation + key bindings + input handler switching (ok) + console chars (ok) + +render:: + render pipelines + pipeline for Lines AlphaLines Quads AlphaQuads Characters + .map models + +sys:: + win32 (requires removal or #ifdef of the select() calls) \ No newline at end of file diff --git a/configure.in b/configure.in index 673249a..579b643 100644 --- a/configure.in +++ b/configure.in @@ -1,7 +1,7 @@ AC_INIT(configure.in) AM_CONFIG_HEADER(src/config.h) -AM_INIT_AUTOMAKE(osirion, 0.0.1) +AM_INIT_AUTOMAKE(osirion, 0.1) AC_LANG_CPLUSPLUS AC_PROG_CXX diff --git a/osirion.kdevelop.pcs b/osirion.kdevelop.pcs index bce43cb..cabcdfb 100644 Binary files a/osirion.kdevelop.pcs and b/osirion.kdevelop.pcs differ diff --git a/osirion.kdevses b/osirion.kdevses index e8415d1..c5f0f7b 100644 --- a/osirion.kdevses +++ b/osirion.kdevses @@ -1,7 +1,20 @@ - + + + + + + + + + + + + + + diff --git a/src/Makefile.am b/src/Makefile.am index 4815954..d4d3842 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,6 +1,5 @@ # set the include path found by configure AM_CPPFLAGS = $(DEBUG_CFLAGS) $(WARN_CFLAGS) $(all_includes) -INCLUDES = -I$(top_srcdir)/src SUBDIRS = math sys filesystem net core server render client game noinst_HEADERS = config.h diff --git a/src/client/client.cc b/src/client/client.cc index b93fe35..19d6f3e 100644 --- a/src/client/client.cc +++ b/src/client/client.cc @@ -60,7 +60,8 @@ void func_r_restart(std::stringstream &args) void main(int count, char **arguments) { - std::cout << "The Osirion Project " << VERSION << std::endl; + std::cout << core::name() << " " << core::version() << std::endl; + for (int i =0; i < count; i++) std::cout << arguments[i] << " "; std::cout << std::endl; diff --git a/src/core/Makefile.am b/src/core/Makefile.am index 6c42468..8a65e9a 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 gameserver.cc module.cc netclient.cc netconnection.cc \ - netserver.cc player.cc + func.cc gameconnection.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 gameserver.h module.h netconnection.h player.h + gameconnection.h gameinterface.h gameserver.h module.h netconnection.h player.h diff --git a/src/core/application.cc b/src/core/application.cc index 9c7620a..a95bd22 100644 --- a/src/core/application.cc +++ b/src/core/application.cc @@ -18,6 +18,7 @@ #include "core/cvar.h" #include "core/entity.h" #include "core/func.h" +#include "core/gameconnection.h" #include "core/gameserver.h" namespace core @@ -211,47 +212,30 @@ void Application::connect(std::string const &host) return; } - if (application_game) { delete application_game; application_game = 0; } if (host.size()) { - /* - // connect to remote core - core::GameInterface::gameinterface_instance = 0; - std::string remotehost(host); - size_t found = remotehost.find(':'); - unsigned int port = 8042; - if (found != std::string::npos) { - std::istringstream str(remotehost.substr(found+1)); - if (str >> port) { - remotehost.erase(found, std::string::npos); - } else { - con_print << "Invalid hostname '" << remotehost << "'\n"; - return; - } - } - netconnection.connect(remotehost, port); + application_game = new GameConnection(host); - if (netconnection.connected()) { - con_print << "Connected.\n"; + if (application_game->running()) { + con_print << "Connected to '" << host << "'\n"; } else { - netconnection.disconnect(); - con_warn << "Could not connect to '" << host << "'\n"; + delete application_game; + application_game = 0; + con_warn << "Could not connect to '" << host << "'!\n"; } - */ - con_warn << "Can not connect to remote core.... yet!\n"; } else { application_game = new GameServer(); if (application_game->running()) { - con_print << "Connected.\n"; + con_print << "Connected to local game.\n"; } else { delete application_game; application_game = 0; - con_warn << "Could not connect.\n"; + con_warn << "Could not connect to local game!\n"; } } } @@ -264,14 +248,6 @@ void Application::disconnect() application_game = 0; con_print << "Disconnected.\n"; } - - /* - if (netconnection.connected()) { - netconnection.disconnect(); - con_print << "Disconnected.\n"; - return; - } - */ } void Application::frame(float seconds) diff --git a/src/core/commandbuffer.cc b/src/core/commandbuffer.cc index 729c1db..5a7fbdb 100644 --- a/src/core/commandbuffer.cc +++ b/src/core/commandbuffer.cc @@ -11,6 +11,7 @@ #include "sys/sys.h" #include "core/application.h" #include "core/commandbuffer.h" +#include "core/gameconnection.h" #include "core/func.h" #include "core/cvar.h" @@ -102,8 +103,10 @@ void CommandBuffer::exec(std::string const &cmdline) } // TODO this must get forwarded to the server - - con_print << "Unknown command '" << command << "'\n"; + if (connection()) + connection()->forward(cmdline); + else + con_print << "Unknown command '" << command << "'\n"; } void CommandBuffer::exec() diff --git a/src/core/core.cc b/src/core/core.cc index b2327ee..c77087e 100644 --- a/src/core/core.cc +++ b/src/core/core.cc @@ -4,7 +4,25 @@ the terms of the GNU General Public License version 2. */ +#include + +#include "core.h" + namespace core { +std::string core_name("The Osirion Project"); +std::string core_version("0.1"); + +const std::string &name() +{ + return core_name; +} + +const std::string & version() +{ + return core_version; } + +} + diff --git a/src/core/core.h b/src/core/core.h index 2a23d84..ddf884f 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -7,10 +7,7 @@ #ifndef __INCLUDED_CORE_H__ #define __INCLUDED_CORE_H__ -/// core contains the basic functionality of the engine -namespace core -{ -} +#include #include "core/application.h" #include "core/commandbuffer.h" @@ -24,5 +21,17 @@ namespace core #include "core/netconnection.h" #include "core/player.h" +/// core contains the basic functionality of the engine +namespace core +{ + +// name of the engine core +const std::string & name(); + +// version of the engine core +const std::string & version(); + +} + #endif // __INCLUDED_CORE_H__ diff --git a/src/core/func.cc b/src/core/func.cc index ab3a404..afe4787 100644 --- a/src/core/func.cc +++ b/src/core/func.cc @@ -119,7 +119,7 @@ void Func::exec(Player *player, std::string const &args) { if (!(flags() & Game)) return; - + GameFuncPtr gamefunction = (GameFuncPtr) func_ptr; gamefunction(player, args); } diff --git a/src/core/gameconnection.cc b/src/core/gameconnection.cc new file mode 100644 index 0000000..43df1be --- /dev/null +++ b/src/core/gameconnection.cc @@ -0,0 +1,93 @@ +/* + core/gameconnection.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 "sys/sys.h" +#include "net/net.h" +#include "core/gameconnection.h" + +namespace core +{ + +GameConnection* GameConnection::connection_instance = 0; + +GameConnection::GameConnection(std::string const &connectionstr) +{ + connection_instance = this; + connection_network = 0; + connection_running = false; + + unsigned int port = net::DEFAULTPORT; + std::string host(connectionstr); + size_t found = host.find(':'); + + if (found != std::string::npos) { + std::istringstream str(host.substr(found+1)); + if (str >> port) { + host.erase(found, std::string::npos); + } else { + con_print << "Invalid hostname '" << host << "'\n"; + abort(); + return; + } + + } + + connection_network = new NetConnection(); + connection_network->connect(host, port); + + if (!connection_network->connected()) { + abort(); + return; + } + + connection_running = true; +} + +GameConnection::~GameConnection() +{ + if (connection_network) { + connection_network->disconnect(); + delete connection_network; + } + + connection_instance = 0; +} + +void GameConnection::abort() +{ + connection_running = false; +} + +void GameConnection::forward(std::string const &cmdline) +{ + + if (!connection_network->connected()) + return; + + std::string netmessage("cmd "); + netmessage.append(cmdline); + netmessage += '\n'; + connection_network->send(netmessage); +} + +void GameConnection::frame(float seconds) +{ + if (!running()) + return; + + if (!connection_network->connected()) { + abort(); + return; + } + + connection_network->frame(seconds); +} + +} + diff --git a/src/core/gameconnection.h b/src/core/gameconnection.h new file mode 100644 index 0000000..c91ef22 --- /dev/null +++ b/src/core/gameconnection.h @@ -0,0 +1,59 @@ +/* + core/gameconnection.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_GAMECONNECTION_H__ +#define __INCLUDED_CORE_GAMECONNECTION_H__ + +#include "core/gameinterface.h" +#include "core/netconnection.h" + +namespace core +{ + +/// a connection to a remote game +class GameConnection : public GameInterface +{ +public: + GameConnection(std::string const &connectionstr); + ~GameConnection(); + +/*----- inspectors ------------------------------------------------ */ + + /// returns true if the game connection can run a time frime + inline bool running() { return connection_running; } + + /// returns true if the game connection can not run a time frime + inline bool error() { return !connection_running; } + +/*----- mutators -------------------------------------------------- */ + + /// run a game connection time frame + void frame(float seconds); + + /// forward a command line to the remote server + void forward(std::string const &cmdline); + +/*----- static ---------------------------------------------------- */ + + /// return the current game connection + static inline GameConnection *instance() { return connection_instance; } + +protected: + /// abort runing + void abort(); + +private: + bool connection_running; + static GameConnection *connection_instance; + NetConnection *connection_network; + +}; + +inline GameConnection *connection() { return GameConnection::instance(); } + +} + +#endif // __INCLUDED_CORE_GAMECONNECTION_H__ diff --git a/src/core/gameserver.cc b/src/core/gameserver.cc index 6c84d3e..e5795ad 100644 --- a/src/core/gameserver.cc +++ b/src/core/gameserver.cc @@ -89,11 +89,6 @@ GameServer::~GameServer() server_instance = 0; } -bool GameServer::running() -{ - return server_running; -} - void GameServer::abort() { server_running = false; @@ -102,13 +97,13 @@ void GameServer::abort() void GameServer::say(Player *player, std::string const &message) { // send to console - con_print <name() << " " << message << "\n"; + 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(": "); netmessage.append(message); netmessage += '\n'; server_network->broadcast(netmessage); @@ -129,7 +124,7 @@ void GameServer::broadcast(std::string const & message, int ignoreplayer) } } -void GameServer::send(Player const *player, std::string message) +void GameServer::send(Player *player, std::string message) { // send to console if (player->id() == localplayer()->id()) { @@ -148,6 +143,35 @@ void GameServer::send(Player const *player, std::string message) } } +void GameServer::exec(Player *player, std::string const & cmdline) +{ + std::string command; + std::stringstream cmdstream; + cmdstream.str(cmdline); + cmdstream >> command; + + //con_debug << "Executing " << player->name() << ": " << cmdline << "\n"; + + Func *function = Func::find(command); + if (function ) { + + std::string args; + if (cmdline.size() > command.size() +1 ) + args.assign(cmdline.substr(command.size()+1)); + + if ((function ->flags() & Func::Game) == Func::Game) { + //con_debug << "About to execute " << function->name() << " " << args << "'\n"; + function->exec(player, args); + return; + } + } + + std::string message("Unknown command '"); + message.append(command); + message.append("'\n"); + send(player, message); +} + void GameServer::player_connect(Player *player) { std::string message(player->name()); diff --git a/src/core/gameserver.h b/src/core/gameserver.h index 32a37c3..d4bd0eb 100644 --- a/src/core/gameserver.h +++ b/src/core/gameserver.h @@ -27,7 +27,7 @@ public: /*----- inspectors ------------------------------------------------ */ /// returns true if the game server can run a time frime - bool running(); + inline bool running() { return server_running; } /// returns true if the game server can not run a time frime inline bool error() { return !server_running; } @@ -50,7 +50,10 @@ public: void broadcast(std::string const & message, int ignoreplayer = -1); /// send a message to a single player - void send(Player const *player, std::string message); + void send(Player *player, std::string message); + + /// a player sends a command to the game server + void exec(Player *player, std::string const &cmdline); /*----- static ---------------------------------------------------- */ @@ -60,6 +63,7 @@ public: protected: /// abort runing void abort(); + private: bool server_running; Module *server_module; diff --git a/src/core/netclient.h b/src/core/netclient.h index 04234da..f06f7c5 100644 --- a/src/core/netclient.h +++ b/src/core/netclient.h @@ -46,7 +46,9 @@ private: std::string client_host; int client_port; Player client_player; - + + std::string sendq; + std::string messageblock; std::deque recvq; }; diff --git a/src/core/netserver.cc b/src/core/netserver.cc index ba8510d..3473e6a 100644 --- a/src/core/netserver.cc +++ b/src/core/netserver.cc @@ -38,9 +38,7 @@ NetServer::~NetServer() for (it = clients.begin(); it != clients.end(); it++) { // notify the game server server()->player_disconnect((*it)->player()); - - con_print << " " << (*it)->host() << ":" << (*it)->port() << " disconnected.\n"; - + con_print << (*it)->host() << ":" << (*it)->port() << " disconnected.\n"; delete (*it); } clients.clear(); @@ -160,7 +158,7 @@ NetClient *NetServer::find_client(Player const *player) // parse server messages /** - * The following incoming messages are parsed; + * The following incoming protocol messages are parsed; * * disconnect * help @@ -182,6 +180,15 @@ void NetServer::parse_incoming_message(NetClient *client, const std::string & me return; } + // cmd + if (command == "cmd") { + if (message.size() > command.size()+1) { + std::string cmdline(message.substr(command.size()+1)); + server()->exec(client->player(), cmdline); + } + return; + } + // say if (command == "say") { if (message.size() > command.size()+1) { @@ -220,30 +227,14 @@ void NetServer::parse_incoming_message(NetClient *client, const std::string & me } if (command == "help") { - send(client, "msg info Available commands:\n"); + send(client, "msg info Available protocol messages:\n"); send(client, "msg info help - shows this help message\n"); - send(client, "msg info name nickname - changes your nickname\n"); - send(client, "msg info say text - say something on the public channel\n"); + send(client, "msg info name [nickname] - changes your nickname\n"); + send(client, "msg info say [text] - say something on the public channel\n"); + send(client, "msg info cmd [text] - execute a game command\n"); send(client, "msg info list_players - shows a list of connected players\n"); send(client, "msg info disconnect - disconnect\n"); } - - // execute game functions - 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); - } - } - } } diff --git a/src/core/netserver.h b/src/core/netserver.h index 8c3da65..dd44285 100644 --- a/src/core/netserver.h +++ b/src/core/netserver.h @@ -47,9 +47,6 @@ protected: /// parse incoming client messages void parse_incoming_message(NetClient *client, const std::string & message); - /// parse client variable - void parse_client_variable(NetClient * client, const std::string varname, std::istringstream &istringstream); - std::list clients; fd_set serverset; int fdmax; diff --git a/src/net/net.h b/src/net/net.h index ab6594d..cdcf4bb 100644 --- a/src/net/net.h +++ b/src/net/net.h @@ -17,6 +17,8 @@ const unsigned int FRAMESIZE = 1152; /// maximum number of pending client connections, hard limit const unsigned int MAXPENDINGCONNECTIONS = 32; +/// default network port +const unsigned int DEFAULTPORT = 8042; } #endif // __INCLUDED_NET_H__ diff --git a/src/net/tcpconnection.cc b/src/net/tcpconnection.cc index e4ff009..0aa4fe6 100644 --- a/src/net/tcpconnection.cc +++ b/src/net/tcpconnection.cc @@ -160,7 +160,7 @@ void TCPConnection::send(std::string const &msg) return; if (msg.size() > FRAMESIZE) { - con_warn << "Network message exceeds " << FRAMESIZE << " bytes!" << std::endl; + con_warn << "Network message exceeds " << FRAMESIZE << " bytes!\n"; return; } diff --git a/src/server/server.cc b/src/server/server.cc index 5c50bcb..4c087b8 100644 --- a/src/server/server.cc +++ b/src/server/server.cc @@ -36,7 +36,8 @@ Server app; /// the server main loop void main(int count, char **arguments) { - std::cout << "The Osirion Project " << VERSION << std::endl; + std::cout << core::name() << " " << core::version() << std::endl; + for (int i =0; i < count; i++) std::cout << arguments[i] << " "; std::cout << std::endl; -- cgit v1.2.3