mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	- (linux) XDG filesystem support
BIG NOTE TO LINUX USERS All user data has been moved according to XDG specs: - Game data (H3 files and mods) and saves: from ~/.vcmi to ~/.local/ - Temporary files, including logs: from ~/.vcmi to ~/.cache/vcmi - Config files: from ~/.vcmi/config to ~/.config/vcmi For compatibility VCMI will read game data from ~/.vcmi as well but this is temporary behavior and will be removed
This commit is contained in:
		| @@ -28,7 +28,7 @@ To compile, the following packages (and their development counterparts) are need | ||||
| 		- locale | ||||
|  | ||||
| On Debian-based systems (e.g. Ubuntu) run: | ||||
|   sudo apt-get install cmake g++ libsdl1.2debian libsdl-image1.2-dev libsdl-ttf2.0-dev libsdl-mixer1.2-dev zlib1g-dev libavformat-dev libswscale-dev libboost-dev libboost-filesystem-dev libboost-system-dev libboost-thread-dev libboost-program-options-dev | ||||
|   sudo apt-get install cmake g++ libsdl1.2debian libsdl-image1.2-dev libsdl-ttf2.0-dev libsdl-mixer1.2-dev zlib1g-dev libavformat-dev libswscale-dev libboost-dev libboost-filesystem-dev libboost-system-dev libboost-thread-dev libboost-program-options-dev libboost-locale-dev qtbase5-dev | ||||
|  | ||||
| On RPM-based distributions (e.g. Fedora) run: | ||||
|   sudo yum install cmake gcc-c++ SDL-devel SDL_image-devel SDL_ttf-devel SDL_mixer-devel boost boost-devel boost-filesystem boost-system boost-thread boost-program-options boost-locale zlib-devel ffmpeg-devel ffmpeg-libs | ||||
|   | ||||
| @@ -171,9 +171,14 @@ void init() | ||||
| static void prog_version(void) | ||||
| { | ||||
| 	printf("%s\n", GameConstants::VCMI_VERSION.c_str()); | ||||
| 	printf("  data directory:    %s\n", VCMIDirs::get().dataPaths().back().c_str()); | ||||
| 	printf("  library directory: %s\n", VCMIDirs::get().libraryPath().c_str()); | ||||
| 	printf("  path to server:    %s\n", VCMIDirs::get().serverPath().c_str()); | ||||
| 	printf("  game data:   %s\n", boost::algorithm::join(VCMIDirs::get().dataPaths(), ":").c_str()); | ||||
| 	printf("  libraries:   %s\n", VCMIDirs::get().libraryPath().c_str()); | ||||
| 	printf("  server:      %s\n", VCMIDirs::get().serverPath().c_str()); | ||||
| 	printf("\n"); | ||||
| 	printf("  user data:   %s\n", VCMIDirs::get().userDataPath().c_str()); | ||||
| 	printf("  user cache:  %s\n", VCMIDirs::get().userCachePath().c_str()); | ||||
| 	printf("  user config: %s\n", VCMIDirs::get().userConfigPath().c_str()); | ||||
| 	printf("  user saves:  %s\n", VCMIDirs::get().userSavePath().c_str()); | ||||
| } | ||||
|  | ||||
| static void prog_help(const po::options_description &opts) | ||||
|   | ||||
| @@ -8,6 +8,7 @@ static CLauncherDirs launcherDirsGlobal; | ||||
| CLauncherDirs::CLauncherDirs() | ||||
| { | ||||
| 	QDir().mkdir(downloadsPath()); | ||||
| 	QDir().mkdir(modsPath()); | ||||
| } | ||||
|  | ||||
| CLauncherDirs & CLauncherDirs::get() | ||||
| @@ -22,5 +23,5 @@ QString CLauncherDirs::downloadsPath() | ||||
|  | ||||
| QString CLauncherDirs::modsPath() | ||||
| { | ||||
| 	return QString::fromUtf8(VCMIDirs::get().userCachePath().c_str()) + "/Mods"; | ||||
| 	return QString::fromUtf8(VCMIDirs::get().userDataPath().c_str()) + "/Mods"; | ||||
| } | ||||
|   | ||||
| @@ -27,6 +27,9 @@ 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(); | ||||
| @@ -42,14 +45,6 @@ std::string VCMIDirs::userSavePath() const | ||||
| 	return userDataPath() + "/Games"; | ||||
| } | ||||
|  | ||||
| std::vector<std::string> VCMIDirs::configPaths() const | ||||
| { | ||||
| 	return std::vector<std::string>(1, dataPaths()[0] + "/config"); | ||||
| } | ||||
|  | ||||
| //FIXME: find way to at least decrease size of this ifdef (along with cleanup in CMake) | ||||
| #if defined(_WIN32) | ||||
|  | ||||
| std::string VCMIDirs::userDataPath() const | ||||
| { | ||||
| 	const std::string homeDir = std::getenv("userprofile"); | ||||
| @@ -84,6 +79,21 @@ std::string VCMIDirs::libraryName(std::string basename) const | ||||
|  | ||||
| #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... | ||||
| @@ -125,11 +135,9 @@ std::string VCMIDirs::libraryName(std::string basename) const | ||||
|  | ||||
| #else | ||||
|  | ||||
| std::string VCMIDirs::userDataPath() const | ||||
| std::string VCMIDirs::libraryName(std::string basename) const | ||||
| { | ||||
| 	if (getenv("HOME") != nullptr ) | ||||
| 		return std::string(getenv("HOME")) + "/.vcmi"; | ||||
| 	return "."; | ||||
| 	return "lib" + basename + ".so"; | ||||
| } | ||||
|  | ||||
| std::string VCMIDirs::libraryPath() const | ||||
| @@ -147,14 +155,68 @@ std::string VCMIDirs::serverPath() const | ||||
| 	return std::string(M_BIN_DIR) + "/" + "vcmiserver"; | ||||
| } | ||||
|  | ||||
| std::vector<std::string> VCMIDirs::dataPaths() const | ||||
| // $XDG_DATA_HOME, default: $HOME/.local/share | ||||
| std::string VCMIDirs::userDataPath() const | ||||
| { | ||||
| 	return std::vector<std::string>(1, M_DATA_DIR); | ||||
| 	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 "."; | ||||
| } | ||||
|  | ||||
| std::string VCMIDirs::libraryName(std::string basename) const | ||||
| std::string VCMIDirs::userSavePath() const | ||||
| { | ||||
| 	return "lib" + basename + ".so"; | ||||
| 	return userDataPath() + "/Saves"; | ||||
| } | ||||
|  | ||||
| // $XDG_CACHE_HOME, default: $HOME/.cache | ||||
| std::string VCMIDirs::userCachePath() const | ||||
| { | ||||
| 	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 "."; | ||||
| } | ||||
|  | ||||
| // $XDG_CONFIG_HOME, default: $HOME/.config | ||||
| std::string VCMIDirs::userConfigPath() const | ||||
| { | ||||
| 	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 "."; | ||||
| } | ||||
|  | ||||
| // $XDG_DATA_DIRS, default: /usr/local/share/:/usr/share/ | ||||
| std::vector<std::string> VCMIDirs::dataPaths() const | ||||
| { | ||||
| 	// construct list in reverse. | ||||
| 	// in specification first directory has highest priority | ||||
| 	// in vcmi fs last directory has highest priority | ||||
|  | ||||
| 	std::vector<std::string> ret; | ||||
|  | ||||
| 	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) | ||||
| 	{ | ||||
| 		std::string dataDirsEnv = getenv("XDG_DATA_DIRS"); | ||||
| 		std::vector<std::string> 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; | ||||
| } | ||||
|  | ||||
| #endif | ||||
|   | ||||
| @@ -33,9 +33,6 @@ public: | ||||
| 	/// Path to saved games | ||||
| 	std::string userSavePath() const; | ||||
|  | ||||
| 	/// Path to config directories, e.g. <data dir>/config. First items have higher priority | ||||
| 	std::vector<std::string> configPaths() const; | ||||
|  | ||||
| 	/// Paths to global system-wide data directories. First items have higher priority | ||||
| 	std::vector<std::string> dataPaths() const; | ||||
|  | ||||
|   | ||||
| @@ -140,10 +140,11 @@ void CResourceHandler::initialize() | ||||
| 	initialLoader = new CFilesystemList; | ||||
|  | ||||
| 	for (auto & path : VCMIDirs::get().dataPaths()) | ||||
| 		initialLoader->addLoader(new CFilesystemLoader("", path, 0, true), false); | ||||
|  | ||||
| 	if (VCMIDirs::get().dataPaths().back() != VCMIDirs::get().userDataPath()) | ||||
| 		initialLoader->addLoader(new CFilesystemLoader("", VCMIDirs::get().userDataPath(), 0, true), false); | ||||
| 	{ | ||||
| 		if (boost::filesystem::is_directory(path)) // some of system-provided paths may not exist | ||||
| 			initialLoader->addLoader(new CFilesystemLoader("", path, 0, true), false); | ||||
| 	} | ||||
| 	initialLoader->addLoader(new CFilesystemLoader("", VCMIDirs::get().userDataPath(), 0, true), false); | ||||
|  | ||||
| 	recurseInDir("CONFIG", 0);// look for configs | ||||
| 	recurseInDir("DATA", 0); // look for archives | ||||
|   | ||||
| @@ -163,7 +163,12 @@ fi | ||||
|  | ||||
| if [[ -z "$dest_dir" ]] | ||||
| then | ||||
| 	dest_dir="$HOME/.vcmi" | ||||
| 	if [[ -z "$XDG_DATA_HOME" ]] | ||||
| 	then | ||||
| 		dest_dir="$HOME/.local/share/vcmi" | ||||
| 	else | ||||
| 		dest_dir="$XDG_DATA_HOME/vcmi" | ||||
| 	fi | ||||
| fi | ||||
|  | ||||
| temp_dir="$dest_dir"/buildertmp | ||||
|   | ||||
		Reference in New Issue
	
	Block a user