From 7f7fb9750df3aceec48f65cee657e15364e0a911 Mon Sep 17 00:00:00 2001 From: Perttu Ahola Date: Sun, 11 Mar 2012 14:54:23 +0200 Subject: [PATCH] command-line/world game selection --- src/CMakeLists.txt | 1 + src/game.cpp | 8 +++-- src/game.h | 7 ++-- src/main.cpp | 74 ++++++++++++++++++++++++++++++++--------- src/server.cpp | 56 +++++++++++-------------------- src/server.h | 18 ++++------ src/subgame.cpp | 82 ++++++++++++++++++++++++++++++++++++++++++++++ src/subgame.h | 53 ++++++++++++++++++++++++++++++ 8 files changed, 231 insertions(+), 68 deletions(-) create mode 100644 src/subgame.cpp create mode 100644 src/subgame.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e1cfcfa09..e9fddf8c0 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -94,6 +94,7 @@ configure_file( ) set(common_SRCS + subgame.cpp inventorymanager.cpp mods.cpp serverremoteplayer.cpp diff --git a/src/game.cpp b/src/game.cpp index 0e3f570f4..ebf5028b7 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -51,6 +51,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "itemdef.h" #include "tile.h" // For TextureSource #include "logoutputbuffer.h" +#include "subgame.h" /* Setting this to 1 enables a special camera mode that forces @@ -651,11 +652,12 @@ void the_game( std::string map_dir, std::string playername, std::string password, - std::string address, + std::string address, // If "", local server is used u16 port, std::wstring &error_message, std::string configpath, - ChatBackend &chat_backend + ChatBackend &chat_backend, + const SubgameSpec &gamespec // Used for local game ) { video::IVideoDriver* driver = device->getVideoDriver(); @@ -705,7 +707,7 @@ void the_game( if(address == ""){ draw_load_screen(L"Creating server...", driver, font); infostream<<"Creating server"<start(port); } diff --git a/src/game.h b/src/game.h index 01e955ecd..4ca5a2433 100644 --- a/src/game.h +++ b/src/game.h @@ -22,7 +22,6 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "common_irrlicht.h" #include - #include "keycode.h" class KeyList : protected core::list @@ -123,6 +122,7 @@ public: }; class ChatBackend; /* to avoid having to include chat.h */ +struct SubgameSpec; void the_game( bool &kill, @@ -133,11 +133,12 @@ void the_game( std::string map_dir, std::string playername, std::string password, - std::string address, + std::string address, // If "", local server is used u16 port, std::wstring &error_message, std::string configpath, - ChatBackend &chat_backend + ChatBackend &chat_backend, + const SubgameSpec &gamespec // Used for local game ); #endif diff --git a/src/main.cpp b/src/main.cpp index 8b2ef3668..00776d89c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -69,6 +69,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "log.h" #include "mods.h" #include "utility_string.h" +#include "subgame.h" /* Settings. @@ -781,6 +782,8 @@ int main(int argc, char *argv[]) "Print more information to console")); allowed_options.insert("logfile", ValueSpec(VALUETYPE_STRING, "Set logfile path (debug.txt)")); + allowed_options.insert("gameid", ValueSpec(VALUETYPE_STRING, + "Set gameid")); #ifndef SERVER allowed_options.insert("speedtests", ValueSpec(VALUETYPE_FLAG, "Run speed tests")); @@ -958,22 +961,63 @@ int main(int argc, char *argv[]) port = 30000; // Map directory - std::string map_dir = porting::path_user + DIR_DELIM + "server" + DIR_DELIM + "worlds" + DIR_DELIM + "world"; - if(cmd_args.exists("map-dir")) - map_dir = cmd_args.get("map-dir"); + std::string world_path = porting::path_user + DIR_DELIM + "server" + DIR_DELIM + "worlds" + DIR_DELIM + "world"; + if(cmd_args.exists("world")) + world_path = cmd_args.get("world"); + else if(cmd_args.exists("map-dir")) + world_path = cmd_args.get("map-dir"); else if(g_settings->exists("map-dir")) - map_dir = g_settings->get("map-dir"); + world_path = g_settings->get("map-dir"); else{ // No map-dir option was specified. // Check if the world is found from the default directory, and if // not, see if the legacy world directory exists. - std::string legacy_map_dir = porting::path_user+DIR_DELIM+".."+DIR_DELIM+"world"; - if(!fs::PathExists(map_dir) && fs::PathExists(legacy_map_dir)){ + std::string legacy_world_path = porting::path_user+DIR_DELIM+".."+DIR_DELIM+"world"; + if(!fs::PathExists(world_path) && fs::PathExists(legacy_world_path)){ errorstream<<"Warning: Using legacy world directory \"" - < gameids = getAvailableGameIds(); + infostream<<"Available gameids: "; + for(std::set::const_iterator i = gameids.begin(); + i != gameids.end(); i++) + infostream<<(*i)<<" "; + infostream<setMinHardwareBufferVertexCount(50); - // Set the window caption - device->setWindowCaption(L"Minetest [Main Menu]"); - // Create time getter g_timegetter = new IrrlichtTimeGetter(device); @@ -1154,6 +1195,8 @@ int main(int argc, char *argv[]) */ while(device->run() && kill == false) { + // Set the window caption + device->setWindowCaption(L"Minetest [Main Menu]"); // This is used for catching disconnects try @@ -1257,7 +1300,7 @@ int main(int argc, char *argv[]) // Delete map if requested if(menudata.delete_map) { - bool r = fs::RecursiveDeleteContent(map_dir); + bool r = fs::RecursiveDeleteContent(world_path); if(r == false) error_message = L"Delete failed"; continue; @@ -1303,14 +1346,15 @@ int main(int argc, char *argv[]) input, device, font, - map_dir, + world_path, playername, password, address, port, error_message, configpath, - chat_backend + chat_backend, + gamespec ); } //try diff --git a/src/server.cpp b/src/server.cpp index 8f40cfa5b..7b34e3554 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -830,13 +830,13 @@ void PlayerInfo::PrintLine(std::ostream *s) */ Server::Server( - std::string path_world, - std::string path_config, - std::string gamename + const std::string &path_world, + const std::string &path_config, + const SubgameSpec &gamespec ): - m_gamename(gamename), m_path_world(path_world), m_path_config(path_config), + m_gamespec(gamespec), m_env(NULL), m_con(PROTOCOL_ID, 512, CONNECTION_TIMEOUT, this), m_authmanager(path_world+DIR_DELIM+"auth.txt"), @@ -865,55 +865,38 @@ Server::Server( m_step_dtime_mutex.Init(); m_step_dtime = 0.0; + if(!gamespec.isValid()) + throw ServerError("Supplied invalid gamespec"); + // Figure out some paths // share/server m_path_share = porting::path_share + DIR_DELIM + "server"; - // game - m_path_game = porting::path_user + DIR_DELIM + "server" + DIR_DELIM - + "games" + DIR_DELIM + m_gamename; - bool user_game = true; // Game is in user's directory - if(!fs::PathExists(m_path_game)){ - m_path_game = m_path_share + DIR_DELIM + "games" + DIR_DELIM - + m_gamename; - user_game = false; - } - if(!fs::PathExists(m_path_game)){ - throw ServerError("Could not find game files for game \"" - +gamename+"\""); - } - // addons - if(!user_game) - m_path_addons.insert(m_path_share + DIR_DELIM + "addons" - + DIR_DELIM + m_gamename); - m_path_addons.insert(porting::path_user + DIR_DELIM + "server" - + DIR_DELIM + "addons" + DIR_DELIM + m_gamename); - infostream<<"Server created for gamename=\""<::const_iterator i = m_gamespec.addon_paths.begin(); + i != m_gamespec.addon_paths.end(); i++) + infostream<<"- addons: "<<(*i)<::const_iterator i = m_path_addons.begin(); - i != m_path_addons.end(); i++){ + for(std::set::const_iterator i = m_gamespec.addon_paths.begin(); + i != m_gamespec.addon_paths.end(); i++) m_modspaths.push_front((*i) + DIR_DELIM + "mods"); - } // Print out mod search paths for(core::list::Iterator i = m_modspaths.begin(); i != m_modspaths.end(); i++){ std::string modspath = *i; - infostream<<"- modspath += "<__| \\___ >____ > |__| "< m_path_addons; // Some timers float m_liquid_transform_timer; diff --git a/src/subgame.cpp b/src/subgame.cpp new file mode 100644 index 000000000..ed50d09a4 --- /dev/null +++ b/src/subgame.cpp @@ -0,0 +1,82 @@ +/* +Minetest-c55 +Copyright (C) 2012 celeron55, Perttu Ahola + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "subgame.h" +#include "porting.h" +#include "filesys.h" +#include "settings.h" + +SubgameSpec findSubgame(const std::string &id) +{ + if(id == "") + return SubgameSpec(); + std::string share_server = porting::path_share + DIR_DELIM + "server"; + std::string user_server = porting::path_user + DIR_DELIM + "server"; + // Find game directory + std::string game_path = + user_server + DIR_DELIM + "games" + DIR_DELIM + id; + bool user_game = true; // Game is in user's directory + if(!fs::PathExists(game_path)){ + game_path = share_server + DIR_DELIM + "games" + DIR_DELIM + id; + user_game = false; + } + if(!fs::PathExists(game_path)) + return SubgameSpec(); + // Find addon directories + std::set addon_paths; + if(!user_game) + addon_paths.insert(share_server + DIR_DELIM + "addons" + + DIR_DELIM + id); + addon_paths.insert(user_server + DIR_DELIM + "addons" + + DIR_DELIM + id); + return SubgameSpec(id, game_path, addon_paths); +} + +std::set getAvailableGameIds() +{ + std::set gameids; + std::set gamespaths; + gamespaths.insert(porting::path_share + DIR_DELIM + "server" + + DIR_DELIM + "games"); + gamespaths.insert(porting::path_user + DIR_DELIM + "server" + + DIR_DELIM + "games"); + for(std::set::const_iterator i = gamespaths.begin(); + i != gamespaths.end(); i++){ + std::vector dirlist = fs::GetDirListing(*i); + for(u32 j=0; j + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifndef SUBGAME_HEADER +#define SUBGAME_HEADER + +#include +#include + +struct SubgameSpec +{ + std::string id; // "" = game does not exist + std::string path; + std::set addon_paths; + + SubgameSpec(const std::string &id_="", + const std::string &path_="", + const std::set &addon_paths_=std::set()): + id(id_), + path(path_), + addon_paths(addon_paths_) + {} + + bool isValid() const + { + return (id != "" && path != ""); + } +}; + +SubgameSpec findSubgame(const std::string &id); + +std::set getAvailableGameIds(); + +std::string getWorldGameId(const std::string &world_path); + +#endif +