Esempio n. 1
0
void PATHMANAGER::Init(std::ostream & info_output, std::ostream & error_output)
{
	typedef std::vector<fs::path> Paths;

	// Set Ogre plugins dir
	{
		ogre_plugin_dir = "";
		char *plugindir = getenv("OGRE_PLUGIN_DIR");
		if (plugindir) {
			ogre_plugin_dir = plugindir;
		#ifndef _WIN32
		} else if (fs::exists(fs::path(OGRE_PLUGIN_DIR) / "RenderSystem_GL.so")) {
			ogre_plugin_dir = OGRE_PLUGIN_DIR;
		#endif
		} else {
			#ifdef _WIN32
			ogre_plugin_dir = ".";
			#else
			Paths dirs;
			#if defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(_M_X64)
			dirs.push_back("/usr/local/lib64");
			dirs.push_back("/usr/lib64");
			#else
			dirs.push_back("/usr/local/lib32");
			dirs.push_back("/usr/lib32");
			#endif
			dirs.push_back("/usr/local");
			dirs.push_back("/usr/lib");
			// Loop through the paths and pick the first one that contain a plugin
			for (Paths::const_iterator p = dirs.begin(); p != dirs.end(); ++p) {
				if (fs::exists(*p / "OGRE/RenderSystem_GL.so")) {
					ogre_plugin_dir = (*p / "OGRE").string();
					break;
				} else if (fs::exists(*p / "ogre/RenderSystem_GL.so")) {
					ogre_plugin_dir = (*p / "ogre").string();
					break;
				}
			}
			#endif
		}
	}

	fs::path shortDir = "stuntrally";
	// Figure out the user's home directory
	{
		home_dir = "";
		#ifndef _WIN32 // POSIX
			char *homedir = getenv("HOME");
			if (homedir == NULL)
			{
				home_dir = "/home/";
				homedir = getenv("USER");
				if (homedir == NULL) {
					homedir = getenv("USERNAME");
					if (homedir == NULL) {
						error_output << "Could not find user's home directory!" << std::endl;
						home_dir = "/tmp/";
					}
				}
			}
		#else // Windows
			char *homedir = getenv("USERPROFILE");
			if (homedir == NULL) homedir = "data"; // WIN 9x/Me
		#endif
		home_dir += homedir;
	}

	// Find user's config dir
	#ifndef _WIN32 // POSIX
	{
		char const* conf = getenv("XDG_CONFIG_HOME");
		if (conf) user_config_dir = (fs::path(conf) / "stuntrally").string();
		else user_config_dir = (fs::path(home_dir) / ".config" / "stuntrally").string();
	}
	#else // Windows
	{
		// Open AppData directory
		std::string str;
		ITEMIDLIST* pidl;
		char AppDir[MAX_PATH];
		HRESULT hRes = SHGetSpecialFolderLocation(NULL, CSIDL_APPDATA|CSIDL_FLAG_CREATE , &pidl);
		if (hRes == NOERROR)
		{
			SHGetPathFromIDList(pidl, AppDir);
			int i;
			for (i = 0; AppDir[i] != '\0'; i++) {
				if (AppDir[i] == '\\') str += '/';
				else str += AppDir[i];
			}
			user_config_dir = (fs::path(str) / "stuntrally").string();
		}
	}
	#endif
	// Create user's config dir
	CreateDir(user_config_dir, error_output);

	// Find user's data dir (for additional data)
	#ifdef _WIN32
	user_data_dir = user_config_dir;  // APPDATA/stuntrally
	#else
	{
		fs::path shareDir = SHARED_DATA_DIR;
		char const* xdg_data_home = getenv("XDG_DATA_HOME");
		user_data_dir = (xdg_data_home ? xdg_data_home / shortDir : fs::path(home_dir) / ".local" / shareDir).string();
	}
	#endif
	// Create user's data dir and its children
	CreateDir(user_data_dir, error_output);
	CreateDir(GetTrackRecordsPath(), error_output);
	CreateDir(GetScreenShotDir(), error_output);
	CreateDir(GetTrackPathUser(), error_output);  // user tracks
	CreateDir(GetTrackPathUser()+"/_previews", error_output);
	CreateDir(GetReplayPath(), error_output);
	CreateDir(GetGhostsPath(), error_output);

	// Find game data dir and defaults config dir
	char *datadir = getenv("STUNTRALLY_DATA_ROOT");
	if (datadir)
		game_data_dir = std::string(datadir);
	else
	{	fs::path shareDir = SHARED_DATA_DIR;
		Paths dirs;

		// Adding users data dir
		// TODO: Disabled for now until this is handled properly
		//dirs.push_back(user_data_dir);

		// Adding relative path from installed executable
		dirs.push_back(execname().parent_path().parent_path() / shareDir);
		// Adding relative path for running from sources
		dirs.push_back(execname().parent_path().parent_path() / "data");
		dirs.push_back(execname().parent_path().parent_path());
		dirs.push_back(execname().parent_path() / "data");
		dirs.push_back(execname().parent_path());
		#ifndef _WIN32
		// Adding XDG_DATA_DIRS
		{
			char const* xdg_data_dirs = getenv("XDG_DATA_DIRS");
			std::istringstream iss(xdg_data_dirs ? xdg_data_dirs : "/usr/local/share/:/usr/share/");
			for (std::string p; std::getline(iss, p, ':'); dirs.push_back(p / shortDir)) {}
		}
		#endif
		// TODO: Adding path from config file

		// Loop through the paths and pick the first one that contain some data
		for (Paths::const_iterator p = dirs.begin(); p != dirs.end(); ++p) {
			// Data dir
			if (fs::exists(*p / "hud")) game_data_dir = p->string();
			// Config dir
			if (fs::exists(*p / "config"))
				game_config_dir = (*p / "config").string();
			// Check if both are found
			if (!game_data_dir.empty() && !game_config_dir.empty()) break;
		}
	}

	// Find cache dir
	#ifdef _WIN32
	cache_dir = user_config_dir + "/cache";  // APPDATA/stuntrally/cache
	#else
	char const* xdg_cache_home = getenv("XDG_CACHE_HOME");
	cache_dir = (xdg_cache_home ? xdg_cache_home / shortDir : fs::path(home_dir) / ".cache" / shortDir).string();
	#endif
	// Create cache dir
	CreateDir(cache_dir, error_output);
	CreateDir(GetShaderCacheDir(), error_output);

	// Print diagnostic info
	std::stringstream out;
	out << "--- Directories: ---" << ogre_plugin_dir << std::endl;
	out << "Ogre plugin:  " << ogre_plugin_dir << std::endl;
	out << "Home:         " << home_dir << std::endl;
	out << "Default cfg:  " << GetGameConfigDir() << std::endl;
	out << "User cfg:     " << GetUserConfigDir() << std::endl;
	out << "Data:         " << GetDataPath() << std::endl;
	out << "User data:    " << GetUserDataDir() << std::endl;
	out << "Cache:        " << GetCacheDir() << std::endl;
	out << "Shader cache: " << GetShaderCacheDir() << std::endl;
	out << "Log:          " << GetLogDir() << std::endl;
	info_output << out.str();
}
void PATHMANAGER::Init(bool log_paths)
{
	typedef vector<fs::path> Paths;

	// Set Ogre plugins dir
	{
		ogre_plugin = "";
		char *plugindir = getenv("OGRE_PLUGIN_DIR");
		if (plugindir) {
			ogre_plugin = plugindir;
		} else {
			#ifdef _WIN32
			ogre_plugin = ".";
			#else
			ogre_plugin = OGRE_PLUGIN_DIR_REL;
			#endif
		}
	}

	fs::path stuntrally = "stuntrally";
	// Figure out the user's home directory
	{
		home_dir = "";
		#ifndef _WIN32 // POSIX
			char *homedir = getenv("HOME");
			if (homedir == NULL)
			{
				home_dir = "/home/";
				homedir = getenv("USER");
				if (homedir == NULL) {
					homedir = getenv("USERNAME");
					if (homedir == NULL) {
						cerr << "Could not find user's home directory!" << endl;
						home_dir = "/tmp/";
					}
				}
			}
		#else // Windows
			char *homedir = getenv("USERPROFILE");
			if (homedir == NULL) homedir = "data"; // WIN 9x/Me
		#endif
		home_dir += homedir;
	}

	// Find user's config dir
	#ifndef _WIN32 // POSIX
	{
		char const* conf = getenv("XDG_CONFIG_HOME");
		if (conf) user_config = (fs::path(conf) / stuntrally).string();
		else user_config = (fs::path(home_dir) / ".config" / stuntrally).string();
	}
	#else // Windows
	{
		// Open AppData directory
		string str;
		ITEMIDLIST* pidl;
		char AppDir[MAX_PATH];
		HRESULT hRes = SHGetSpecialFolderLocation(NULL, CSIDL_APPDATA|CSIDL_FLAG_CREATE, &pidl);
		if (hRes == NOERROR)
		{
			SHGetPathFromIDList(pidl, AppDir);
			int i;
			for (i = 0; AppDir[i] != '\0'; ++i) {
				if (AppDir[i] == '\\') str += '/';
				else str += AppDir[i];
			}
			user_config = (fs::path(str) / stuntrally).string();
		}
	}
	#endif
	// Create user's config dir
	CreateDir(user_config);

	// Find user's data dir (for additional data)
	#ifdef _WIN32
	user_data = user_config;  // APPDATA/stuntrally
	#else
	{
		char const* xdg_data_home = getenv("XDG_DATA_HOME");
		user_data = (xdg_data_home ? xdg_data_home / stuntrally
					: fs::path(home_dir) / ".local/share" / stuntrally).string();
	}
	#endif

	// Create user's data dir and its children
	///--------------------------------------------------
	CreateDir(user_data);
	CreateDir(Records());
	CreateDir(Ghosts());
	
	CreateDir(Replays());
	CreateDir(Screenshots());
	CreateDir(TracksUser());  // user tracks

	CreateDir(DataUser());  // user data


	// Find game data dir and defaults config dir
	char *datadir = getenv("STUNTRALLY_DATA_ROOT");
	if (datadir)
		game_data = string(datadir);
	else
	{	fs::path shareDir = SHARED_DATA_DIR;
		Paths dirs;

		// Adding users data dir
		// TODO: Disabled for now until this is handled properly
		//dirs.push_back(user_data_dir);

		// Adding relative path for running from sources
		dirs.push_back(execname().parent_path().parent_path() / "data");
		dirs.push_back(execname().parent_path().parent_path());
		dirs.push_back(execname().parent_path() / "data");
		dirs.push_back(execname().parent_path());
		// Adding relative path from installed executable
		dirs.push_back(execname().parent_path().parent_path() / shareDir);
		#ifndef _WIN32
		// Adding XDG_DATA_DIRS
		{
			char const* xdg_data_dirs = getenv("XDG_DATA_DIRS");
			istringstream iss(xdg_data_dirs ? xdg_data_dirs : "/usr/local/share/:/usr/share/");
			for (string p; getline(iss, p, ':'); dirs.push_back(p / stuntrally)) {}
		}
		#endif
		// TODO: Adding path from config file

		//  Loop through the paths and pick the first one that contain some data
		for (Paths::const_iterator p = dirs.begin(); p != dirs.end(); ++p)
		{	//  Data dir
			if (fs::exists(*p / "hud"))
				game_data = p->string();
			//  Config dir
			if (fs::exists(*p / "config"))
				game_config = (*p / "config").string();
			//  Check if both are found
			if (!game_data.empty() && !game_config.empty())  break;
		}
	}


	//  Subdirs for each sim_mode
	///--------------------------------------------------
	list <string> li;
	PATHMANAGER::DirList(PATHMANAGER::CarSim(), li);
	for (list <string>::iterator i = li.begin(); i != li.end(); ++i)
	{
		CreateDir(Records()+"/"+*i);
		CreateDir(Ghosts()+"/"+*i);
	}

	// Find cache dir
	#ifdef _WIN32
	cache_dir = user_config + "/cache";  // APPDATA/stuntrally/cache
	#else
	char const* xdg_cache_home = getenv("XDG_CACHE_HOME");
	cache_dir = (xdg_cache_home ? xdg_cache_home / stuntrally
				: fs::path(home_dir) / ".cache" / stuntrally).string();
	#endif
	// Create cache dir
	CreateDir(CacheDir());
	CreateDir(CacheDir()+"/tracks");
	CreateDir(ShaderDir());

	// Print diagnostic info
	if (log_paths)
	{
		info << "Paths info" << endl;
		info << "-------------------------" << endl;
		info << "Ogre plugin:  " << ogre_plugin << endl;
		info << "Data:         " << Data() << endl;
		//info << "Default cfg:  " << GetGameConfigDir() << endl;
		info << "Home:         " << home_dir << endl;
		info << "User cfg,log: " << UserConfigDir() << endl;
		info << "User data:    " << user_data << endl;
		info << "Cache:        " << CacheDir() << endl;
		info << "-------------------------";
	}
}