diff options
Diffstat (limited to 'src/content')
-rw-r--r-- | src/content/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/content/packages.cpp | 69 | ||||
-rw-r--r-- | src/content/packages.h | 52 | ||||
-rw-r--r-- | src/content/subgames.cpp | 82 | ||||
-rw-r--r-- | src/content/subgames.h | 8 |
5 files changed, 67 insertions, 145 deletions
diff --git a/src/content/CMakeLists.txt b/src/content/CMakeLists.txt index 5adcf6b1e..6dd049418 100644 --- a/src/content/CMakeLists.txt +++ b/src/content/CMakeLists.txt @@ -1,6 +1,5 @@ set(content_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/content.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/packages.cpp ${CMAKE_CURRENT_SOURCE_DIR}/mods.cpp ${CMAKE_CURRENT_SOURCE_DIR}/subgames.cpp PARENT_SCOPE diff --git a/src/content/packages.cpp b/src/content/packages.cpp deleted file mode 100644 index 2d488eb76..000000000 --- a/src/content/packages.cpp +++ /dev/null @@ -1,69 +0,0 @@ -/* -Minetest -Copyright (C) 2018 rubenwardy <rw@rubenwardy.com> - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser 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 "content/packages.h" -#include "log.h" -#include "filesys.h" -#include "porting.h" -#include "settings.h" -#include "content/mods.h" -#include "content/subgames.h" - -std::string Package::getDownloadURL(const std::string &baseURL) const -{ - return baseURL + "/packages/" + author + "/" + name + "/releases/" + - std::to_string(release) + "/download/"; -} - -#if USE_CURL -std::vector<Package> getPackagesFromURL(const std::string &url) -{ - std::vector<std::string> extra_headers; - extra_headers.emplace_back("Accept: application/json"); - - Json::Value json = fetchJsonValue(url, &extra_headers); - if (!json.isArray()) { - errorstream << "Invalid JSON download " << std::endl; - return std::vector<Package>(); - } - - std::vector<Package> packages; - - // Note: `unsigned int` is required to index JSON - for (unsigned int i = 0; i < json.size(); ++i) { - Package package; - - package.author = json[i]["author"].asString(); - package.name = json[i]["name"].asString(); - package.title = json[i]["title"].asString(); - package.type = json[i]["type"].asString(); - package.shortDesc = json[i]["shortDesc"].asString(); - package.release = json[i]["release"].asInt(); - if (json[i].isMember("thumbnail")) - package.thumbnail = json[i]["thumbnail"].asString(); - - if (package.valid()) - packages.push_back(package); - else - errorstream << "Invalid package at " << i << std::endl; - } - - return packages; -} -#endif diff --git a/src/content/packages.h b/src/content/packages.h deleted file mode 100644 index 9029475ef..000000000 --- a/src/content/packages.h +++ /dev/null @@ -1,52 +0,0 @@ -/* -Minetest -Copyright (C) 2018 rubenwardy <rw@rubenwardy.com> - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser 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. -*/ - -#pragma once -#include "config.h" -#include "convert_json.h" -#include "irrlichttypes.h" - -struct Package -{ - std::string author; - std::string name; // Technical name - std::string title; - std::string type; // One of "mod", "game", or "txp" - - std::string shortDesc; - u32 release; - std::string thumbnail; - - bool valid() const - { - return !(author.empty() || name.empty() || title.empty() || - type.empty() || release <= 0); - } - - std::string getDownloadURL(const std::string &baseURL) const; -}; - -#if USE_CURL -std::vector<Package> getPackagesFromURL(const std::string &url); -#else -inline std::vector<Package> getPackagesFromURL(const std::string &url) -{ - return std::vector<Package>(); -} -#endif diff --git a/src/content/subgames.cpp b/src/content/subgames.cpp index 170f54e20..e9dc609b0 100644 --- a/src/content/subgames.cpp +++ b/src/content/subgames.cpp @@ -31,12 +31,20 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "client/tile.h" // getImagePath #endif +// The maximum number of identical world names allowed +#define MAX_WORLD_NAMES 100 + +namespace +{ + bool getGameMinetestConfig(const std::string &game_path, Settings &conf) { std::string conf_path = game_path + DIR_DELIM + "minetest.conf"; return conf.readConfigFile(conf_path.c_str()); } +} + struct GameFindPath { std::string path; @@ -213,6 +221,21 @@ bool getWorldExists(const std::string &world_path) fs::PathExists(world_path + DIR_DELIM + "world.mt")); } +//! Try to get the displayed name of a world +std::string getWorldName(const std::string &world_path, const std::string &default_name) +{ + std::string conf_path = world_path + DIR_DELIM + "world.mt"; + Settings conf; + bool succeeded = conf.readConfigFile(conf_path.c_str()); + if (!succeeded) { + return default_name; + } + + if (!conf.exists("world_name")) + return default_name; + return conf.get("world_name"); +} + std::string getWorldGameId(const std::string &world_path, bool can_be_legacy) { std::string conf_path = world_path + DIR_DELIM + "world.mt"; @@ -259,7 +282,7 @@ std::vector<WorldSpec> getAvailableWorlds() if (!dln.dir) continue; std::string fullpath = worldspath + DIR_DELIM + dln.name; - std::string name = dln.name; + std::string name = getWorldName(fullpath, dln.name); // Just allow filling in the gameid always for now bool can_be_legacy = true; std::string gameid = getWorldGameId(fullpath, can_be_legacy); @@ -288,27 +311,45 @@ std::vector<WorldSpec> getAvailableWorlds() return worlds; } -bool loadGameConfAndInitWorld(const std::string &path, const SubgameSpec &gamespec) +void loadGameConfAndInitWorld(const std::string &path, const std::string &name, + const SubgameSpec &gamespec, bool create_world) { - // Override defaults with those provided by the game. - // We clear and reload the defaults because the defaults - // might have been overridden by other subgame config - // files that were loaded before. - g_settings->clearDefaults(); - set_default_settings(g_settings); - Settings game_defaults; - getGameMinetestConfig(gamespec.path, game_defaults); - g_settings->overrideDefaults(&game_defaults); + std::string final_path = path; + + // If we're creating a new world, ensure that the path isn't already taken + if (create_world) { + int counter = 1; + while (fs::PathExists(final_path) && counter < MAX_WORLD_NAMES) { + final_path = path + "_" + std::to_string(counter); + counter++; + } - infostream << "Initializing world at " << path << std::endl; + if (fs::PathExists(final_path)) { + throw BaseException("Too many similar filenames"); + } + } - fs::CreateAllDirs(path); + Settings *game_settings = Settings::getLayer(SL_GAME); + const bool new_game_settings = (game_settings == nullptr); + if (new_game_settings) { + // Called by main-menu without a Server instance running + // -> create and free manually + game_settings = Settings::createLayer(SL_GAME); + } + + getGameMinetestConfig(gamespec.path, *game_settings); + game_settings->removeSecureSettings(); + + infostream << "Initializing world at " << final_path << std::endl; + + fs::CreateAllDirs(final_path); // Create world.mt if does not already exist - std::string worldmt_path = path + DIR_DELIM "world.mt"; + std::string worldmt_path = final_path + DIR_DELIM "world.mt"; if (!fs::PathExists(worldmt_path)) { Settings conf; + conf.set("world_name", name); conf.set("gameid", gamespec.id); conf.set("backend", "sqlite3"); conf.set("player_backend", "sqlite3"); @@ -316,16 +357,16 @@ bool loadGameConfAndInitWorld(const std::string &path, const SubgameSpec &gamesp conf.setBool("creative_mode", g_settings->getBool("creative_mode")); conf.setBool("enable_damage", g_settings->getBool("enable_damage")); - if (!conf.updateConfigFile(worldmt_path.c_str())) - return false; + if (!conf.updateConfigFile(worldmt_path.c_str())) { + throw BaseException("Failed to update the config file"); + } } // Create map_meta.txt if does not already exist - std::string map_meta_path = path + DIR_DELIM + "map_meta.txt"; + std::string map_meta_path = final_path + DIR_DELIM + "map_meta.txt"; if (!fs::PathExists(map_meta_path)) { verbosestream << "Creating map_meta.txt (" << map_meta_path << ")" << std::endl; - fs::CreateAllDirs(path); std::ostringstream oss(std::ios_base::binary); Settings conf; @@ -338,5 +379,8 @@ bool loadGameConfAndInitWorld(const std::string &path, const SubgameSpec &gamesp fs::safeWriteToFile(map_meta_path, oss.str()); } - return true; + + // The Settings object is no longer needed for created worlds + if (new_game_settings) + delete game_settings; } diff --git a/src/content/subgames.h b/src/content/subgames.h index 4198ea860..60392639b 100644 --- a/src/content/subgames.h +++ b/src/content/subgames.h @@ -53,9 +53,6 @@ struct SubgameSpec bool isValid() const { return (!id.empty() && !path.empty()); } }; -// minetest.conf -bool getGameMinetestConfig(const std::string &game_path, Settings &conf); - SubgameSpec findSubgame(const std::string &id); SubgameSpec findWorldSubgame(const std::string &world_path); @@ -63,6 +60,8 @@ std::set<std::string> getAvailableGameIds(); std::vector<SubgameSpec> getAvailableGames(); bool getWorldExists(const std::string &world_path); +//! Try to get the displayed name of a world +std::string getWorldName(const std::string &world_path, const std::string &default_name); std::string getWorldGameId(const std::string &world_path, bool can_be_legacy = false); struct WorldSpec @@ -88,4 +87,5 @@ std::vector<WorldSpec> getAvailableWorlds(); // loads the subgame's config and creates world directory // and world.mt if they don't exist -bool loadGameConfAndInitWorld(const std::string &path, const SubgameSpec &gamespec); +void loadGameConfAndInitWorld(const std::string &path, const std::string &name, + const SubgameSpec &gamespec, bool create_world); |