@@ -48,7 +48,7 @@ Error PackedData::add_pack(const String &p_path, bool p_replace_files, uint64_t
48
48
}
49
49
50
50
void PackedData::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) {
51
- String simplified_path = p_path.simplify_path ();
51
+ String simplified_path = p_path.simplify_path (). trim_prefix ( " res:// " ) ;
52
52
PathMD5 pmd5 (simplified_path.md5_buffer ());
53
53
54
54
bool exists = files.has (pmd5);
@@ -68,13 +68,11 @@ void PackedData::add_path(const String &p_pkg_path, const String &p_path, uint64
68
68
}
69
69
70
70
if (!exists) {
71
- // search for dir
72
- String p = simplified_path.replace_first (" res://" , " " );
71
+ // Search for directory.
73
72
PackedDir *cd = root;
74
73
75
- if (p.contains (" /" )) { // in a subdir
76
-
77
- Vector<String> ds = p.get_base_dir ().split (" /" );
74
+ if (simplified_path.contains (" /" )) { // In a subdirectory.
75
+ Vector<String> ds = simplified_path.get_base_dir ().split (" /" );
78
76
79
77
for (int j = 0 ; j < ds.size (); j++) {
80
78
if (!cd->subdirs .has (ds[j])) {
@@ -89,29 +87,73 @@ void PackedData::add_path(const String &p_pkg_path, const String &p_path, uint64
89
87
}
90
88
}
91
89
String filename = simplified_path.get_file ();
92
- // Don't add as a file if the path points to a directory
90
+ // Don't add as a file if the path points to a directory.
93
91
if (!filename.is_empty ()) {
94
92
cd->files .insert (filename);
95
93
}
96
94
}
97
95
}
98
96
97
+ void PackedData::remove_path (const String &p_path) {
98
+ String simplified_path = p_path.simplify_path ().trim_prefix (" res://" );
99
+ PathMD5 pmd5 (simplified_path.md5_buffer ());
100
+ if (!files.has (pmd5)) {
101
+ return ;
102
+ }
103
+
104
+ // Search for directory.
105
+ PackedDir *cd = root;
106
+
107
+ if (simplified_path.contains (" /" )) { // In a subdirectory.
108
+ Vector<String> ds = simplified_path.get_base_dir ().split (" /" );
109
+
110
+ for (int j = 0 ; j < ds.size (); j++) {
111
+ if (!cd->subdirs .has (ds[j])) {
112
+ return ; // Subdirectory does not exist, do not bother creating.
113
+ } else {
114
+ cd = cd->subdirs [ds[j]];
115
+ }
116
+ }
117
+ }
118
+
119
+ cd->files .erase (simplified_path.get_file ());
120
+
121
+ files.erase (pmd5);
122
+ }
123
+
99
124
void PackedData::add_pack_source (PackSource *p_source) {
100
125
if (p_source != nullptr ) {
101
126
sources.push_back (p_source);
102
127
}
103
128
}
104
129
105
130
uint8_t *PackedData::get_file_hash (const String &p_path) {
106
- PathMD5 pmd5 (p_path.md5_buffer ());
131
+ String simplified_path = p_path.simplify_path ().trim_prefix (" res://" );
132
+ PathMD5 pmd5 (simplified_path.md5_buffer ());
107
133
HashMap<PathMD5, PackedFile, PathMD5>::Iterator E = files.find (pmd5);
108
- if (!E || E-> value . offset == 0 ) {
134
+ if (!E) {
109
135
return nullptr ;
110
136
}
111
137
112
138
return E->value .md5 ;
113
139
}
114
140
141
+ HashSet<String> PackedData::get_file_paths () const {
142
+ HashSet<String> file_paths;
143
+ _get_file_paths (root, root->name , file_paths);
144
+ return file_paths;
145
+ }
146
+
147
+ void PackedData::_get_file_paths (PackedDir *p_dir, const String &p_parent_dir, HashSet<String> &r_paths) const {
148
+ for (const String &E : p_dir->files ) {
149
+ r_paths.insert (p_parent_dir.path_join (E));
150
+ }
151
+
152
+ for (const KeyValue<String, PackedDir *> &E : p_dir->subdirs ) {
153
+ _get_file_paths (E.value , p_parent_dir.path_join (E.key ), r_paths);
154
+ }
155
+ }
156
+
115
157
void PackedData::clear () {
116
158
files.clear ();
117
159
_free_packed_dirs (root);
@@ -269,13 +311,17 @@ bool PackedSourcePCK::try_open_pack(const String &p_path, bool p_replace_files,
269
311
String path;
270
312
path.parse_utf8 (cs.ptr ());
271
313
272
- uint64_t ofs = file_base + f->get_64 ();
314
+ uint64_t ofs = f->get_64 ();
273
315
uint64_t size = f->get_64 ();
274
316
uint8_t md5[16 ];
275
317
f->get_buffer (md5, 16 );
276
318
uint32_t flags = f->get_32 ();
277
319
278
- PackedData::get_singleton ()->add_path (p_path, path, ofs + p_offset, size, md5, this , p_replace_files, (flags & PACK_FILE_ENCRYPTED));
320
+ if (flags & PACK_FILE_REMOVAL) { // The file was removed.
321
+ PackedData::get_singleton ()->remove_path (path);
322
+ } else {
323
+ PackedData::get_singleton ()->add_path (p_path, path, file_base + ofs + p_offset, size, md5, this , p_replace_files, (flags & PACK_FILE_ENCRYPTED));
324
+ }
279
325
}
280
326
281
327
return true ;
0 commit comments