601 lines
17 KiB
C++
601 lines
17 KiB
C++
#include "path_info.h"
|
|
|
|
#include <cstdlib>
|
|
#include <string>
|
|
|
|
#include "enums.h"
|
|
#include "filesystem.h" // IWYU pragma: keep
|
|
#include "make_static.h"
|
|
#include "options.h"
|
|
#include "rng.h"
|
|
#include "system_locale.h"
|
|
|
|
#if defined(_WIN32)
|
|
#include <windows.h>
|
|
#endif
|
|
|
|
/**
|
|
* Return a locale specific path, or if there is no path for the current
|
|
* locale, return the default path.
|
|
* @param path The local path is based on that value.
|
|
* @param extension File name extension, is automatically added to the path
|
|
* of the translated file. Can be empty, but must otherwise include the
|
|
* initial '.', e.g. ".json"
|
|
* @param fallback The path of the fallback filename.
|
|
* It is used if no translated file can be found.
|
|
*/
|
|
static std::string find_translated_file( const std::string &path, const std::string &extension,
|
|
const std::string &fallback );
|
|
static cata_path find_translated_file( const cata_path &base_path, const std::string &extension,
|
|
const cata_path &fallback );
|
|
|
|
static std::string motd_value;
|
|
static std::string gfxdir_value;
|
|
static std::string config_dir_value;
|
|
static std::string user_dir_value;
|
|
static std::string datadir_value;
|
|
static std::string base_path_value;
|
|
static std::string savedir_value;
|
|
static std::string autopickup_value;
|
|
static std::string autonote_value;
|
|
static std::string keymap_value;
|
|
static std::string options_value;
|
|
static std::string memorialdir_value;
|
|
static std::string langdir_value;
|
|
|
|
|
|
static cata_path autonote_path_value;
|
|
static cata_path autopickup_path_value;
|
|
static cata_path base_path_path_value;
|
|
static cata_path config_dir_path_value;
|
|
static cata_path datadir_path_value;
|
|
static cata_path gfxdir_path_value;
|
|
static cata_path keymap_path_value;
|
|
static cata_path langdir_path_value;
|
|
static cata_path memorialdir_path_value;
|
|
static cata_path motd_path_value;
|
|
static cata_path options_path_value;
|
|
static cata_path savedir_path_value;
|
|
static cata_path user_dir_path_value;
|
|
|
|
void PATH_INFO::init_base_path( std::string path )
|
|
{
|
|
if( !path.empty() ) {
|
|
const char ch = path.back();
|
|
if( ch != '/' && ch != '\\' ) {
|
|
path.push_back( '/' );
|
|
}
|
|
}
|
|
|
|
base_path_value = path;
|
|
base_path_path_value = cata_path{ cata_path::root_path::base, fs::path{} };
|
|
}
|
|
|
|
void PATH_INFO::init_user_dir( std::string dir )
|
|
{
|
|
if( dir.empty() ) {
|
|
const char *user_dir;
|
|
#if defined(_WIN32)
|
|
user_dir = getenv( "LOCALAPPDATA" );
|
|
// On Windows userdir without dot
|
|
dir = std::string( user_dir ) + "/cataclysm-dda/";
|
|
#elif defined(MACOSX)
|
|
user_dir = getenv( "HOME" );
|
|
dir = std::string( user_dir ) + "/Library/Application Support/Cataclysm/";
|
|
#elif defined(USE_XDG_DIR)
|
|
if( ( user_dir = getenv( "XDG_DATA_HOME" ) ) ) {
|
|
dir = std::string( user_dir ) + "/cataclysm-dda/";
|
|
} else {
|
|
user_dir = getenv( "HOME" );
|
|
dir = std::string( user_dir ) + "/.local/share/cataclysm-dda/";
|
|
}
|
|
#else
|
|
user_dir = getenv( "HOME" );
|
|
dir = std::string( user_dir ) + "/.cataclysm-dda/";
|
|
#endif
|
|
}
|
|
|
|
user_dir_value = dir;
|
|
user_dir_path_value = cata_path{ cata_path::root_path::user, fs::path{} };
|
|
}
|
|
|
|
void PATH_INFO::set_standard_filenames()
|
|
{
|
|
// Special: data_dir and gfx_dir
|
|
std::string prefix;
|
|
cata_path prefix_path;
|
|
|
|
// Data is always relative to itself. Also, the base path might not be writeable.
|
|
datadir_path_value = cata_path{ cata_path::root_path::data, fs::path{} };
|
|
|
|
if( !base_path_value.empty() ) {
|
|
#if defined(DATA_DIR_PREFIX)
|
|
datadir_value = base_path_value + "share/cataclysm-dda/";
|
|
prefix = datadir_value;
|
|
prefix_path = datadir_path_value;
|
|
#else
|
|
datadir_value = base_path_value + "data/";
|
|
prefix = base_path_value;
|
|
prefix_path = base_path_path_value;
|
|
#endif
|
|
} else {
|
|
datadir_value = "data/";
|
|
// Base path is empty here but everything else is still relative to base, which is empty.
|
|
prefix_path = base_path_path_value;
|
|
}
|
|
|
|
gfxdir_value = prefix + "gfx/";
|
|
gfxdir_path_value = prefix_path / "gfx";
|
|
langdir_value = prefix + "lang/mo/";
|
|
langdir_path_value = prefix_path / "lang" / "mo";
|
|
|
|
// Shared dirs
|
|
|
|
// Shared files
|
|
motd_value = datadir_value + "motd/" + "en.motd";
|
|
|
|
savedir_value = user_dir_value + "save/";
|
|
// Special: savedir is always relative to itself even if in the user dir location.
|
|
savedir_path_value = cata_path{ cata_path::root_path::save, fs::path{} };
|
|
memorialdir_value = user_dir_value + "memorial/";
|
|
memorialdir_path_value = user_dir_path_value / "memorial";
|
|
|
|
#if defined(USE_XDG_DIR)
|
|
const char *user_dir;
|
|
std::string dir;
|
|
if( ( user_dir = getenv( "XDG_CONFIG_HOME" ) ) ) {
|
|
dir = std::string( user_dir ) + "/cataclysm-dda/";
|
|
} else {
|
|
user_dir = getenv( "HOME" );
|
|
dir = std::string( user_dir ) + "/.config/cataclysm-dda/";
|
|
}
|
|
config_dir_value = dir;
|
|
config_dir_path_value = cata_path{ cata_path::root_path::config, fs::path{} };
|
|
#else
|
|
config_dir_value = user_dir_value + "config/";
|
|
config_dir_path_value = user_dir_path_value / "config";
|
|
#endif
|
|
options_value = config_dir_value + "options.json";
|
|
options_path_value = config_dir_path_value / "options.json";
|
|
keymap_value = config_dir_value + "keymap.txt";
|
|
autopickup_value = config_dir_value + "auto_pickup.json";
|
|
autopickup_path_value = config_dir_path_value / "auto_pickup.json";
|
|
autonote_value = config_dir_value + "auto_note.json";
|
|
autonote_path_value = config_dir_path_value / "auto_note.json";
|
|
}
|
|
|
|
std::string find_translated_file( const std::string &base_path, const std::string &extension,
|
|
const std::string &fallback )
|
|
{
|
|
#if defined(LOCALIZE) && !defined(__CYGWIN__)
|
|
const std::string language_option = get_option<std::string>( "USE_LANG" );
|
|
const std::string loc_name = language_option.empty() ? SystemLocale::Language().value_or( "" ) :
|
|
language_option;
|
|
if( !loc_name.empty() ) {
|
|
std::string local_path = base_path + loc_name + extension;
|
|
if( file_exist( local_path ) ) {
|
|
return local_path;
|
|
}
|
|
}
|
|
#else
|
|
( void ) base_path;
|
|
( void ) extension;
|
|
#endif
|
|
return fallback;
|
|
}
|
|
|
|
cata_path find_translated_file( const cata_path &base_path, const std::string &extension,
|
|
const cata_path &fallback )
|
|
{
|
|
#if defined(LOCALIZE) && !defined(__CYGWIN__)
|
|
const std::string language_option = get_option<std::string>( "USE_LANG" );
|
|
const std::string loc_name = language_option.empty() ? SystemLocale::Language().value_or( "" ) :
|
|
language_option;
|
|
if( !loc_name.empty() ) {
|
|
cata_path local_path = base_path / ( loc_name + extension );
|
|
if( file_exist( local_path ) ) {
|
|
return local_path;
|
|
}
|
|
}
|
|
#else
|
|
( void )base_path;
|
|
( void )extension;
|
|
#endif
|
|
return fallback;
|
|
}
|
|
|
|
cata_path PATH_INFO::autopickup()
|
|
{
|
|
return autopickup_path_value;
|
|
}
|
|
cata_path PATH_INFO::autonote()
|
|
{
|
|
return autonote_path_value;
|
|
}
|
|
cata_path PATH_INFO::base_colors()
|
|
{
|
|
return config_dir_path_value / "base_colors.json";
|
|
}
|
|
std::string PATH_INFO::base_path()
|
|
{
|
|
return base_path_value;
|
|
}
|
|
cata_path PATH_INFO::base_path_path()
|
|
{
|
|
return base_path_path_value;
|
|
}
|
|
std::string PATH_INFO::cache_dir()
|
|
{
|
|
return datadir_value + "cache/";
|
|
}
|
|
cata_path PATH_INFO::colors()
|
|
{
|
|
return datadir_path_value / "raw" / "colors.json";
|
|
}
|
|
cata_path PATH_INFO::color_templates()
|
|
{
|
|
return datadir_path_value / "raw" / "color_templates";
|
|
}
|
|
cata_path PATH_INFO::color_themes()
|
|
{
|
|
return datadir_path_value / "raw" / "color_themes";
|
|
}
|
|
std::string PATH_INFO::config_dir()
|
|
{
|
|
return config_dir_value;
|
|
}
|
|
cata_path PATH_INFO::config_dir_path()
|
|
{
|
|
return config_dir_path_value;
|
|
}
|
|
cata_path PATH_INFO::custom_colors()
|
|
{
|
|
return config_dir_path_value / "custom_colors.json";
|
|
}
|
|
std::string PATH_INFO::datadir()
|
|
{
|
|
return datadir_value;
|
|
}
|
|
cata_path PATH_INFO::datadir_path()
|
|
{
|
|
return datadir_path_value;
|
|
}
|
|
std::string PATH_INFO::debug()
|
|
{
|
|
return config_dir_value + "debug.log";
|
|
}
|
|
cata_path PATH_INFO::defaultsounddir()
|
|
{
|
|
return datadir_path_value / "sound";
|
|
}
|
|
std::string PATH_INFO::defaulttilejson()
|
|
{
|
|
return "tile_config.json";
|
|
}
|
|
std::string PATH_INFO::defaultlayeringjson()
|
|
{
|
|
return "layering.json";
|
|
}
|
|
std::string PATH_INFO::defaulttilepng()
|
|
{
|
|
return "tinytile.png";
|
|
}
|
|
cata_path PATH_INFO::fontdata()
|
|
{
|
|
return config_dir_path_value / "fonts.json";
|
|
}
|
|
std::string PATH_INFO::fontdir()
|
|
{
|
|
return datadir_value + "font/";
|
|
}
|
|
std::string PATH_INFO::user_font()
|
|
{
|
|
return user_dir_value + "font/";
|
|
}
|
|
std::string PATH_INFO::graveyarddir()
|
|
{
|
|
return user_dir_value + "graveyard/";
|
|
}
|
|
cata_path PATH_INFO::help()
|
|
{
|
|
return datadir_path_value / "help" / "texts.json";
|
|
}
|
|
cata_path PATH_INFO::keybindings()
|
|
{
|
|
return datadir_path_value / "raw" / "keybindings.json";
|
|
}
|
|
cata_path PATH_INFO::keybindings_vehicle()
|
|
{
|
|
return datadir_path_value / "raw" / "keybindings" / "vehicle.json";
|
|
}
|
|
std::string PATH_INFO::keymap()
|
|
{
|
|
return keymap_value;
|
|
}
|
|
cata_path PATH_INFO::lastworld()
|
|
{
|
|
return config_dir_path_value / "lastworld.json";
|
|
}
|
|
cata_path PATH_INFO::legacy_fontdata()
|
|
{
|
|
return datadir_path_value / "fontdata.json";
|
|
}
|
|
std::string PATH_INFO::memorialdir()
|
|
{
|
|
return memorialdir_value;
|
|
}
|
|
cata_path PATH_INFO::memorialdir_path()
|
|
{
|
|
return memorialdir_path_value;
|
|
}
|
|
cata_path PATH_INFO::jsondir()
|
|
{
|
|
return datadir_path_value / "core";
|
|
}
|
|
cata_path PATH_INFO::moddir()
|
|
{
|
|
return datadir_path_value / "mods";
|
|
}
|
|
cata_path PATH_INFO::options()
|
|
{
|
|
return options_path_value;
|
|
}
|
|
cata_path PATH_INFO::panel_options()
|
|
{
|
|
return config_dir_path_value / "panel_options.json";
|
|
}
|
|
cata_path PATH_INFO::safemode()
|
|
{
|
|
return config_dir_path_value / "safemode.json";
|
|
}
|
|
std::string PATH_INFO::savedir()
|
|
{
|
|
return savedir_value;
|
|
}
|
|
cata_path PATH_INFO::savedir_path()
|
|
{
|
|
return savedir_path_value;
|
|
}
|
|
std::string PATH_INFO::sokoban()
|
|
{
|
|
return datadir_value + "raw/" + "sokoban.txt";
|
|
}
|
|
std::string PATH_INFO::templatedir()
|
|
{
|
|
return user_dir_value + "templates/";
|
|
}
|
|
cata_path PATH_INFO::templatedir_path()
|
|
{
|
|
return user_dir_path_value / "templates";
|
|
}
|
|
std::string PATH_INFO::user_dir()
|
|
{
|
|
return user_dir_value;
|
|
}
|
|
cata_path PATH_INFO::user_dir_path()
|
|
{
|
|
return user_dir_path_value;
|
|
}
|
|
cata_path PATH_INFO::user_gfx()
|
|
{
|
|
return user_dir_path_value / "gfx";
|
|
}
|
|
cata_path PATH_INFO::user_keybindings()
|
|
{
|
|
return config_dir_path_value / "keybindings.json";
|
|
}
|
|
std::string PATH_INFO::user_moddir()
|
|
{
|
|
return user_dir_value + "mods/";
|
|
}
|
|
cata_path PATH_INFO::user_moddir_path()
|
|
{
|
|
return user_dir_path_value / "mods";
|
|
}
|
|
cata_path PATH_INFO::user_sound()
|
|
{
|
|
return user_dir_path_value / "sound";
|
|
}
|
|
std::string PATH_INFO::worldoptions()
|
|
{
|
|
return "worldoptions.json";
|
|
}
|
|
std::string PATH_INFO::crash()
|
|
{
|
|
return config_dir_value + "crash.log";
|
|
}
|
|
std::string PATH_INFO::tileset_conf()
|
|
{
|
|
return "tileset.txt";
|
|
}
|
|
cata_path PATH_INFO::mods_replacements()
|
|
{
|
|
return datadir_path_value / "mods" / "replacements.json";
|
|
}
|
|
cata_path PATH_INFO::mods_dev_default()
|
|
{
|
|
return datadir_path_value / "mods" / "default.json";
|
|
}
|
|
cata_path PATH_INFO::mods_user_default()
|
|
{
|
|
return config_dir_path_value / "user-default-mods.json";
|
|
}
|
|
std::string PATH_INFO::soundpack_conf()
|
|
{
|
|
return "soundpack.txt";
|
|
}
|
|
cata_path PATH_INFO::gfxdir()
|
|
{
|
|
return gfxdir_path_value;
|
|
}
|
|
std::string PATH_INFO::langdir()
|
|
{
|
|
return langdir_value;
|
|
}
|
|
cata_path PATH_INFO::langdir_path()
|
|
{
|
|
return langdir_path_value;
|
|
}
|
|
std::string PATH_INFO::lang_file()
|
|
{
|
|
return "cataclysm-dda.mo";
|
|
}
|
|
cata_path PATH_INFO::data_sound()
|
|
{
|
|
return datadir_path_value / "sound";
|
|
}
|
|
|
|
std::string PATH_INFO::credits()
|
|
{
|
|
return find_translated_file( datadir_value + "credits/", ".credits",
|
|
datadir_value + "credits/" + "en.credits" );
|
|
}
|
|
|
|
std::string PATH_INFO::motd()
|
|
{
|
|
return find_translated_file( datadir_value + "motd/", ".motd", motd_value );
|
|
}
|
|
|
|
std::string PATH_INFO::title( const holiday current_holiday )
|
|
{
|
|
std::string theme_basepath = datadir_value + "title/";
|
|
std::string theme_extension = ".title";
|
|
std::string theme_fallback = theme_basepath + "en.title";
|
|
|
|
if( !get_option<bool>( "ENABLE_ASCII_TITLE" ) ) {
|
|
return _( "Cataclysm: Dark Days Ahead" );
|
|
}
|
|
|
|
if( x_in_y( get_option<int>( "ALT_TITLE" ), 100 ) ) {
|
|
theme_extension = ".alt1";
|
|
theme_fallback = datadir_value + "title/" + "en.alt1";
|
|
}
|
|
|
|
if( !get_option<bool>( "SEASONAL_TITLE" ) ) {
|
|
return find_translated_file( theme_basepath, theme_extension, theme_fallback );
|
|
}
|
|
|
|
switch( current_holiday ) {
|
|
case holiday::new_year:
|
|
theme_extension = ".new_year";
|
|
theme_fallback = datadir_value + "title/" + "en.new_year";
|
|
break;
|
|
case holiday::easter:
|
|
theme_extension = ".easter";
|
|
theme_fallback = datadir_value + "title/" + "en.easter";
|
|
break;
|
|
case holiday::independence_day:
|
|
theme_extension = ".independence_day";
|
|
theme_fallback = datadir_value + "title/" + "en.independence_day";
|
|
break;
|
|
case holiday::halloween:
|
|
theme_extension = ".halloween";
|
|
theme_fallback = datadir_value + "title/" + "en.halloween";
|
|
break;
|
|
case holiday::thanksgiving:
|
|
theme_extension = ".thanksgiving";
|
|
theme_fallback = datadir_value + "title/" + "en.thanksgiving";
|
|
break;
|
|
case holiday::christmas:
|
|
theme_extension = ".christmas";
|
|
theme_fallback = datadir_value + "title/" + "en.christmas";
|
|
break;
|
|
case holiday::none:
|
|
case holiday::num_holiday:
|
|
default:
|
|
break;
|
|
}
|
|
return find_translated_file( theme_basepath, theme_extension, theme_fallback );
|
|
}
|
|
|
|
cata_path PATH_INFO::names()
|
|
{
|
|
return find_translated_file( datadir_path_value / "names", ".json",
|
|
datadir_path_value / "names" / "en.json" );
|
|
}
|
|
|
|
void PATH_INFO::set_datadir( const std::string &datadir )
|
|
{
|
|
datadir_value = datadir;
|
|
datadir_path_value = cata_path{ cata_path::root_path::data, fs::path{} };
|
|
// Shared dirs
|
|
gfxdir_value = datadir_value + "gfx/";
|
|
gfxdir_path_value = datadir_path_value / "gfx";
|
|
|
|
// Shared files
|
|
motd_value = datadir_value + "motd/" + "en.motd";
|
|
motd_path_value = datadir_path_value / "motd" / "en.motd";
|
|
}
|
|
|
|
void PATH_INFO::set_config_dir( const std::string &config_dir )
|
|
{
|
|
config_dir_value = config_dir;
|
|
config_dir_path_value = cata_path{ cata_path::root_path::config, fs::path{} };
|
|
options_value = config_dir_value + "options.json";
|
|
options_path_value = config_dir_path_value / "options.json";
|
|
keymap_value = config_dir_value + "keymap.txt";
|
|
keymap_path_value = config_dir_path_value / "keymap.txt";
|
|
autopickup_value = config_dir_value + "auto_pickup.json";
|
|
autopickup_path_value = config_dir_path_value / "auto_pickup.json";
|
|
}
|
|
|
|
void PATH_INFO::set_savedir( const std::string &savedir )
|
|
{
|
|
savedir_value = savedir;
|
|
savedir_path_value = cata_path{ cata_path::root_path::save, fs::path{} };
|
|
}
|
|
|
|
void PATH_INFO::set_memorialdir( const std::string &memorialdir )
|
|
{
|
|
memorialdir_value = memorialdir;
|
|
memorialdir_path_value = cata_path{ cata_path::root_path::memorial, fs::path{} };
|
|
}
|
|
|
|
void PATH_INFO::set_options( const std::string &options )
|
|
{
|
|
options_value = options;
|
|
options_path_value = cata_path{cata_path::root_path::unknown, options_value};
|
|
}
|
|
|
|
void PATH_INFO::set_keymap( const std::string &keymap )
|
|
{
|
|
keymap_value = keymap;
|
|
}
|
|
|
|
void PATH_INFO::set_autopickup( const std::string &autopickup )
|
|
{
|
|
autopickup_value = autopickup;
|
|
autopickup_path_value = cata_path{ cata_path::root_path::unknown, autopickup_value };
|
|
}
|
|
|
|
void PATH_INFO::set_motd( const std::string &motd )
|
|
{
|
|
motd_value = motd;
|
|
}
|
|
|
|
fs::path cata_path::get_logical_root_path() const
|
|
{
|
|
const std::string &path_value = ( []( cata_path::root_path root ) -> const std::string& {
|
|
switch( root )
|
|
{
|
|
case cata_path::root_path::base:
|
|
return base_path_value;
|
|
case cata_path::root_path::config:
|
|
return config_dir_value;
|
|
case cata_path::root_path::data:
|
|
return datadir_value;
|
|
case cata_path::root_path::memorial:
|
|
return memorialdir_value;
|
|
case cata_path::root_path::save:
|
|
return savedir_value;
|
|
case cata_path::root_path::user:
|
|
return user_dir_value;
|
|
case cata_path::root_path::unknown:
|
|
default: {
|
|
return STATIC( std::string() );
|
|
}
|
|
}
|
|
} )( logical_root_ );
|
|
return fs::path{ path_value };
|
|
}
|