From d6ee7ec642cc6b3097c8d321a1a00630e24027d1 Mon Sep 17 00:00:00 2001 From: Stijn Buys Date: Sat, 16 Feb 2008 12:22:33 +0000 Subject: initial client-to-server connection --- src/core/application.cc | 255 +++++++++++++++++++++++++++++++++++++----------- 1 file changed, 196 insertions(+), 59 deletions(-) (limited to 'src/core/application.cc') diff --git a/src/core/application.cc b/src/core/application.cc index 2d29fad..55f8fc2 100644 --- a/src/core/application.cc +++ b/src/core/application.cc @@ -25,6 +25,7 @@ namespace core { Cvar sv_dedicated; +Cvar sv_private; Cvar net_host; Cvar net_port; @@ -56,13 +57,18 @@ void func_quit(std::stringstream &args) void func_connect(std::stringstream &args) { - if (Application::instance()) - Application::instance()->connect(); + std::string host; + if (!(args >> host)) + host.clear(); + + if (Application::instance()) { + Application::instance()->connect(host); + } } void func_disconnect(std::stringstream &args) { - if (Application::instance()) + if (Application::instance()) Application::instance()->disconnect(); } @@ -80,6 +86,54 @@ void func_list_ent(std::stringstream &args) { entity::list(); } + +void func_say(std::stringstream &args) +{ + if (application()->netserver) { + std::ostringstream osstream; + osstream << "msg public " << localplayer.name << " " << args.str() << "\n"; + application()->netserver->broadcast(osstream); + con_print << localplayer.name << ": " << args.str() << std::endl; + } else if (application()->netconnection.connected()) { + std::ostringstream osstream; + osstream << args.str() << std::endl; + application()->netconnection.send(osstream.str()); + } else if (game() && game()->connected) { + con_print << args.str() << std::endl; + } else + con_print << "Not connected."; +} + +void func_name(std::stringstream &args) { + std::string name; + if (args >> name) { + if (name.size() > 16) + name = name.substr(0,16); + } else { + con_print << "name " << localplayer.name << std::endl; + return; + } + + if (name == localplayer.name) { + con_print << "name " << name << std::endl; + return; + } + + if (application()->netserver) { + std::ostringstream osstream; + osstream << "msg info " << localplayer.name << " renamed to " << name << "\n"; + application()->netserver->broadcast(osstream); + con_print << "name " << name << std::endl; + } else if (application()->netconnection.connected()) { + std::ostringstream osstream; + osstream << args.str() << std::endl; + application()->netconnection.send(osstream.str()); + } else { + con_print << "name " << name << std::endl; + } + localplayer.name = name; +} + // --------------- signal_handler ----------------------------------- extern "C" void signal_handler(int signum) @@ -111,14 +165,15 @@ Application *Application::application_instance = 0; Application::Application() { - netserver = 0; - if (application_instance) { std::cerr << "multiple core::Application instances!" << std::endl; sys::quit(2); } + application_instance = this; - + netserver = 0; + gameinterface_preload = 0; + sys::signal(SIGHUP, signal_handler); sys::signal(SIGINT, signal_handler); sys::signal(SIGQUIT, signal_handler); @@ -128,27 +183,48 @@ 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() { - con_print << "Initializing core..." << std::endl; con_debug << "Debug messages enabled" << std::endl; + con_print << "Initializing core..." << std::endl; - // initialize core subsystems filesystem::init(); - // dedicated or not, client should have set this to 0 + gameinterface_preload = core::GameInterface::gameinterface_instance; + core::GameInterface::gameinterface_instance = 0; + if (gameinterface_preload) { + con_print << " preloaded game found: " << gameinterface_preload->name << std::endl; + } + game_time = 0; + + // dedicated server, client should have set this to 0 core::sv_dedicated = core::cvar::get("sv_dedicated", "1", core::cvar::ReadOnly); + + // private server for the client, server should have set this to 0 + core::sv_private = core::cvar::get("sv_private", "0"); + if (sv_dedicated->value()) localplayer.name = "Console"; else - localplayer.name = "Player"; + localplayer.name = "Player0"; // network settings core::net_host = core::cvar::get("net_host", "0.0.0.0"); @@ -166,9 +242,8 @@ void Application::init() func::add("list_func", func_list_func); func::add("list_ent", func_list_ent); - if (game()) - game()->connected = false; - current_time = 0; + func::add("say", func_say); + func::add("name", func_name); } void Application::shutdown() @@ -191,74 +266,136 @@ void Application::quit(int status) sys::quit(status); } -void Application::connect() +void Application::connect(std::string const &host) { - if (!game()) { - con_warn << "No game module loaded!" << std::endl; + if (game() && game()->connected || netconnection.connected()) { + con_warn << "Connected. Disconnect first." << std::endl; return; } - if (game()->connected) { - con_warn << "Connected. Disconnect first." << std::endl; + if (game()) { + // unload previous game + if (game() != gameinterface_preload) + delete core::GameInterface::gameinterface_instance; } - - entity::clear(); - game()->current_time = 0; - - if (game()->connected = game()->init()) { - con_print << "Connected." << std::endl; + + 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 << "'" << std::endl; + return; + } + } + netconnection.connect(remotehost, port); + + if (netconnection.connected()) { + con_print << "Connected." << std::endl; + } else { + netconnection.disconnect(); + con_warn << "Could not connect to '" << host << "'" << std::endl; + } } else { - con_warn << "Connect failed." << std::endl; - return; - } - if (core::sv_dedicated->value() && !netserver) { - netserver = new NetServer(net_host->text(), (unsigned int)net_port->value()); + // use preloaded game + core::GameInterface::gameinterface_instance = gameinterface_preload; + + // reset everything + entity::clear(); + game_time = 0; + + if (game()->connected = game()->init()) { + con_print << "Connected." << std::endl; + } else { + con_warn << "Could not connect." << std::endl; + return; + } + + if (!netserver && (core::sv_dedicated->value() || core::sv_private->value())) { + netserver = new NetServer(net_host->text(), (unsigned int)net_port->value()); + if (!netserver->valid()) { + delete netserver; + if (core::sv_dedicated->value()) + shutdown(); + } + } } } void Application::disconnect() { - if (!game()) { - con_warn << "No game module loaded!" << std::endl; - return; + if (netserver) { + delete netserver; + netserver = 0; } - - if (!game()->connected) { - con_warn << "Not connected." << std::endl; + + if (netconnection.connected()) { + netconnection.disconnect(); + con_print << "Disconnected." << std::endl; return; } - game()->shutdown(); - - game()->connected = false; - game()->current_time = 0; + if (game()) { + if (!game()->connected) { + con_warn << "Not connected." << std::endl; + return; + } + + game()->shutdown(); + game()->connected = false; + game_time = 0; - // remove all entities - entity::clear(); - - // TODO remove all game functions - - // TODO remove all game cvars + // remove all entities + entity::clear(); + + // remove all game functions + for (std::map::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); + } + } - con_print << "Disconnected." << std::endl; + // remove all game cvars + for (std::map::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); + } + } + + con_print << "Disconnected." << std::endl; + } } void Application::frame(float seconds) { - current_time += seconds; + if (seconds == 0.0f) + return; - if (netserver) { - // TODO limit netserver frames in local mode - netserver->frame(seconds); - } + 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); + } - if (game() && game()->connected) { - entity::frame(seconds); - - game()->current_time += seconds; - game()->frame(seconds); - } - + if (game() && game()->connected) { + entity::frame(seconds); + game_time += seconds; + + game()->frame(seconds); + } + } // execute commands in the buffer commandbuffer::execute(); -- cgit v1.2.3