| 123 | } |
| 124 | |
| 125 | void PckDumper::_do_extract(uint32_t i, ExtractToken *tokens) { |
| 126 | auto &file = tokens[i].file; |
| 127 | const auto &dir = output_dir; |
| 128 | Error err = OK; |
| 129 | Ref<FileAccess> pck_f = FileAccess::open(file->get_path(), FileAccess::READ, &err); |
| 130 | if (err || pck_f.is_null()) { |
| 131 | broken_cnt++; |
| 132 | completed_cnt++; |
| 133 | if (err == ERR_UNAUTHORIZED || err == ERR_FILE_CORRUPT) { |
| 134 | tokens[i].err = ERR_UNAUTHORIZED; |
| 135 | } else { |
| 136 | tokens[i].err = ERR_FILE_CANT_OPEN; |
| 137 | } |
| 138 | return; |
| 139 | } |
| 140 | String path = tokens[i].path_to_extract; |
| 141 | if (path.begins_with("user://")) { |
| 142 | path = path.replace_first("user://", ".user/"); |
| 143 | } |
| 144 | String target_name = dir.path_join(path.trim_prefix("res://")); |
| 145 | err = gdre::ensure_dir(target_name.get_base_dir()); |
| 146 | if (err != OK) { |
| 147 | broken_cnt++; |
| 148 | completed_cnt++; |
| 149 | tokens[i].err = ERR_CANT_CREATE; |
| 150 | return; |
| 151 | } |
| 152 | Ref<FileAccess> fa = FileAccess::open(target_name, FileAccess::WRITE, &err); |
| 153 | if (err || fa.is_null()) { |
| 154 | broken_cnt++; |
| 155 | completed_cnt++; |
| 156 | tokens[i].err = ERR_FILE_CANT_WRITE; |
| 157 | return; |
| 158 | } |
| 159 | |
| 160 | int64_t rq_size = file->get_size(); |
| 161 | uint8_t buf[16384]; |
| 162 | while (rq_size > 0) { |
| 163 | int got = pck_f->get_buffer(buf, MIN(16384, rq_size)); |
| 164 | fa->store_buffer(buf, got); |
| 165 | rq_size -= 16384; |
| 166 | } |
| 167 | fa->flush(); |
| 168 | completed_cnt++; |
| 169 | if (file->is_malformed() && file->get_raw_path() != file->get_path()) { |
| 170 | print_line("Warning: " + file->get_raw_path() + " is a malformed path!\nSaving to " + file->get_path() + " instead."); |
| 171 | } |
| 172 | print_verbose("Extracted " + target_name); |
| 173 | } |
| 174 | |
| 175 | Error PckDumper::_pck_dump_to_dir( |
| 176 | const String &dir, |
nothing calls this directly
no test coverage detected