From 677f0eafd054dc4e8aea018d0271294568c02369 Mon Sep 17 00:00:00 2001 From: nikitalita <69168929+nikitalita@users.noreply.github.com> Date: Wed, 6 Nov 2024 17:49:02 -0600 Subject: [PATCH] straighten out path finding --- utility/file_access_gdre.cpp | 88 +++++++++++++++++++++--------------- utility/file_access_gdre.h | 10 ++-- utility/gdre_settings.cpp | 4 +- 3 files changed, 60 insertions(+), 42 deletions(-) diff --git a/utility/file_access_gdre.cpp b/utility/file_access_gdre.cpp index 3bed7a621..011219a63 100644 --- a/utility/file_access_gdre.cpp +++ b/utility/file_access_gdre.cpp @@ -38,10 +38,6 @@ Vector> GDREPackedData::get_file_info_list(const Vector GDREPackedData::try_open_path(const String &p_path) { - PathMD5 pmd5(p_path.md5_buffer()); + String simplified_path = p_path.simplify_path(); + PathMD5 pmd5(simplified_path.md5_buffer()); HashMap::Iterator E = files.find(pmd5); - if (!E || E->value.offset == 0) { - if (is_gdre_file(p_path)) { - WARN_PRINT("Attempted to load a GDRE resource while another pack is loaded..."); - if (PackedData::get_singleton()) { - // This works even when PackedData is disabled - return PackedData::get_singleton()->try_open_path(p_path); - } - } - return Ref(); + if (!E) { + return nullptr; //not found + } + if (E->value.offset == 0) { + return nullptr; //was erased } + return E->value.src->get_file(p_path, &E->value); } bool GDREPackedData::has_path(const String &p_path) { - bool ret = files.has(PathMD5(p_path.md5_buffer())); - if (!ret) { - // We return true if the path is a GDRE resource to ensure that this will be used to load it - if (is_gdre_file(p_path)) { - WARN_PRINT("Attempted to check for existence of GDRE resource while another pack is loaded..."); - if (PackedData::get_singleton()) { - // This works even when PackedData is disabled - return PackedData::get_singleton()->has_path(p_path); - } - } - } - return ret; + return files.has(PathMD5(p_path.simplify_path().md5_buffer())); } + Ref GDREPackedData::try_open_directory(const String &p_path) { Ref da = memnew(DirAccessGDRE()); if (da->change_dir(p_path) != OK) { @@ -232,13 +216,17 @@ Error FileAccessGDRE::open_internal(const String &p_path, int p_mode_flags) { if (!(p_mode_flags & WRITE) && GDREPackedData::get_singleton() && !GDREPackedData::get_singleton()->is_disabled()) { proxy = GDREPackedData::get_singleton()->try_open_path(p_path); if (proxy.is_valid()) { + if (is_gdre_file(p_path)) { + WARN_PRINT(vformat("Opening gdre file %s from a loaded external pack???? PLEASE REPORT THIS!!!!", p_path)); + }; return OK; } } String path = p_path; - if (is_gdre_file(p_path)) { - WARN_PRINT("Attempted to open a gdre file while we have a pack loaded..."); - if (GDREPackedData::real_packed_data_has_pack_loaded() && !PackedData::get_singleton()->is_disabled()) { + if (!(p_mode_flags & WRITE) && is_gdre_file(p_path)) { + WARN_PRINT(vformat("Attempted to open a gdre file %s while we have a pack loaded...", p_path)); + if (PathFinder::real_packed_data_has_path(p_path)) { + // this works even when PackedData is disabled proxy = PackedData::get_singleton()->try_open_path(p_path); if (proxy.is_valid()) { return OK; @@ -246,7 +234,7 @@ Error FileAccessGDRE::open_internal(const String &p_path, int p_mode_flags) { } } // Otherwise, it's on the file system. - path = PathFinder::_fix_path_file_access(p_path); + path = PathFinder::_fix_path_file_access(p_path, p_mode_flags); Error err; proxy = _open_filesystem(path, p_mode_flags, &err); if (err != OK) { @@ -323,12 +311,17 @@ void FileAccessGDRE::store_buffer(const uint8_t *p_src, uint64_t p_length) { } bool FileAccessGDRE::file_exists(const String &p_name) { - if (GDREPackedData::get_singleton() && !GDREPackedData::get_singleton()->is_disabled() && GDREPackedData::get_singleton()->has_path(p_name)) { + if (PathFinder::gdre_packed_data_valid_path(p_name)) { return true; } if (proxy.is_valid()) { return proxy->file_exists(p_name); } + // TODO: I don't think this is necessary and may screw things up; revisit this + // After proxy, check if it's in the real packed data + // if (PathFinder::real_packed_data_has_path(p_name)) { + // return true; + // } return false; } @@ -804,10 +797,28 @@ Ref FileAccessGDRE::_open_filesystem(const String &p_path, int p_mod return file_proxy; } -String PathFinder::_fix_path_file_access(const String &p_path) { +bool PathFinder::real_packed_data_has_path(const String &p_path, bool check_disabled) { + return PackedData::get_singleton() && (!check_disabled || !PackedData::get_singleton()->is_disabled()) && PackedData::get_singleton()->has_path(p_path); +} + +bool PathFinder::gdre_packed_data_valid_path(const String &p_path) { + return GDREPackedData::get_singleton() && !GDREPackedData::get_singleton()->is_disabled() && GDREPackedData::get_singleton()->has_path(p_path); +} + +String PathFinder::_fix_path_file_access(const String &p_path, int p_mode_flags) { if (p_path.begins_with("res://")) { - if (p_path.get_file().begins_with("gdre_")) { + if (is_gdre_file(p_path)) { WARN_PRINT("WARNING: Calling fix_path on a gdre file..."); + if (!(p_mode_flags & FileAccess::WRITE)) { + if (gdre_packed_data_valid_path(p_path)) { + WARN_PRINT("WARNING: fix_path: gdre file is in a loaded external pack???? PLEASE REPORT THIS!!!!"); + return p_path.replace_first("res://", ""); + }; + // PackedData is disabled if an external pack is loaded, so we don't check if it's disabled here + if (real_packed_data_has_path(p_path)) { + return p_path.replace_first("res://", ""); + } + } String res_path = GDRESettings::get_singleton()->get_gdre_resource_path(); if (res_path != "") { return p_path.replace("res:/", res_path); @@ -820,12 +831,17 @@ String PathFinder::_fix_path_file_access(const String &p_path) { return p_path.replace_first("res://", ""); } else if (p_path.begins_with("user://")) { // Some packs have user files in them, so we need to check for those if (p_path.get_file().begins_with("gdre_")) { - WARN_PRINT("WARNING: Calling fix_path on a gdre file..."); - // TODO: Once we start adding user files, we'll have to handle this; for right now, it doesn't particularly matter + WARN_PRINT(vformat("WARNING: Calling fix_path on a gdre file %s...", p_path)); + if (!(p_mode_flags & FileAccess::WRITE)) { + if (gdre_packed_data_valid_path(p_path)) { + WARN_PRINT(vformat("WARNING: fix_path: gdre file %s is in a loaded external pack???? PLEASE REPORT THIS!!!!", p_path)); + return p_path.replace_first("user://", ""); + }; + } } // check if the file is in the PackedData first - if (GDREPackedData::get_singleton() && !GDREPackedData::get_singleton()->is_disabled() && GDREPackedData::get_singleton()->has_path(p_path)) { + if (!(p_mode_flags & FileAccess::WRITE) && gdre_packed_data_valid_path(p_path)) { return p_path.replace_first("user://", ""); } String data_dir = OS::get_singleton()->get_user_data_dir(); diff --git a/utility/file_access_gdre.h b/utility/file_access_gdre.h index 81641a80d..6e48ca5ad 100644 --- a/utility/file_access_gdre.h +++ b/utility/file_access_gdre.h @@ -60,8 +60,6 @@ class GDREPackedData { void add_pack_source(PackSource *p_source); void add_path(const String &p_pkg_path, const String &p_path, uint64_t p_ofs, uint64_t p_size, const uint8_t *p_md5, PackSource *p_src, bool p_replace_files, bool p_encrypted = false, bool p_pck_src = false); // for PackSource - bool has_mapped_file(const String &p_path); - void clear(); void set_disabled(bool p_disabled); _FORCE_INLINE_ bool is_disabled() const; @@ -180,19 +178,23 @@ class DirAccessGDRE : public DirAccess { class PathFinder { public: + static bool real_packed_data_has_path(const String &p_path, bool check_disabled = false); static bool gdre_packed_data_valid_path(const String &p_path); - static String _fix_path_file_access(const String &p_path); + static String _fix_path_file_access(const String &p_path, int p_mode_flags = 0); }; template class FileAccessProxy : public T { static_assert(std::is_base_of::value, "T must derive from FileAccess"); + int mode_flags; + public: virtual String fix_path(const String &p_path) const override { - return PathFinder::_fix_path_file_access(p_path.replace("\\", "/")); + return PathFinder::_fix_path_file_access(p_path.replace("\\", "/"), mode_flags); } virtual Error open_internal(const String &p_path, int p_mode_flags) override { + mode_flags = p_mode_flags; return T::open_internal(p_path, p_mode_flags); } }; diff --git a/utility/gdre_settings.cpp b/utility/gdre_settings.cpp index 59cbfea67..40b7fa87e 100644 --- a/utility/gdre_settings.cpp +++ b/utility/gdre_settings.cpp @@ -1320,7 +1320,7 @@ Array GDRESettings::get_import_files(bool copy) { } bool GDRESettings::has_file(const String &p_path) { - return GDREPackedData::get_singleton()->has_mapped_file(p_path); + return GDREPackedData::get_singleton()->has_path(p_path); } Error GDRESettings::load_pack_uid_cache(bool p_reset) { @@ -1447,7 +1447,7 @@ Error GDRESettings::_load_import_file(const String &p_path, bool should_load_md5 // sound.wav-.smp -> sound.wav-.md5 String md5 = src.get_basename() + ".md5"; while (true) { - if (GDREPackedData::get_singleton()->has_mapped_file(md5)) { + if (GDREPackedData::get_singleton()->has_path(md5)) { break; }