Allow customizing user:// path (folder in OS::get_data_path())

This allows to specify any valid folder name (including with subfolders) to use
as user:// on all platforms. The folder is constrained to the platform-specific
OS::get_data_path() (typically what `XDG_DATA_HOME` resolves to).

Fixes #13236.
This commit is contained in:
Rémi Verschelde 2017-11-26 19:00:53 +01:00
parent 9cf44c1c53
commit af9c67db0c
6 changed files with 37 additions and 21 deletions

View file

@ -101,6 +101,6 @@ void _err_print_error(const char *p_function, const char *p_file, int p_line, co
void _err_print_index_error(const char *p_function, const char *p_file, int p_line, int64_t p_index, int64_t p_size, const char *p_index_str, const char *p_size_str, bool fatal) {
String fstr(fatal ? "FATAL: " : "");
String err(fstr + "Index" + p_index_str + "=" + itos(p_index) + " out of size (" + p_size_str + "=" + itos(p_size) + ")");
String err(fstr + "Index " + p_index_str + "=" + itos(p_index) + " out of size (" + p_size_str + "=" + itos(p_size) + ")");
_err_print_error(p_function, p_file, p_line, err.utf8().get_data());
}

View file

@ -279,14 +279,22 @@ String OS::get_locale() const {
return "en";
}
// Helper function used by OS_Unix and OS_Windows
String OS::get_safe_application_name() const {
String an = ProjectSettings::get_singleton()->get("application/config/name");
Vector<String> invalid_char = String("\\ / : * ? \" < > |").split(" ");
for (int i = 0; i < invalid_char.size(); i++) {
an = an.replace(invalid_char[i], "-");
// Helper function to ensure that a dir name/path will be valid on the OS
String OS::get_safe_dir_name(const String &p_dir_name, bool p_allow_dir_separator) const {
Vector<String> invalid_chars = String(": * ? \" < > |").split(" ");
if (p_allow_dir_separator) {
// Dir separators are allowed, but disallow ".." to avoid going up the filesystem
invalid_chars.push_back("..");
} else {
invalid_chars.push_back("/");
}
return an;
String safe_dir_name = p_dir_name.replace("\\", "/").strip_edges();
for (int i = 0; i < invalid_chars.size(); i++) {
safe_dir_name = safe_dir_name.replace(invalid_chars[i], "-");
}
return safe_dir_name;
}
// Path to data, config, cache, etc. OS-specific folders

View file

@ -338,7 +338,7 @@ public:
virtual String get_locale() const;
String get_safe_application_name() const;
String get_safe_dir_name(const String &p_dir_name, bool p_allow_dir_separator = false) const;
virtual String get_godot_dir_name() const;
virtual String get_data_path() const;

View file

@ -891,7 +891,8 @@ ProjectSettings::ProjectSettings() {
custom_prop_info["application/run/main_scene"] = PropertyInfo(Variant::STRING, "application/run/main_scene", PROPERTY_HINT_FILE, "tscn,scn,res");
GLOBAL_DEF("application/run/disable_stdout", false);
GLOBAL_DEF("application/run/disable_stderr", false);
GLOBAL_DEF("application/config/use_shared_user_dir", true);
GLOBAL_DEF("application/config/use_custom_user_dir", false);
GLOBAL_DEF("application/config/custom_user_dir_name", "");
key.instance();
key->set_scancode(KEY_ENTER);

View file

@ -447,13 +447,17 @@ int OS_Unix::get_processor_count() const {
String OS_Unix::get_user_data_dir() const {
String appname = get_safe_application_name();
String appname = get_safe_dir_name(ProjectSettings::get_singleton()->get("application/config/name"));
if (appname != "") {
bool use_godot_dir = ProjectSettings::get_singleton()->get("application/config/use_shared_user_dir");
if (use_godot_dir) {
return get_data_path().plus_file(get_godot_dir_name()).plus_file("app_userdata").plus_file(appname);
bool use_custom_dir = ProjectSettings::get_singleton()->get("application/config/use_custom_user_dir");
if (use_custom_dir) {
String custom_dir = get_safe_dir_name(ProjectSettings::get_singleton()->get("application/config/custom_user_dir_name"), true);
if (custom_dir == "") {
custom_dir = appname;
}
return get_data_path().plus_file(custom_dir);
} else {
return get_data_path().plus_file(appname);
return get_data_path().plus_file(get_godot_dir_name()).plus_file("app_userdata").plus_file(appname);
}
}

View file

@ -2199,14 +2199,17 @@ String OS_Windows::get_system_dir(SystemDir p_dir) const {
String OS_Windows::get_user_data_dir() const {
String appname = get_safe_application_name();
String appname = get_safe_dir_name(ProjectSettings::get_singleton()->get("application/config/name"));
if (appname != "") {
bool use_godot_dir = ProjectSettings::get_singleton()->get("application/config/use_shared_user_dir");
if (use_godot_dir) {
return get_data_path().plus_file(get_godot_dir_name()).plus_file("app_userdata").plus_file(appname).replace("\\", "/");
bool use_custom_dir = ProjectSettings::get_singleton()->get("application/config/use_custom_user_dir");
if (use_custom_dir) {
String custom_dir = get_safe_dir_name(ProjectSettings::get_singleton()->get("application/config/custom_user_dir_name"), true);
if (custom_dir == "") {
custom_dir = appname;
}
return get_data_path().plus_file(custom_dir).replace("\\", "/");
} else {
return get_data_path().plus_file(appname).replace("\\", "/");
return get_data_path().plus_file(get_godot_dir_name()).plus_file("app_userdata").plus_file(appname).replace("\\", "/");
}
}