You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-05 12:10:55 +00:00
Fix "res://" being replaced by resource packs in the editor and on Android
This commit is contained in:
@@ -472,13 +472,30 @@ void ProjectSettings::_emit_changed() {
|
|||||||
emit_signal("settings_changed");
|
emit_signal("settings_changed");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ProjectSettings::_load_resource_pack(const String &p_pack, bool p_replace_files, int p_offset) {
|
bool ProjectSettings::load_resource_pack(const String &p_pack, bool p_replace_files, int p_offset) {
|
||||||
|
return ProjectSettings::_load_resource_pack(p_pack, p_replace_files, p_offset, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ProjectSettings::_load_resource_pack(const String &p_pack, bool p_replace_files, int p_offset, bool p_main_pack) {
|
||||||
if (PackedData::get_singleton()->is_disabled()) {
|
if (PackedData::get_singleton()->is_disabled()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ok = PackedData::get_singleton()->add_pack(p_pack, p_replace_files, p_offset) == OK;
|
if (p_pack == "res://") {
|
||||||
|
// Loading the resource directory as a pack source is reserved for internal use only.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!p_main_pack && !using_datapack && !OS::get_singleton()->get_resource_dir().is_empty()) {
|
||||||
|
// Add the project's resource file system to PackedData so directory access keeps working when
|
||||||
|
// the game is running without a main pack, like in the editor or on Android.
|
||||||
|
PackedData::get_singleton()->add_pack_source(memnew(PackedSourceDirectory));
|
||||||
|
PackedData::get_singleton()->add_pack("res://", false, 0);
|
||||||
|
DirAccess::make_default<DirAccessPack>(DirAccess::ACCESS_RESOURCES);
|
||||||
|
using_datapack = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ok = PackedData::get_singleton()->add_pack(p_pack, p_replace_files, p_offset) == OK;
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -491,9 +508,11 @@ bool ProjectSettings::_load_resource_pack(const String &p_pack, bool p_replace_f
|
|||||||
ResourceUID::get_singleton()->load_from_cache(false);
|
ResourceUID::get_singleton()->load_from_cache(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
//if data.pck is found, all directory access will be from here
|
// If the data pack was found, all directory access will be from here.
|
||||||
|
if (!using_datapack) {
|
||||||
DirAccess::make_default<DirAccessPack>(DirAccess::ACCESS_RESOURCES);
|
DirAccess::make_default<DirAccessPack>(DirAccess::ACCESS_RESOURCES);
|
||||||
using_datapack = true;
|
using_datapack = true;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -572,7 +591,7 @@ Error ProjectSettings::_setup(const String &p_path, const String &p_main_pack, b
|
|||||||
// Attempt with a user-defined main pack first
|
// Attempt with a user-defined main pack first
|
||||||
|
|
||||||
if (!p_main_pack.is_empty()) {
|
if (!p_main_pack.is_empty()) {
|
||||||
bool ok = _load_resource_pack(p_main_pack);
|
bool ok = _load_resource_pack(p_main_pack, false, 0, true);
|
||||||
ERR_FAIL_COND_V_MSG(!ok, ERR_CANT_OPEN, vformat("Cannot open resource pack '%s'.", p_main_pack));
|
ERR_FAIL_COND_V_MSG(!ok, ERR_CANT_OPEN, vformat("Cannot open resource pack '%s'.", p_main_pack));
|
||||||
|
|
||||||
Error err = _load_settings_text_or_binary("res://project.godot", "res://project.binary");
|
Error err = _load_settings_text_or_binary("res://project.godot", "res://project.binary");
|
||||||
@@ -591,7 +610,7 @@ Error ProjectSettings::_setup(const String &p_path, const String &p_main_pack, b
|
|||||||
// and if so, we attempt loading it at the end.
|
// and if so, we attempt loading it at the end.
|
||||||
|
|
||||||
// Attempt with PCK bundled into executable.
|
// Attempt with PCK bundled into executable.
|
||||||
bool found = _load_resource_pack(exec_path);
|
bool found = _load_resource_pack(exec_path, false, 0, true);
|
||||||
|
|
||||||
// Attempt with exec_name.pck.
|
// Attempt with exec_name.pck.
|
||||||
// (This is the usual case when distributing a Godot game.)
|
// (This is the usual case when distributing a Godot game.)
|
||||||
@@ -607,20 +626,20 @@ Error ProjectSettings::_setup(const String &p_path, const String &p_main_pack, b
|
|||||||
#ifdef MACOS_ENABLED
|
#ifdef MACOS_ENABLED
|
||||||
if (!found) {
|
if (!found) {
|
||||||
// Attempt to load PCK from macOS .app bundle resources.
|
// Attempt to load PCK from macOS .app bundle resources.
|
||||||
found = _load_resource_pack(OS::get_singleton()->get_bundle_resource_dir().path_join(exec_basename + ".pck")) || _load_resource_pack(OS::get_singleton()->get_bundle_resource_dir().path_join(exec_filename + ".pck"));
|
found = _load_resource_pack(OS::get_singleton()->get_bundle_resource_dir().path_join(exec_basename + ".pck"), false, 0, true) || _load_resource_pack(OS::get_singleton()->get_bundle_resource_dir().path_join(exec_filename + ".pck"), false, 0, true);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!found) {
|
if (!found) {
|
||||||
// Try to load data pack at the location of the executable.
|
// Try to load data pack at the location of the executable.
|
||||||
// As mentioned above, we have two potential names to attempt.
|
// As mentioned above, we have two potential names to attempt.
|
||||||
found = _load_resource_pack(exec_dir.path_join(exec_basename + ".pck")) || _load_resource_pack(exec_dir.path_join(exec_filename + ".pck"));
|
found = _load_resource_pack(exec_dir.path_join(exec_basename + ".pck"), false, 0, true) || _load_resource_pack(exec_dir.path_join(exec_filename + ".pck"), false, 0, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!found) {
|
if (!found) {
|
||||||
// If we couldn't find them next to the executable, we attempt
|
// If we couldn't find them next to the executable, we attempt
|
||||||
// the current working directory. Same story, two tests.
|
// the current working directory. Same story, two tests.
|
||||||
found = _load_resource_pack(exec_basename + ".pck") || _load_resource_pack(exec_filename + ".pck");
|
found = _load_resource_pack(exec_basename + ".pck", false, 0, true) || _load_resource_pack(exec_filename + ".pck", false, 0, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we opened our package, try and load our project.
|
// If we opened our package, try and load our project.
|
||||||
@@ -1418,7 +1437,7 @@ void ProjectSettings::_bind_methods() {
|
|||||||
ClassDB::bind_method(D_METHOD("localize_path", "path"), &ProjectSettings::localize_path);
|
ClassDB::bind_method(D_METHOD("localize_path", "path"), &ProjectSettings::localize_path);
|
||||||
ClassDB::bind_method(D_METHOD("globalize_path", "path"), &ProjectSettings::globalize_path);
|
ClassDB::bind_method(D_METHOD("globalize_path", "path"), &ProjectSettings::globalize_path);
|
||||||
ClassDB::bind_method(D_METHOD("save"), &ProjectSettings::save);
|
ClassDB::bind_method(D_METHOD("save"), &ProjectSettings::save);
|
||||||
ClassDB::bind_method(D_METHOD("load_resource_pack", "pack", "replace_files", "offset"), &ProjectSettings::_load_resource_pack, DEFVAL(true), DEFVAL(0));
|
ClassDB::bind_method(D_METHOD("load_resource_pack", "pack", "replace_files", "offset"), &ProjectSettings::load_resource_pack, DEFVAL(true), DEFVAL(0));
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("save_custom", "file"), &ProjectSettings::_save_custom_bnd);
|
ClassDB::bind_method(D_METHOD("save_custom", "file"), &ProjectSettings::_save_custom_bnd);
|
||||||
|
|
||||||
|
|||||||
@@ -135,7 +135,8 @@ protected:
|
|||||||
|
|
||||||
void _convert_to_last_version(int p_from_version);
|
void _convert_to_last_version(int p_from_version);
|
||||||
|
|
||||||
bool _load_resource_pack(const String &p_pack, bool p_replace_files = true, int p_offset = 0);
|
bool load_resource_pack(const String &p_pack, bool p_replace_files, int p_offset);
|
||||||
|
bool _load_resource_pack(const String &p_pack, bool p_replace_files = true, int p_offset = 0, bool p_main_pack = false);
|
||||||
|
|
||||||
void _add_property_info_bind(const Dictionary &p_info);
|
void _add_property_info_bind(const Dictionary &p_info);
|
||||||
|
|
||||||
|
|||||||
@@ -331,6 +331,44 @@ Ref<FileAccess> PackedSourcePCK::get_file(const String &p_path, PackedData::Pack
|
|||||||
|
|
||||||
//////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
bool PackedSourceDirectory::try_open_pack(const String &p_path, bool p_replace_files, uint64_t p_offset) {
|
||||||
|
// Load with offset feature only supported for PCK files.
|
||||||
|
ERR_FAIL_COND_V_MSG(p_offset != 0, false, "Invalid PCK data. Note that loading files with a non-zero offset isn't supported with directories.");
|
||||||
|
|
||||||
|
if (p_path != "res://") {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
add_directory(p_path, p_replace_files);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ref<FileAccess> PackedSourceDirectory::get_file(const String &p_path, PackedData::PackedFile *p_file) {
|
||||||
|
Ref<FileAccess> ret = FileAccess::create_for_path(p_path);
|
||||||
|
ret->reopen(p_path, FileAccess::READ);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PackedSourceDirectory::add_directory(const String &p_path, bool p_replace_files) {
|
||||||
|
Ref<DirAccess> da = DirAccess::open(p_path);
|
||||||
|
if (da.is_null()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
da->set_include_hidden(true);
|
||||||
|
|
||||||
|
for (const String &file_name : da->get_files()) {
|
||||||
|
String file_path = p_path.path_join(file_name);
|
||||||
|
uint8_t md5[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||||
|
PackedData::get_singleton()->add_path(p_path, file_path, 0, 0, md5, this, p_replace_files, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const String &sub_dir_name : da->get_directories()) {
|
||||||
|
String sub_dir_path = p_path.path_join(sub_dir_name);
|
||||||
|
add_directory(sub_dir_path, p_replace_files);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
Error FileAccessPack::open_internal(const String &p_path, int p_mode_flags) {
|
Error FileAccessPack::open_internal(const String &p_path, int p_mode_flags) {
|
||||||
ERR_PRINT("Can't open pack-referenced file.");
|
ERR_PRINT("Can't open pack-referenced file.");
|
||||||
return ERR_UNAVAILABLE;
|
return ERR_UNAVAILABLE;
|
||||||
|
|||||||
@@ -147,6 +147,14 @@ public:
|
|||||||
virtual Ref<FileAccess> get_file(const String &p_path, PackedData::PackedFile *p_file) override;
|
virtual Ref<FileAccess> get_file(const String &p_path, PackedData::PackedFile *p_file) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class PackedSourceDirectory : public PackSource {
|
||||||
|
void add_directory(const String &p_path, bool p_replace_files);
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual bool try_open_pack(const String &p_path, bool p_replace_files, uint64_t p_offset) override;
|
||||||
|
virtual Ref<FileAccess> get_file(const String &p_path, PackedData::PackedFile *p_file) override;
|
||||||
|
};
|
||||||
|
|
||||||
class FileAccessPack : public FileAccess {
|
class FileAccessPack : public FileAccess {
|
||||||
PackedData::PackedFile pf;
|
PackedData::PackedFile pf;
|
||||||
|
|
||||||
|
|||||||
@@ -151,6 +151,7 @@
|
|||||||
Loads the contents of the .pck or .zip file specified by [param pack] into the resource filesystem ([code]res://[/code]). Returns [code]true[/code] on success.
|
Loads the contents of the .pck or .zip file specified by [param pack] into the resource filesystem ([code]res://[/code]). Returns [code]true[/code] on success.
|
||||||
[b]Note:[/b] If a file from [param pack] shares the same path as a file already in the resource filesystem, any attempts to load that file will use the file from [param pack] unless [param replace_files] is set to [code]false[/code].
|
[b]Note:[/b] If a file from [param pack] shares the same path as a file already in the resource filesystem, any attempts to load that file will use the file from [param pack] unless [param replace_files] is set to [code]false[/code].
|
||||||
[b]Note:[/b] The optional [param offset] parameter can be used to specify the offset in bytes to the start of the resource pack. This is only supported for .pck files.
|
[b]Note:[/b] The optional [param offset] parameter can be used to specify the offset in bytes to the start of the resource pack. This is only supported for .pck files.
|
||||||
|
[b]Note:[/b] [DirAccess] will not show changes made to the contents of [code]res://[/code] after calling this function.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="localize_path" qualifiers="const">
|
<method name="localize_path" qualifiers="const">
|
||||||
|
|||||||
Reference in New Issue
Block a user