diff --git a/lib/VCMIDirs.cpp b/lib/VCMIDirs.cpp index 35c6ad47c..c35ea9913 100644 --- a/lib/VCMIDirs.cpp +++ b/lib/VCMIDirs.cpp @@ -1,6 +1,3 @@ -#include "StdInc.h" -#include "VCMIDirs.h" - /* * VCMIDirs.cpp, part of VCMI engine * @@ -11,241 +8,470 @@ * */ -static VCMIDirs VCMIDirsGlobal; +#include "StdInc.h" +#include "VCMIDirs.h" -VCMIDirs::VCMIDirs() +namespace bfs = boost::filesystem; + +namespace VCMIDirs { - // initialize local directory and create folders to which VCMI needs write access - boost::filesystem::create_directory(userDataPath()); - boost::filesystem::create_directory(userCachePath()); - boost::filesystem::create_directory(userConfigPath()); - boost::filesystem::create_directory(userSavePath()); -} - -VCMIDirs & VCMIDirs::get() -{ - return VCMIDirsGlobal; -} - -//FIXME: find way to at least decrease size of this ifdef (along with cleanup in CMake) -#if defined(_WIN32) - -std::string VCMIDirs::userCachePath() const -{ - return userDataPath(); -} - -std::string VCMIDirs::userConfigPath() const -{ - return userDataPath() + "/config"; -} - -std::string VCMIDirs::userSavePath() const -{ - return userDataPath() + "/Games"; -} - -std::string VCMIDirs::userDataPath() const -{ - const std::string homeDir = std::getenv("userprofile"); - return homeDir + "\\vcmi"; - //return dataPaths()[0]; -} - -std::string VCMIDirs::libraryPath() const -{ - return "."; -} - -std::string VCMIDirs::clientPath() const -{ - return libraryPath() + "\\" + "VCMI_client.exe"; -} - -std::string VCMIDirs::serverPath() const -{ - return libraryPath() + "\\" + "VCMI_server.exe"; -} - -std::vector VCMIDirs::dataPaths() const -{ - return std::vector(1, "."); -} - -std::string VCMIDirs::libraryName(std::string basename) const -{ - return basename + ".dll"; -} - -#elif defined(__APPLE__) - -std::string VCMIDirs::userCachePath() const -{ - return userDataPath(); -} - -std::string VCMIDirs::userConfigPath() const -{ - return userDataPath() + "/config"; -} - -std::string VCMIDirs::userSavePath() const -{ - return userDataPath() + "/Games"; -} - -std::string VCMIDirs::userDataPath() const -{ - // This is Cocoa code that should be normally used to get path to Application Support folder but can't use it here for now... - // NSArray* urls = [[NSFileManager defaultManager] URLsForDirectory:NSApplicationSupportDirectory inDomains:NSUserDomainMask]; - // UserPath = path([urls[0] path] + "/vcmi").string(); - - // ...so here goes a bit of hardcode instead - std::string home_dir = "."; - if (getenv("HOME") != nullptr ) - home_dir = getenv("HOME"); - - return boost::filesystem::path(home_dir + "/Library/Application Support/vcmi").string(); -} - -std::string VCMIDirs::libraryPath() const -{ - return "."; -} - -std::string VCMIDirs::clientPath() const -{ - return "./vcmiclient"; -} - -std::string VCMIDirs::serverPath() const -{ - return "./vcmiserver"; -} - -std::vector VCMIDirs::dataPaths() const -{ - return std::vector(1, "../Data"); -} - -std::string VCMIDirs::libraryName(std::string basename) const -{ - return "lib" + basename + ".dylib"; -} - -#else - -std::string VCMIDirs::libraryName(std::string basename) const -{ - return "lib" + basename + ".so"; -} - -std::string VCMIDirs::libraryPath() const -{ - return M_LIB_DIR; -} - -std::string VCMIDirs::clientPath() const -{ - return std::string(M_BIN_DIR) + "/" + "vcmiclient"; -} - -std::string VCMIDirs::serverPath() const -{ - return std::string(M_BIN_DIR) + "/" + "vcmiserver"; -} - -// $XDG_DATA_HOME, default: $HOME/.local/share -std::string VCMIDirs::userDataPath() const -{ -#ifdef __ANDROID__ - // on Android HOME will be set to something like /sdcard/data/Android/is.xyz.vcmi/files/ - return std::string(getenv("HOME")); -#else - if (getenv("XDG_DATA_HOME") != nullptr ) - return std::string(getenv("XDG_DATA_HOME")) + "/vcmi"; - if (getenv("HOME") != nullptr ) - return std::string(getenv("HOME")) + "/.local/share" + "/vcmi"; - return "."; -#endif -} - -std::string VCMIDirs::userSavePath() const -{ - return userDataPath() + "/Saves"; -} - -// $XDG_CACHE_HOME, default: $HOME/.cache -std::string VCMIDirs::userCachePath() const -{ -#ifdef __ANDROID__ - return userDataPath() + "/cache"; -#else - if (getenv("XDG_CACHE_HOME") != nullptr ) - return std::string(getenv("XDG_CACHE_HOME")) + "/vcmi"; - if (getenv("HOME") != nullptr ) - return std::string(getenv("HOME")) + "/.cache" + "/vcmi"; - return "."; -#endif -} - -// $XDG_CONFIG_HOME, default: $HOME/.config -std::string VCMIDirs::userConfigPath() const -{ -#ifdef __ANDROID__ - return userDataPath() + "/config"; -#else - if (getenv("XDG_CONFIG_HOME") != nullptr ) - return std::string(getenv("XDG_CONFIG_HOME")) + "/vcmi"; - if (getenv("HOME") != nullptr ) - return std::string(getenv("HOME")) + "/.config" + "/vcmi"; - return "."; -#endif -} - -// $XDG_DATA_DIRS, default: /usr/local/share/:/usr/share/ -std::vector VCMIDirs::dataPaths() const -{ - // construct list in reverse. - // in specification first directory has highest priority - // in vcmi fs last directory has highest priority - - std::vector ret; -#ifdef __ANDROID__ - ret.push_back(userDataPath()); -#else - if (getenv("HOME") != nullptr ) // compatibility, should be removed after 0.96 - ret.push_back(std::string(getenv("HOME")) + "/.vcmi"); - ret.push_back(M_DATA_DIR); - - if (getenv("XDG_DATA_DIRS") != nullptr) + namespace detail { - std::string dataDirsEnv = getenv("XDG_DATA_DIRS"); - std::vector dataDirs; - boost::split(dataDirs, dataDirsEnv, boost::is_any_of(":")); - for (auto & entry : boost::adaptors::reverse(dataDirs)) - ret.push_back(entry + "/vcmi"); + bfs::path g_user_data_path; + bfs::path g_user_cache_path; + bfs::path g_user_config_path; + bfs::path g_user_save_path; + + bfs::path g_library_path; + bfs::path g_client_path; + bfs::path g_server_path; + + std::vector g_data_paths; + + std::string g_help_string; + + extern bfs::path GetDataPath(); + extern bfs::path GetCachePath(); + extern bfs::path GetConfigPath(); + extern bfs::path GetUserSavePath(); + + extern bfs::path GetLibraryPath(); + extern bfs::path GetClientPath(); + extern bfs::path GetServerPath(); + extern std::vector GetDataPaths(); + + extern std::string GetHelpString(); } - else + + void InitAllPathes(void) { - ret.push_back("/usr/share/"); - ret.push_back("/usr/local/share/"); + detail::g_user_data_path = detail::GetDataPath(); + detail::g_user_cache_path = detail::GetCachePath(); + detail::g_user_config_path = detail::GetConfigPath(); + detail::g_user_save_path = detail::GetUserSavePath(); + + detail::g_library_path = detail::GetLibraryPath(); + detail::g_client_path = detail::GetClientPath(); + detail::g_server_path = detail::GetServerPath(); + + detail::g_data_paths = detail::GetDataPaths(); + + detail::g_help_string = detail::GetHelpString(); + + // initialize local directory and create folders to which VCMI needs write access + bfs::create_directory(detail::g_user_data_path); + bfs::create_directory(detail::g_user_cache_path); + bfs::create_directory(detail::g_user_config_path); + bfs::create_directory(detail::g_user_save_path); + } + + namespace detail + { + struct InitAllPathes_ctor + { + InitAllPathes_ctor() { InitAllPathes(); } + } InitAllPathes_ctor_global_obj; + }; + + // TODO: Remove _VCMIDirs + static _VCMIDirs _VCMIDirsGlobal; + _VCMIDirs & get() + { + puts("VCMIDirs::get() - used of deprecated function :#"); + return _VCMIDirsGlobal; } -#endif - return ret; } -#endif +// FIXME: find way to at least decrease size of this ifdef (along with cleanup in CMake) +#ifdef _WIN32 +// This part should be moved into separate file (for example: VCMIDirs_win32.cpp) +// WinAPI +#include +#include -std::string VCMIDirs::genHelpString() const +namespace VCMIDirs { - return - " game data: " + boost::algorithm::join(dataPaths(), ":") + "\n" + - " libraries: " + libraryPath() + "\n" + - " server: " + serverPath() + "\n" + - "\n" + - " user data: " + userDataPath() + "\n" + - " user cache: " + userCachePath() + "\n" + - " user config: " + userConfigPath() + "\n" + - " user saves: " + userSavePath() + "\n"; + namespace detail + { + bfs::path GetDataPath() + { + const char* profile_dir_a; + wchar_t profile_dir_w[MAX_PATH]; + + // The user's profile folder. A typical path is C:\Users\username. + // FIXME: Applications should not create files or folders at this level; + // they should put their data under the locations referred to by CSIDL_APPDATA or CSIDL_LOCAL_APPDATA. + if (SHGetSpecialFolderPathW(nullptr, profile_dir_w, CSIDL_PROFILE, FALSE) == FALSE) // WinAPI way failed + { + if (profile_dir_a = std::getenv("userprofile")) // STL way succeed + return bfs::path(profile_dir_a) / "vcmi"; + else + return "."; // Every thing failed, return current directory. + } + else + return bfs::path(profile_dir_w) / "vcmi"; + + //return dataPaths()[0] ???; + } + + bfs::path GetCachePath() + { + return GetDataPath(); + } + + bfs::path GetConfigPath() + { + return GetDataPath() / "config"; + } + + bfs::path GetUserSavePath() + { + return GetDataPath() / "Games"; + } + + bfs::path GetLibraryPath() + { + return "."; + } + + bfs::path GetClientPath() + { + return GetLibraryPath() / "VCMI_client.exe"; + } + + bfs::path GetServerPath() + { + return GetLibraryPath() / "VCMI_server.exe"; + } + + std::vector GetDataPaths() + { + return std::vector(1, bfs::path(".")); + } + + std::string GetHelpString() + { + // I think this function should have multiple versions + // 1. For various arguments + // 2. Inverse functions + // and should be moved to vstd + // or use http://utfcpp.sourceforge.net/ + auto utf8_convert = [](const bfs::path& path) -> std::string + { + const auto& path_string = path.native(); + auto perform_convert = [&path_string](LPSTR output, int output_size) + { + return WideCharToMultiByte( + CP_UTF8, // Use wchar_t -> utf8 char_t + WC_ERR_INVALID_CHARS, // Fails when invalid char occur + path_string.c_str(), // String to convert + path_string.size(), // String to convert size + output, // Result + output_size, // Result size + nullptr, nullptr); // For the ... CP_UTF8 settings for CodePage, this parameter must be set to NULL + }; + + int char_count = perform_convert(nullptr, 0); // Result size (0 - obtain size) + if (char_count > 0) + { + std::unique_ptr buffer(new char[char_count]); + if ((char_count = perform_convert(buffer.get(), char_count)) > 0) + return std::string(buffer.get(), char_count); + } + + // Conversion failed :C + return path.string(); + }; + + std::vector temp_vec; + for (const bfs::path& path : GetDataPaths()) + temp_vec.push_back(utf8_convert(path)); + std::string gd_string_a = boost::algorithm::join(temp_vec, L";"); + + + return + " game data: " + gd_string_a + "\n" + + " libraries: " + utf8_convert(GetLibraryPath()) + "\n" + + " server: " + utf8_convert(GetServerPath()) + "\n" + + "\n" + + " user data: " + utf8_convert(GetDataPath()) + "\n" + + " user cache: " + utf8_convert(GetCachePath()) + "\n" + + " user config: " + utf8_convert(GetConfigPath()) + "\n" + + " user saves: " + utf8_convert(GetUserSavePath()) + "\n"; // Should end without new-line? + } + } + + std::string libraryName(const std::string& basename) + { + return basename + ".dll"; + } } + +#elif defined (__APPLE__) +// This part should be moved to separate file (for example: VCMIDirs_apple.cpp) + +namespace VCMIDirs +{ + namespace detail + { + bfs::path GetDataPath() + { + // This is Cocoa code that should be normally used to get path to Application Support folder but can't use it here for now... + // NSArray* urls = [[NSFileManager defaultManager] URLsForDirectory:NSApplicationSupportDirectory inDomains:NSUserDomainMask]; + // UserPath = path([urls[0] path] + "/vcmi").string(); + + // ...so here goes a bit of hardcode instead + + const char* home_dir = getenv("HOME"); // Should be std::getenv? + if (home_dir == nullptr) + home_dir = "."; + return bfs::path(home_dir) / "Library" / "Application Support" / "vcmi"; + } + + bfs::path GetCachePath() + { + return GetDataPath(); + } + + bfs::path GetConfigPath() + { + return GetDataPath() / "config"; + } + + bfs::path GetUserSavePath() + { + return GetDataPath() / "Games"; + } + + bfs::path GetLibraryPath() + { + return "."; + } + + bfs::path GetClientPath() + { + return "./vcmiclient"; + } + + bfs::path GetServerPath() + { + return "./vcmiserver"; + } + + std::vector GetDataPaths() + { + return std::vector(1, "../Data"); + } + + std::string GetHelpString() + { + std::vector temp_vec; + for (const bfs::path& path : GetDataPaths()) + temp_vec.push_back(path.string()); + + return + " game data: " + boost::algorithm::join(temp_vec, ":") + "\n" + + " libraries: " + GetLibraryPath().string() + "\n" + + " server: " + GetServerPath().string() + "\n" + + "\n" + + " user data: " + GetDataPath().string() + "\n" + + " user cache: " + GetCachePath().string() + "\n" + + " user config: " + GetConfigPath().string() + "\n" + + " user saves: " + GetUserSavePath().string() + "\n"; // Should end without new-line? + } + } + + std::string libraryName(const std::string& basename) + { + return "lib" + basename + ".dylib"; + } +} +#elif defined __ANDROID__ +// This part should be moved to separate file (for example: VCMIDirs_android.cpp) + +namespace VCMIDirs +{ + namespace detail + { + bfs::path GetDataPath() + { + // on Android HOME will be set to something like /sdcard/data/Android/is.xyz.vcmi/files/ + return getenv("HOME"); + } + + bfs::path GetCachePath() + { + return GetDataPath() / "cache"; + } + + bfs::path GetConfigPath() + { + return GetDataPath() / "config"; + } + + bfs::path GetUserSavePath() + { + return GetDataPath() / "Saves"; // Why different than other platforms??? + } + + bfs::path GetLibraryPath() + { + return M_LIB_DIR; + } + + bfs::path GetClientPath() + { + return bfs::path(M_BIN_DIR) / "vcmiclient"; + } + + bfs::path GetServerPath() + { + return bfs::path(M_BIN_DIR) / "vcmiserver"; + } + + std::vector GetDataPaths() + { + return std::vector(1, GetDataPath()); + } + + std::string GetHelpString() + { + std::vector temp_vec; + for (const bfs::path& path : GetDataPaths()) + temp_vec.push_back(path.string()); + + return + " game data: " + boost::algorithm::join(temp_vec, ":") + "\n" + + " libraries: " + GetLibraryPath().string() + "\n" + + " server: " + GetServerPath().string() + "\n" + + "\n" + + " user data: " + GetDataPath().string() + "\n" + + " user cache: " + GetCachePath().string() + "\n" + + " user config: " + GetConfigPath().string() + "\n" + + " user saves: " + GetUserSavePath().string() + "\n"; // Should end without new-line? + } + } + + std::string libraryName(const std::string& basename) + { + return "lib" + basename + ".so"; + } +} +#else +// This part should be moved to separate file (for example: VCMIDirs_default.cpp) + +namespace VCMIDirs +{ + namespace detail + { + // $XDG_DATA_HOME, default: $HOME/.local/share + bfs::path GetDataPath() + { + const char* home_dir; + if (home_dir = getenv("XDG_DATA_HOME")) + return = home_dir; + else if (home_dir = getenv("HOME")) + return = bfs::path(home_dir) / ".local" / "share" / "vcmi"; + else + return "."; + } + + // $XDG_CACHE_HOME, default: $HOME/.cache + bfs::path GetCachePath() + { + const char* home_dir; + if (home_dir = getenv("XDG_CACHE_HOME")) + return bfs::path(home_dir) / "vcmi"; + else if (home_dir = getenv("HOME")) + return bfs::path(home_dir) / ".cache" / "vcmi"; + else + return "."; + } + + // $XDG_CONFIG_HOME, default: $HOME/.config + bfs::path GetConfigPath() + { + const char* home_dir; + if (home_dir = getenv("XDG_CONFIG_HOME")) + return bfs:path(home_dir) / "vcmi"; + else if (home_dir = getenv("HOME")) + return bfs::path(home_dir) / ".config" / "vcmi"; + else + return "."; + } + + bfs::path GetUserSavePath() + { + return GetDataPath() / "Saves"; // Why different than other platforms??? + } + + bfs::path GetLibraryPath() + { + return M_LIB_DIR; + } + + bfs::path GetClientPath() + { + return bfs::path(M_BIN_DIR) / "vcmiclient"; + } + + bfs::path GetServerPath() + { + return bfs::path(M_BIN_DIR) / "vcmiserver"; + } + + std::vector GetDataPaths() + { + // $XDG_DATA_DIRS, default: /usr/local/share/:/usr/share/ + + // construct list in reverse. + // in specification first directory has highest priority + // in vcmi fs last directory has highest priority + std::vector ret; + + const char* home_dir; + if (home_dir = getenv("HOME")) // compatibility, should be removed after 0.96 + ret.push_back(bfs::path(home_dir) / ".vcmi"); + ret.push_back(M_DATA_DIR); + + if (home_dir = getenv("XDG_DATA_DIRS") != nullptr) + { + std::string dataDirsEnv = home_dir; + std::vector dataDirs; + boost::split(dataDirs, dataDirsEnv, boost::is_any_of(":")); + for (auto & entry : boost::adaptors::reverse(dataDirs)) + ret.push_back(entry + "/vcmi"); + } + else + { + ret.push_back("/usr/share/"); + ret.push_back("/usr/local/share/"); + } + + return ret; + } + + std::string GetHelpString() + { + std::vector temp_vec; + for (const bfs::path& path : GetDataPaths()) + temp_vec.push_back(path.string()); + + return + " game data: " + boost::algorithm::join(temp_vec, ":") + "\n" + + " libraries: " + GetLibraryPath().string() + "\n" + + " server: " + GetServerPath().string() + "\n" + + "\n" + + " user data: " + GetDataPath().string() + "\n" + + " user cache: " + GetCachePath().string() + "\n" + + " user config: " + GetConfigPath().string() + "\n" + + " user saves: " + GetUserSavePath().string() + "\n"; // Should end without new-line? + } + } + + std::string libraryName(const std::string& basename) + { + return "lib" + basename + ".so"; + } +} +#endif \ No newline at end of file diff --git a/lib/VCMIDirs.h b/lib/VCMIDirs.h index c3f02c56c..28b5f72c1 100644 --- a/lib/VCMIDirs.h +++ b/lib/VCMIDirs.h @@ -1,52 +1,118 @@ +/* +* VCMIDirs.h, part of VCMI engine +* +* Authors: listed in file AUTHORS in main folder +* +* License: GNU General Public License v2.0 or later +* Full text of license available in license.txt file, in main folder +* +*/ + #pragma once -#include "GameConstants.h" +// Boost +#include -/* - * VCMIDirs.h, part of VCMI engine - * - * Authors: listed in file AUTHORS in main folder - * - * License: GNU General Public License v2.0 or later - * Full text of license available in license.txt file, in main folder - * - */ +// STL C++ +#include +#include -/// Where to find the various VCMI files. This is mostly useful for linux. -class DLL_LINKAGE VCMIDirs +// TODO: Remove _VCMIDirs +class _VCMIDirs; + +// Where to find the various VCMI files. This is mostly useful for linux. +namespace VCMIDirs +{ + namespace detail + { + extern DLL_LINKAGE boost::filesystem::path g_user_data_path; + extern DLL_LINKAGE boost::filesystem::path g_user_cache_path; + extern DLL_LINKAGE boost::filesystem::path g_user_config_path; + extern DLL_LINKAGE boost::filesystem::path g_user_save_path; + + extern DLL_LINKAGE boost::filesystem::path g_library_path; + extern DLL_LINKAGE boost::filesystem::path g_client_path; + extern DLL_LINKAGE boost::filesystem::path g_server_path; + + extern DLL_LINKAGE std::vector g_data_paths; + + extern DLL_LINKAGE std::string g_help_string; + } + + /// deprecated: get singleton instance + extern DLL_LINKAGE _VCMIDirs & get(); + + // Path to user-specific data directory + inline const boost::filesystem::path& userDataPath() { return detail::g_user_data_path; } + + // Path to "cache" directory, can be used for any non-essential files + inline const boost::filesystem::path& userCachePath() { return detail::g_user_cache_path; } + + // Path to writeable directory with user configs + inline const boost::filesystem::path& userConfigPath() { return detail::g_user_config_path; } + + // Path to saved games + inline const boost::filesystem::path& userSavePath() { return detail::g_user_save_path; } + + // Paths to global system-wide data directories. First items have higher priority + inline const std::vector& dataPaths() { return detail::g_data_paths; } + + // Full path to client executable, including server name (e.g. /usr/bin/vcmiclient) + inline const boost::filesystem::path& clientPath() { return detail::g_client_path; } + + // Full path to server executable, including server name (e.g. /usr/bin/vcmiserver) + inline const boost::filesystem::path& serverPath() { return detail::g_server_path; } + + // Path where vcmi libraries can be found (in AI and Scripting subdirectories) + inline const boost::filesystem::path& libraryPath() { return detail::g_library_path; } + + // Returns system-specific name for dynamic libraries ( StupidAI => "libStupidAI.so" or "StupidAI.dll") + extern DLL_LINKAGE std::string libraryName(const std::string& basename); + //extern DLL_LINKAGE std::string libraryName(const char* basename); + //extern DLL_LINKAGE std::string libraryName(std::string&& basename); + + + inline const std::string& genHelpString() { return detail::g_help_string; } +} + +// TODO: Remove _VCMIDirs +// This class is deprecated +class DLL_LINKAGE _VCMIDirs { public: - VCMIDirs(); + /// deprecated: Path to user-specific data directory + std::string userDataPath() const { return VCMIDirs::userDataPath().string(); } - /// get singleton instance - static VCMIDirs & get(); + /// deprecated: Path to "cache" directory, can be used for any non-essential files + std::string userCachePath() const { return VCMIDirs::userCachePath().string(); } - /// Path to user-specific data directory - std::string userDataPath() const; + /// deprecated: Path to writeable directory with user configs + std::string userConfigPath() const { return VCMIDirs::userConfigPath().string(); } - /// Path to "cache" directory, can be used for any non-essential files - std::string userCachePath() const; + /// deprecated: Path to saved games + std::string userSavePath() const { return VCMIDirs::userSavePath().string(); } - /// Path to writeable directory with user configs - std::string userConfigPath() const; + /// deprecated: Paths to global system-wide data directories. First items have higher priority + std::vector dataPaths() const + { + std::vector result; + for (const auto& path : VCMIDirs::dataPaths()) + result.push_back(path.string()); + return result; + } - /// Path to saved games - std::string userSavePath() const; + /// deprecated: Full path to client executable, including server name (e.g. /usr/bin/vcmiclient) + std::string clientPath() const { return VCMIDirs::clientPath().string(); } - /// Paths to global system-wide data directories. First items have higher priority - std::vector dataPaths() const; + /// deprecated: Full path to server executable, including server name (e.g. /usr/bin/vcmiserver) + std::string serverPath() const { return VCMIDirs::serverPath().string(); } - /// Full path to client executable, including server name (e.g. /usr/bin/vcmiclient) - std::string clientPath() const; + /// deprecated: Path where vcmi libraries can be found (in AI and Scripting subdirectories) + std::string libraryPath() const { return VCMIDirs::libraryPath().string(); } - /// Full path to server executable, including server name (e.g. /usr/bin/vcmiserver) - std::string serverPath() const; + /// deprecated: Returns system-specific name for dynamic libraries ( StupidAI => "libStupidAI.so" or "StupidAI.dll") + std::string libraryName(std::string basename) const { return VCMIDirs::libraryName(basename); } - /// Path where vcmi libraries can be found (in AI and Scripting subdirectories) - std::string libraryPath() const; - - /// Returns system-specific name for dynamic libraries ( StupidAI => "libStupidAI.so" or "StupidAI.dll") - std::string libraryName(std::string basename) const; - - std::string genHelpString() const; -}; + /// deprecated: + std::string genHelpString() const { return VCMIDirs::genHelpString(); } +}; \ No newline at end of file