diff options
-rw-r--r-- | src/CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/client.cpp | 463 | ||||
-rw-r--r-- | src/client.h | 22 | ||||
-rw-r--r-- | src/dirs.cpp | 491 | ||||
-rw-r--r-- | src/dirs.h | 56 |
6 files changed, 565 insertions, 471 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index dd24d7ae2..819b5372a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -743,6 +743,8 @@ SET(SRCS debug.h defaults.cpp defaults.h + dirs.cpp + dirs.h dragdrop.h effectmanager.cpp effectmanager.h diff --git a/src/Makefile.am b/src/Makefile.am index 072bc6949..f81145e6a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -858,6 +858,8 @@ manaplus_SOURCES += gui/widgets/avatarlistbox.cpp \ debug.h \ defaults.cpp \ defaults.h \ + dirs.cpp \ + dirs.h \ dragdrop.h \ dropshortcut.cpp \ dropshortcut.h \ diff --git a/src/client.cpp b/src/client.cpp index 454573ac6..c0733c50b 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -27,6 +27,7 @@ #include "auctionmanager.h" #include "chatlogger.h" #include "configuration.h" +#include "dirs.h" #include "dropshortcut.h" #include "emoteshortcut.h" #include "eventsmanager.h" @@ -255,9 +256,9 @@ void Client::testsInit() else { logger = new Logger; - initLocalDataDir(); - initTempDir(); - initConfigDir(); + Dirs::initLocalDataDir(); + Dirs::initTempDir(); + Dirs::initConfigDir(); } } @@ -270,8 +271,8 @@ void Client::gameInit() branding.init(settings.options.brandingPath); branding.setDefaultValues(getBrandingDefaults()); - initRootDir(); - initHomeDir(); + Dirs::initRootDir(); + Dirs::initHomeDir(); // Configure logger if (!settings.options.logFileName.empty()) @@ -322,7 +323,7 @@ void Client::gameInit() logger->log1(FULL_VERSION); logger->log("Start configPath: " + config.getConfigPath()); - initScreenshotDir(); + Dirs::initScreenshotDir(); // Initialize SDL logger->log1("Initializing SDL..."); @@ -347,8 +348,8 @@ void Client::gameInit() SDL_EventState(SDL_USEREVENT, SDL_IGNORE); #ifdef WIN32 - extractDataDir(); - mountDataDir(); + Dirs::extractDataDir(); + Dirs::mountDataDir(); #endif setIcon(); @@ -368,11 +369,11 @@ void Client::gameInit() initGraphics(); #ifndef WIN32 - extractDataDir(); - mountDataDir(); + Dirs::extractDataDir(); + Dirs::mountDataDir(); #endif - updateDataPath(); + Dirs::updateDataPath(); // Add the main data directories to our PhysicsFS search path if (!settings.options.dataPath.empty()) @@ -536,24 +537,6 @@ void Client::updateEnv() setEnv("SDL_VIDEO_ALLOW_SCREENSAVER", "0"); } -void Client::updateDataPath() -{ - if (settings.options.dataPath.empty() - && !branding.getStringValue("dataPath").empty()) - { - if (isRealPath(branding.getStringValue("dataPath"))) - { - settings.options.dataPath = branding.getStringValue("dataPath"); - } - else - { - settings.options.dataPath = branding.getDirectory().append(dirSeparator) - + branding.getStringValue("dataPath"); - } - settings.options.skipUpdate = true; - } -} - void Client::initGraphics() { graphicsManager.initGraphics(settings.options.noOpenGL); @@ -611,91 +594,6 @@ static void setProgress(const int val) #endif #endif -void Client::extractDataDir() -{ -#ifdef ANDROID -#ifdef USE_SDL2 - Files::setCopyCallBack(&updateProgress); - setProgress(0); - extractAssets(); - - const std::string zipName = std::string(getenv( - "APPDIR")).append("/data.zip"); - const std::string dirName = std::string(getenv( - "APPDIR")).append("/data"); - Files::extractZip(zipName, "data", dirName); - Files::extractLocale(); -#endif -#endif - -#if defined __native_client__ - const std::string dirName = _nacl_dir.append("/data"); - Files::extractZip("/http/data.zip", "data", dirName); -#endif -} - -void Client::mountDataDir() -{ - const ResourceManager *const resman = ResourceManager::getInstance(); - resman->addToSearchPath(PKG_DATADIR "data/perserver/default", false); - resman->addToSearchPath("data/perserver/default", false); - -#if defined __APPLE__ - CFBundleRef mainBundle = CFBundleGetMainBundle(); - CFURLRef resourcesURL = CFBundleCopyResourcesDirectoryURL(mainBundle); - char path[PATH_MAX]; - if (!CFURLGetFileSystemRepresentation(resourcesURL, TRUE, (uint8_t*)path, - PATH_MAX)) - { - fprintf(stderr, "Can't find Resources directory\n"); - } - CFRelease(resourcesURL); - // possible crash - strncat(path, "/data", PATH_MAX - 1); - resman->addToSearchPath(path, false); -// possible this need for support run client from dmg images. -// mPackageDir = path; -#endif - resman->addToSearchPath(PKG_DATADIR "data", false); - setPackageDir(PKG_DATADIR "data"); - resman->addToSearchPath("data", false); - -#ifdef ANDROID -#ifdef USE_SDL2 - if (getenv("APPDIR")) - { - const std::string appDir = getenv("APPDIR"); - resman->addToSearchPath(appDir + "/data", false); - resman->addToSearchPath(appDir + "/data/perserver/default", false); - } -#endif -#endif - -#if defined __native_client__ - resman->addToSearchPath(_nacl_dir.append("/data"), false); -#endif - - // Add branding/data to PhysFS search path - if (!settings.options.brandingPath.empty()) - { - std::string path = settings.options.brandingPath; - - // Strip blah.manaplus from the path -#ifdef WIN32 - const int loc1 = path.find_last_of('/'); - const int loc2 = path.find_last_of('\\'); - const int loc = static_cast<int>(std::max(loc1, loc2)); -#else - const int loc = static_cast<int>(path.find_last_of('/')); -#endif - if (loc > 0) - { - resman->addToSearchPath(path.substr( - 0, loc + 1).append("data"), false); - } - } -} - void Client::initLang() { #ifdef ENABLE_NLS @@ -1349,7 +1247,7 @@ int Client::gameExec() settings.updateHost = settings.options.updateHost; else settings.updateHost = loginData.updateHost; - initUpdatesDir(); + Dirs::initUpdatesDir(); if (!settings.oldUpdates.empty()) UpdaterWindow::unloadUpdates(settings.oldUpdates); @@ -1874,170 +1772,6 @@ void Client::action(const ActionEvent &event) } } -void Client::initRootDir() -{ - settings.rootDir = PhysFs::getBaseDir(); - const std::string portableName = settings.rootDir + "portable.xml"; - struct stat statbuf; - - if (!stat(portableName.c_str(), &statbuf) && S_ISREG(statbuf.st_mode)) - { - std::string dir; - Configuration portable; - portable.init(portableName); - - if (settings.options.brandingPath.empty()) - { - branding.init(portableName); - branding.setDefaultValues(getBrandingDefaults()); - } - - logger->log("Portable file: %s", portableName.c_str()); - - if (settings.options.localDataDir.empty()) - { - dir = portable.getValue("dataDir", ""); - if (!dir.empty()) - { - settings.options.localDataDir = settings.rootDir + dir; - logger->log("Portable data dir: %s", - settings.options.localDataDir.c_str()); - } - } - - if (settings.options.configDir.empty()) - { - dir = portable.getValue("configDir", ""); - if (!dir.empty()) - { - settings.options.configDir = settings.rootDir + dir; - logger->log("Portable config dir: %s", - settings.options.configDir.c_str()); - } - } - - if (settings.options.screenshotDir.empty()) - { - dir = portable.getValue("screenshotDir", ""); - if (!dir.empty()) - { - settings.options.screenshotDir = settings.rootDir + dir; - logger->log("Portable screenshot dir: %s", - settings.options.screenshotDir.c_str()); - } - } - } -} - -/** - * Initializes the home directory. On UNIX and FreeBSD, ~/.mana is used. On - * Windows and other systems we use the current working directory. - */ -void Client::initHomeDir() -{ - initLocalDataDir(); - initTempDir(); - initConfigDir(); -} - -void Client::initLocalDataDir() -{ - settings.localDataDir = settings.options.localDataDir; - - if (settings.localDataDir.empty()) - { -#ifdef __APPLE__ - // Use Application Directory instead of .mana - settings.localDataDir = std::string(PhysFs::getUserDir()) + - "/Library/Application Support/" + - branding.getValue("appName", "ManaPlus"); -#elif defined __HAIKU__ - settings.localDataDir = std::string(PhysFs::getUserDir()) + - "/config/data/Mana"; -#elif defined WIN32 - settings.localDataDir = getSpecialFolderLocation(CSIDL_LOCAL_APPDATA); - if (settings.localDataDir.empty()) - settings.localDataDir = std::string(PhysFs::getUserDir()); - settings.localDataDir.append("/Mana"); -#elif defined __ANDROID__ - settings.localDataDir = getSdStoragePath() + branding.getValue( - "appShort", "ManaPlus") + "/local"; -#elif defined __native_client__ - settings.localDataDir = _nacl_dir.append("/local"); -#else - settings.localDataDir = std::string(PhysFs::getUserDir()) + - ".local/share/mana"; -#endif - } - - if (mkdir_r(settings.localDataDir.c_str())) - { - // TRANSLATORS: directory creation error - logger->error(strprintf(_("%s doesn't exist and can't be created! " - "Exiting."), settings.localDataDir.c_str())); - } -#ifdef USE_PROFILER - Perfomance::init(settings.localDataDir + "/profiler.log"); -#endif -} - -void Client::initTempDir() -{ - settings.tempDir = settings.localDataDir + dirSeparator + "temp"; - - if (mkdir_r(settings.tempDir.c_str())) - { - // TRANSLATORS: directory creation error - logger->error(strprintf(_("%s doesn't exist and can't be created! " - "Exiting."), settings.tempDir.c_str())); - } -// ResourceManager::deleteFilesInDirectory(settings.tempDir); -} - -void Client::initConfigDir() -{ - settings.configDir = settings.options.configDir; - - if (settings.configDir.empty()) - { -#ifdef __APPLE__ - settings.configDir = settings.localDataDir + dirSeparator - + branding.getValue("appShort", "mana"); -#elif defined __HAIKU__ - settings.configDir = std::string(PhysFs::getUserDir()) + - "/config/settings/Mana" + - branding.getValue("appName", "ManaPlus"); -#elif defined WIN32 - settings.configDir = getSpecialFolderLocation(CSIDL_APPDATA); - if (settings.configDir.empty()) - { - settings.configDir = settings.localDataDir; - } - else - { - settings.configDir.append("/mana/").append(branding.getValue( - "appShort", "mana")); - } -#elif defined __ANDROID__ - settings.configDir = getSdStoragePath() + branding.getValue( - "appShort", "ManaPlus").append("/config"); -#elif defined __native_client__ - settings.configDir = _nacl_dir.append("/config"); -#else - settings.configDir = std::string(PhysFs::getUserDir()).append( - "/.config/mana/").append(branding.getValue("appShort", "mana")); -#endif - logger->log("Generating config dir: " + settings.configDir); - } - - if (mkdir_r(settings.configDir.c_str())) - { - // TRANSLATORS: directory creation error - logger->error(strprintf(_("%s doesn't exist and can't be created! " - "Exiting."), settings.configDir.c_str())); - } -} - /** * Initializes the home directory. On UNIX and FreeBSD, ~/.mana is used. On * Windows and other systems we use the current working directory. @@ -2068,7 +1802,7 @@ void Client::initServerConfig(const std::string &serverName) } initPacketLimiter(); initTradeFilter(); - initUsersDir(); + Dirs::initUsersDir(); player_relations.init(); // Initialize the item and emote shortcuts. @@ -2169,156 +1903,6 @@ void Client::backupConfig() const Files::copyFile(fileName3, fileName4); } -/** - * Parse the update host and determine the updates directory - * Then verify that the directory exists (creating if needed). - */ -void Client::initUpdatesDir() -{ - std::stringstream updates; - - // If updatesHost is currently empty, fill it from config file - if (settings.updateHost.empty()) - settings.updateHost = config.getStringValue("updatehost"); - if (!checkPath(settings.updateHost)) - return; - - // Don't go out of range int he next check - if (settings.updateHost.length() < 2) - return; - - const size_t sz = settings.updateHost.size(); - // Remove any trailing slash at the end of the update host - if (settings.updateHost.at(sz - 1) == '/') - settings.updateHost.resize(sz - 1); - - // Parse out any "http://" or "https://", and set the updates directory - const size_t pos = settings.updateHost.find("://"); - if (pos != settings.updateHost.npos) - { - if (pos + 3 < settings.updateHost.length() - && !settings.updateHost.empty()) - { - updates << "updates/" << settings.updateHost.substr(pos + 3); - settings.updatesDir = updates.str(); - } - else - { - logger->log("Error: Invalid update host: %s", - settings.updateHost.c_str()); - // TRANSLATORS: update server initialisation error - errorMessage = strprintf(_("Invalid update host: %s."), - settings.updateHost.c_str()); - mState = STATE_ERROR; - } - } - else - { - logger->log1("Warning: no protocol was specified for the update host"); - updates << "updates/" << settings.updateHost; - settings.updatesDir = updates.str(); - } - -#ifdef WIN32 - if (settings.updatesDir.find(":") != std::string::npos) - replaceAll(settings.updatesDir, ":", "_"); -#endif - - const std::string updateDir("/" + settings.updatesDir); - - // Verify that the updates directory exists. Create if necessary. - if (!PhysFs::isDirectory(updateDir.c_str())) - { - if (!PhysFs::mkdir(updateDir.c_str())) - { -#if defined WIN32 - std::string newDir = settings.localDataDir - + "\\" + settings.updatesDir; - size_t loc = newDir.find("/", 0); - - while (loc != std::string::npos) - { - newDir.replace(loc, 1, "\\"); - loc = newDir.find("/", loc); - } - - if (!CreateDirectory(newDir.c_str(), nullptr) && - GetLastError() != ERROR_ALREADY_EXISTS) - { - logger->log("Error: %s can't be made, but doesn't exist!", - newDir.c_str()); - // TRANSLATORS: update server initialisation error - errorMessage = _("Error creating updates directory!"); - mState = STATE_ERROR; - } -#else - logger->log("Error: %s/%s can't be made, but doesn't exist!", - settings.localDataDir.c_str(), settings.updatesDir.c_str()); - // TRANSLATORS: update server initialisation error - errorMessage = _("Error creating updates directory!"); - mState = STATE_ERROR; -#endif - } - } - const std::string updateLocal = updateDir + "/local"; - const std::string updateFix = updateDir + "/fix"; - if (!PhysFs::isDirectory(updateLocal.c_str())) - PhysFs::mkdir(updateLocal.c_str()); - if (!PhysFs::isDirectory(updateFix.c_str())) - PhysFs::mkdir(updateFix.c_str()); -} - -void Client::initScreenshotDir() -{ - if (!settings.options.screenshotDir.empty()) - { - settings.screenshotDir = settings.options.screenshotDir; - if (mkdir_r(settings.screenshotDir.c_str())) - { - // TRANSLATORS: directory creation error - logger->log(strprintf( - _("Error: %s doesn't exist and can't be created! " - "Exiting."), settings.screenshotDir.c_str())); - } - } - else if (settings.screenshotDir.empty()) - { - settings.screenshotDir = decodeBase64String( - config.getStringValue("screenshotDirectory3")); - if (settings.screenshotDir.empty()) - { -#ifdef __ANDROID__ - settings.screenshotDir = getSdStoragePath() - + std::string("/images"); - - if (mkdir_r(settings.screenshotDir.c_str())) - { - // TRANSLATORS: directory creation error - logger->log(strprintf( - _("Error: %s doesn't exist and can't be created! " - "Exiting."), settings.screenshotDir.c_str())); - } -#else - settings.screenshotDir = getPicturesDir(); -#endif - if (config.getBoolValue("useScreenshotDirectorySuffix")) - { - const std::string configScreenshotSuffix = - branding.getValue("screenshots", "ManaPlus"); - - if (!configScreenshotSuffix.empty()) - { - settings.screenshotDir.append(dirSeparator).append( - configScreenshotSuffix); - } - } - config.setValue("screenshotDirectory3", - encodeBase64String(settings.screenshotDir)); - } - } - logger->log("screenshotDirectory: " + settings.screenshotDir); -} - #ifndef ANDROID void Client::storeSafeParameters() const { @@ -2473,25 +2057,6 @@ void Client::initTradeFilter() const } } -void Client::initUsersDir() -{ - settings.usersDir = settings.serverConfigDir + "/users/"; - if (mkdir_r(settings.usersDir.c_str())) - { - // TRANSLATORS: directory creation error - logger->error(strprintf(_("%s doesn't exist and can't be created! " - "Exiting."), settings.usersDir.c_str())); - } - - settings.npcsDir = settings.serverConfigDir + "/npcs/"; - if (mkdir_r(settings.npcsDir.c_str())) - { - // TRANSLATORS: directory creation error - logger->error(strprintf(_("%s doesn't exist and can't be created! " - "Exiting."), settings.npcsDir.c_str())); - } -} - void Client::initPacketLimiter() { // here i setting packet limits. but current server is broken, diff --git a/src/client.h b/src/client.h index 7fb34b98e..d7066145a 100644 --- a/src/client.h +++ b/src/client.h @@ -162,8 +162,6 @@ public: void initTradeFilter() const; - void initUsersDir(); - void initPacketLimiter(); void writePacketLimits(const std::string &packetLimitsName) const; @@ -202,28 +200,8 @@ private: void initTitle(); - void updateDataPath(); - - static void extractDataDir(); - - void mountDataDir(); - - void initRootDir(); - - void initHomeDir(); - void initConfiguration() const; - void initLocalDataDir(); - - void initTempDir(); - - void initConfigDir(); - - void initUpdatesDir(); - - void initScreenshotDir(); - void initServerConfig(const std::string &serverName); static void initFeatures(); diff --git a/src/dirs.cpp b/src/dirs.cpp new file mode 100644 index 000000000..da3aacd8e --- /dev/null +++ b/src/dirs.cpp @@ -0,0 +1,491 @@ +/* + * The ManaPlus Client + * Copyright (C) 2004-2009 The Mana World Development Team + * Copyright (C) 2009-2010 The Mana Developers + * Copyright (C) 2011-2014 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * 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 + * 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, see <http://www.gnu.org/licenses/>. + */ + +#include "dirs.h" + +#include "client.h" +#include "configuration.h" +#include "logger.h" +#include "settings.h" + +#include "utils/base64.h" +#include "utils/gettext.h" +#include "utils/mkdir.h" +#include "utils/paths.h" +#include "utils/physfstools.h" + +#include "resources/resourcemanager.h" + +#ifdef __APPLE__ +#include <CoreFoundation/CFBundle.h> +#endif + +#include <SDL_image.h> + +#ifdef WIN32 +#include <SDL_syswm.h> +#include "utils/specialfolder.h" +#endif + +#include <sys/stat.h> + +#include "debug.h" + +#if defined __native_client__ +#define _nacl_dir std::string("/persistent/manaplus") +#endif + +void Dirs::updateDataPath() +{ + if (settings.options.dataPath.empty() + && !branding.getStringValue("dataPath").empty()) + { + if (isRealPath(branding.getStringValue("dataPath"))) + { + settings.options.dataPath = branding.getStringValue("dataPath"); + } + else + { + settings.options.dataPath = branding.getDirectory().append(dirSeparator) + + branding.getStringValue("dataPath"); + } + settings.options.skipUpdate = true; + } +} + +void Dirs::extractDataDir() +{ +#ifdef ANDROID +#ifdef USE_SDL2 + Files::setCopyCallBack(&updateProgress); + setProgress(0); + extractAssets(); + + const std::string zipName = std::string(getenv( + "APPDIR")).append("/data.zip"); + const std::string dirName = std::string(getenv( + "APPDIR")).append("/data"); + Files::extractZip(zipName, "data", dirName); + Files::extractLocale(); +#endif +#endif + +#if defined __native_client__ + const std::string dirName = _nacl_dir.append("/data"); + Files::extractZip("/http/data.zip", "data", dirName); +#endif +} + +void Dirs::mountDataDir() +{ + const ResourceManager *const resman = ResourceManager::getInstance(); + resman->addToSearchPath(PKG_DATADIR "data/perserver/default", false); + resman->addToSearchPath("data/perserver/default", false); + +#if defined __APPLE__ + CFBundleRef mainBundle = CFBundleGetMainBundle(); + CFURLRef resourcesURL = CFBundleCopyResourcesDirectoryURL(mainBundle); + char path[PATH_MAX]; + if (!CFURLGetFileSystemRepresentation(resourcesURL, TRUE, (uint8_t*)path, + PATH_MAX)) + { + fprintf(stderr, "Can't find Resources directory\n"); + } + CFRelease(resourcesURL); + // possible crash + strncat(path, "/data", PATH_MAX - 1); + resman->addToSearchPath(path, false); +// possible this need for support run client from dmg images. +// mPackageDir = path; +#endif + resman->addToSearchPath(PKG_DATADIR "data", false); + setPackageDir(PKG_DATADIR "data"); + resman->addToSearchPath("data", false); + +#ifdef ANDROID +#ifdef USE_SDL2 + if (getenv("APPDIR")) + { + const std::string appDir = getenv("APPDIR"); + resman->addToSearchPath(appDir + "/data", false); + resman->addToSearchPath(appDir + "/data/perserver/default", false); + } +#endif +#endif + +#if defined __native_client__ + resman->addToSearchPath(_nacl_dir.append("/data"), false); +#endif + + // Add branding/data to PhysFS search path + if (!settings.options.brandingPath.empty()) + { + std::string path = settings.options.brandingPath; + + // Strip blah.manaplus from the path +#ifdef WIN32 + const int loc1 = path.find_last_of('/'); + const int loc2 = path.find_last_of('\\'); + const int loc = static_cast<int>(std::max(loc1, loc2)); +#else + const int loc = static_cast<int>(path.find_last_of('/')); +#endif + if (loc > 0) + { + resman->addToSearchPath(path.substr( + 0, loc + 1).append("data"), false); + } + } +} + +void Dirs::initRootDir() +{ + settings.rootDir = PhysFs::getBaseDir(); + const std::string portableName = settings.rootDir + "portable.xml"; + struct stat statbuf; + + if (!stat(portableName.c_str(), &statbuf) && S_ISREG(statbuf.st_mode)) + { + std::string dir; + Configuration portable; + portable.init(portableName); + + if (settings.options.brandingPath.empty()) + { + branding.init(portableName); + branding.setDefaultValues(getBrandingDefaults()); + } + + logger->log("Portable file: %s", portableName.c_str()); + + if (settings.options.localDataDir.empty()) + { + dir = portable.getValue("dataDir", ""); + if (!dir.empty()) + { + settings.options.localDataDir = settings.rootDir + dir; + logger->log("Portable data dir: %s", + settings.options.localDataDir.c_str()); + } + } + + if (settings.options.configDir.empty()) + { + dir = portable.getValue("configDir", ""); + if (!dir.empty()) + { + settings.options.configDir = settings.rootDir + dir; + logger->log("Portable config dir: %s", + settings.options.configDir.c_str()); + } + } + + if (settings.options.screenshotDir.empty()) + { + dir = portable.getValue("screenshotDir", ""); + if (!dir.empty()) + { + settings.options.screenshotDir = settings.rootDir + dir; + logger->log("Portable screenshot dir: %s", + settings.options.screenshotDir.c_str()); + } + } + } +} + +/** + * Initializes the home directory. On UNIX and FreeBSD, ~/.mana is used. On + * Windows and other systems we use the current working directory. + */ +void Dirs::initHomeDir() +{ + initLocalDataDir(); + initTempDir(); + initConfigDir(); +} + +void Dirs::initLocalDataDir() +{ + settings.localDataDir = settings.options.localDataDir; + + if (settings.localDataDir.empty()) + { +#ifdef __APPLE__ + // Use Application Directory instead of .mana + settings.localDataDir = std::string(PhysFs::getUserDir()) + + "/Library/Application Support/" + + branding.getValue("appName", "ManaPlus"); +#elif defined __HAIKU__ + settings.localDataDir = std::string(PhysFs::getUserDir()) + + "/config/data/Mana"; +#elif defined WIN32 + settings.localDataDir = getSpecialFolderLocation(CSIDL_LOCAL_APPDATA); + if (settings.localDataDir.empty()) + settings.localDataDir = std::string(PhysFs::getUserDir()); + settings.localDataDir.append("/Mana"); +#elif defined __ANDROID__ + settings.localDataDir = getSdStoragePath() + branding.getValue( + "appShort", "ManaPlus") + "/local"; +#elif defined __native_client__ + settings.localDataDir = _nacl_dir.append("/local"); +#else + settings.localDataDir = std::string(PhysFs::getUserDir()) + + ".local/share/mana"; +#endif + } + + if (mkdir_r(settings.localDataDir.c_str())) + { + // TRANSLATORS: directory creation error + logger->error(strprintf(_("%s doesn't exist and can't be created! " + "Exiting."), settings.localDataDir.c_str())); + } +#ifdef USE_PROFILER + Perfomance::init(settings.localDataDir + "/profiler.log"); +#endif +} + +void Dirs::initTempDir() +{ + settings.tempDir = settings.localDataDir + dirSeparator + "temp"; + + if (mkdir_r(settings.tempDir.c_str())) + { + // TRANSLATORS: directory creation error + logger->error(strprintf(_("%s doesn't exist and can't be created! " + "Exiting."), settings.tempDir.c_str())); + } +// ResourceManager::deleteFilesInDirectory(settings.tempDir); +} + +void Dirs::initConfigDir() +{ + settings.configDir = settings.options.configDir; + + if (settings.configDir.empty()) + { +#ifdef __APPLE__ + settings.configDir = settings.localDataDir + dirSeparator + + branding.getValue("appShort", "mana"); +#elif defined __HAIKU__ + settings.configDir = std::string(PhysFs::getUserDir()) + + "/config/settings/Mana" + + branding.getValue("appName", "ManaPlus"); +#elif defined WIN32 + settings.configDir = getSpecialFolderLocation(CSIDL_APPDATA); + if (settings.configDir.empty()) + { + settings.configDir = settings.localDataDir; + } + else + { + settings.configDir.append("/mana/").append(branding.getValue( + "appShort", "mana")); + } +#elif defined __ANDROID__ + settings.configDir = getSdStoragePath() + branding.getValue( + "appShort", "ManaPlus").append("/config"); +#elif defined __native_client__ + settings.configDir = _nacl_dir.append("/config"); +#else + settings.configDir = std::string(PhysFs::getUserDir()).append( + "/.config/mana/").append(branding.getValue("appShort", "mana")); +#endif + logger->log("Generating config dir: " + settings.configDir); + } + + if (mkdir_r(settings.configDir.c_str())) + { + // TRANSLATORS: directory creation error + logger->error(strprintf(_("%s doesn't exist and can't be created! " + "Exiting."), settings.configDir.c_str())); + } +} + +/** + * Parse the update host and determine the updates directory + * Then verify that the directory exists (creating if needed). + */ +void Dirs::initUpdatesDir() +{ + std::stringstream updates; + + // If updatesHost is currently empty, fill it from config file + if (settings.updateHost.empty()) + settings.updateHost = config.getStringValue("updatehost"); + if (!checkPath(settings.updateHost)) + return; + + // Don't go out of range int he next check + if (settings.updateHost.length() < 2) + return; + + const size_t sz = settings.updateHost.size(); + // Remove any trailing slash at the end of the update host + if (settings.updateHost.at(sz - 1) == '/') + settings.updateHost.resize(sz - 1); + + // Parse out any "http://" or "https://", and set the updates directory + const size_t pos = settings.updateHost.find("://"); + if (pos != settings.updateHost.npos) + { + if (pos + 3 < settings.updateHost.length() + && !settings.updateHost.empty()) + { + updates << "updates/" << settings.updateHost.substr(pos + 3); + settings.updatesDir = updates.str(); + } + else + { + logger->log("Error: Invalid update host: %s", + settings.updateHost.c_str()); + // TRANSLATORS: update server initialisation error + errorMessage = strprintf(_("Invalid update host: %s."), + settings.updateHost.c_str()); + client->setState(STATE_ERROR); + } + } + else + { + logger->log1("Warning: no protocol was specified for the update host"); + updates << "updates/" << settings.updateHost; + settings.updatesDir = updates.str(); + } + +#ifdef WIN32 + if (settings.updatesDir.find(":") != std::string::npos) + replaceAll(settings.updatesDir, ":", "_"); +#endif + + const std::string updateDir("/" + settings.updatesDir); + + // Verify that the updates directory exists. Create if necessary. + if (!PhysFs::isDirectory(updateDir.c_str())) + { + if (!PhysFs::mkdir(updateDir.c_str())) + { +#if defined WIN32 + std::string newDir = settings.localDataDir + + "\\" + settings.updatesDir; + size_t loc = newDir.find("/", 0); + + while (loc != std::string::npos) + { + newDir.replace(loc, 1, "\\"); + loc = newDir.find("/", loc); + } + + if (!CreateDirectory(newDir.c_str(), nullptr) && + GetLastError() != ERROR_ALREADY_EXISTS) + { + logger->log("Error: %s can't be made, but doesn't exist!", + newDir.c_str()); + // TRANSLATORS: update server initialisation error + errorMessage = _("Error creating updates directory!"); + client->setState(STATE_ERROR); + } +#else + logger->log("Error: %s/%s can't be made, but doesn't exist!", + settings.localDataDir.c_str(), settings.updatesDir.c_str()); + // TRANSLATORS: update server initialisation error + errorMessage = _("Error creating updates directory!"); + client->setState(STATE_ERROR); +#endif + } + } + const std::string updateLocal = updateDir + "/local"; + const std::string updateFix = updateDir + "/fix"; + if (!PhysFs::isDirectory(updateLocal.c_str())) + PhysFs::mkdir(updateLocal.c_str()); + if (!PhysFs::isDirectory(updateFix.c_str())) + PhysFs::mkdir(updateFix.c_str()); +} + +void Dirs::initScreenshotDir() +{ + if (!settings.options.screenshotDir.empty()) + { + settings.screenshotDir = settings.options.screenshotDir; + if (mkdir_r(settings.screenshotDir.c_str())) + { + // TRANSLATORS: directory creation error + logger->log(strprintf( + _("Error: %s doesn't exist and can't be created! " + "Exiting."), settings.screenshotDir.c_str())); + } + } + else if (settings.screenshotDir.empty()) + { + settings.screenshotDir = decodeBase64String( + config.getStringValue("screenshotDirectory3")); + if (settings.screenshotDir.empty()) + { +#ifdef __ANDROID__ + settings.screenshotDir = getSdStoragePath() + + std::string("/images"); + + if (mkdir_r(settings.screenshotDir.c_str())) + { + // TRANSLATORS: directory creation error + logger->log(strprintf( + _("Error: %s doesn't exist and can't be created! " + "Exiting."), settings.screenshotDir.c_str())); + } +#else + settings.screenshotDir = getPicturesDir(); +#endif + if (config.getBoolValue("useScreenshotDirectorySuffix")) + { + const std::string configScreenshotSuffix = + branding.getValue("screenshots", "ManaPlus"); + + if (!configScreenshotSuffix.empty()) + { + settings.screenshotDir.append(dirSeparator).append( + configScreenshotSuffix); + } + } + config.setValue("screenshotDirectory3", + encodeBase64String(settings.screenshotDir)); + } + } + logger->log("screenshotDirectory: " + settings.screenshotDir); +} + +void Dirs::initUsersDir() +{ + settings.usersDir = settings.serverConfigDir + "/users/"; + if (mkdir_r(settings.usersDir.c_str())) + { + // TRANSLATORS: directory creation error + logger->error(strprintf(_("%s doesn't exist and can't be created! " + "Exiting."), settings.usersDir.c_str())); + } + + settings.npcsDir = settings.serverConfigDir + "/npcs/"; + if (mkdir_r(settings.npcsDir.c_str())) + { + // TRANSLATORS: directory creation error + logger->error(strprintf(_("%s doesn't exist and can't be created! " + "Exiting."), settings.npcsDir.c_str())); + } +} diff --git a/src/dirs.h b/src/dirs.h new file mode 100644 index 000000000..ed01a822a --- /dev/null +++ b/src/dirs.h @@ -0,0 +1,56 @@ +/* + * The ManaPlus Client + * Copyright (C) 2004-2009 The Mana World Development Team + * Copyright (C) 2009-2010 The Mana Developers + * Copyright (C) 2011-2014 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * 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 + * 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, see <http://www.gnu.org/licenses/>. + */ + +#ifndef DIRS_H +#define DIRS_H + +#include <string> + +#include "localconsts.h" + +class Dirs final +{ + public: + static void initUsersDir(); + + static void updateDataPath(); + + static void extractDataDir(); + + static void mountDataDir(); + + static void initRootDir(); + + static void initHomeDir(); + + static void initLocalDataDir(); + + static void initTempDir(); + + static void initConfigDir(); + + static void initUpdatesDir(); + + static void initScreenshotDir(); +}; + +#endif // DIRS_H |