|
5 | 5 | using AssetRipper.GUI.Extensions; |
6 | 6 | using AssetRipper.GUI.Managers; |
7 | 7 | using AssetRipper.Import.Logging; |
| 8 | +using AssetRipper.SourceGenerated.NativeEnums.Images.Crunch; |
8 | 9 | using Avalonia.Input; |
9 | 10 | using Avalonia.Platform.Storage; |
10 | 11 | using Avalonia.Threading; |
11 | 12 | using System.Collections.ObjectModel; |
12 | 13 | using System.Diagnostics; |
13 | 14 | using System.IO.Compression; |
| 15 | +using System.Text.Json.Nodes; |
14 | 16 |
|
15 | 17 | namespace AssetRipper.GUI |
16 | 18 | { |
@@ -170,17 +172,106 @@ public void OnFileDropped(DragEventArgs e) |
170 | 172 |
|
171 | 173 | string[]? filesDropped = e.Data.GetFileNames()?.ToArray(); |
172 | 174 |
|
| 175 | + if (filesDropped != null && filesDropped.Length == 1 && Path.GetExtension(filesDropped[0]) == ".xapk") |
| 176 | + { |
| 177 | + Logger.Log(LogType.Info, LogCategory.Import, $"Detected XAPK file. (file drop)'"); |
| 178 | + DoLoadXAPK(filesDropped); |
| 179 | + return; |
| 180 | + } |
| 181 | + |
173 | 182 | DoLoad(filesDropped); |
174 | 183 | } |
175 | 184 |
|
176 | | - private void DoLoadArchives(string[]? filesDropped) |
| 185 | + private void DoLoadXAPK(string[]? files) |
177 | 186 | { |
178 | | - if (filesDropped == null || filesDropped.Length < 1) |
| 187 | + if (files.Length < 1) return; |
| 188 | + |
| 189 | + _ = Task.Run(() => |
179 | 190 | { |
180 | | - return; |
181 | | - } |
| 191 | + string xapkExtractPath = "temp/XAPK_EXTRACT_" + DateTime.Now.ToString("yyyyMMddHHmm"); |
| 192 | + Directory.CreateDirectory(xapkExtractPath); |
| 193 | + |
| 194 | + try |
| 195 | + { |
| 196 | + Logger.Log(LogType.Info, LogCategory.Import, $"Decompressing '{files[0]}'"); |
| 197 | + |
| 198 | + if (!File.Exists(files[0])) |
| 199 | + { |
| 200 | + Logger.Log(LogType.Error, LogCategory.Import, $"File '{files[0]}' does not exist."); |
| 201 | + throw new Exception($"File '{files[0]}' does not exist. Have you tried importing multiple folders?"); |
| 202 | + } |
| 203 | + |
| 204 | + LoadingText = "Decompressing " + files[0]; |
| 205 | + |
| 206 | + ZipFile.ExtractToDirectory(files[0], xapkExtractPath, true); |
| 207 | + |
| 208 | + string manifestPath = Path.Combine(xapkExtractPath, "manifest.json"); |
| 209 | + |
| 210 | + if (!File.Exists(manifestPath)) |
| 211 | + { |
| 212 | + throw new FileNotFoundException($"unable to find XAPK's manifest file at path: '{manifestPath}'"); |
| 213 | + } |
| 214 | + |
| 215 | + JsonNode? index = JsonNode.Parse(File.ReadAllText(manifestPath)) ?? throw new Exception("Unable to parse the manifest JSON."); |
| 216 | + JsonNode? xapkVersion = index["xapk_version"]; |
| 217 | + |
| 218 | + if (xapkVersion == null) |
| 219 | + { |
| 220 | + Logger.Log(LogType.Warning, LogCategory.Import, "Unable to locate XAPK version in the manifest"); |
| 221 | + } |
| 222 | + else if (xapkVersion.GetValue<int>() != 1) |
| 223 | + { |
| 224 | + Logger.Log(LogType.Warning, LogCategory.Import, $"XAPK version is not {xapkVersion} which is not supported."); |
| 225 | + } |
| 226 | + |
| 227 | + List<string> filesToExtract = []; |
| 228 | + |
| 229 | + JsonNode? packageName = index["package_name"] ?? throw new Exception("Package name cannot be found."); |
| 230 | + |
| 231 | + filesToExtract.Add(Path.Combine(xapkExtractPath, $"{packageName}.apk")); |
| 232 | + |
| 233 | + JsonNode? expansions = index["expansions"]; |
| 234 | + |
| 235 | + if (expansions == null) |
| 236 | + { |
| 237 | + Logger.Log(LogType.Warning, LogCategory.Import, "Unable to locate expansions in the manifest"); |
| 238 | + } |
| 239 | + else |
| 240 | + { |
| 241 | + foreach (JsonNode? v in expansions.AsArray()) |
| 242 | + { |
| 243 | + if (v == null) |
| 244 | + { |
| 245 | + Logger.Log(LogType.Warning, LogCategory.Import, "An entry in expansions is null."); |
| 246 | + continue; |
| 247 | + } |
| 248 | + |
| 249 | + JsonNode? file = v["file"]; |
| 250 | + if (file == null) |
| 251 | + { |
| 252 | + Logger.Log(LogType.Warning, LogCategory.Import, "An entry in expansions doesnt have file node or its null."); |
| 253 | + continue; |
| 254 | + } |
| 255 | + Logger.Log(LogType.Info, LogCategory.Import, $"found expansion file: '{file}'"); |
| 256 | + filesToExtract.Add(Path.Combine(xapkExtractPath, file.ToString())); |
| 257 | + } |
| 258 | + } |
| 259 | + |
| 260 | + DoLoad([.. filesToExtract]); |
| 261 | + } |
| 262 | + catch (Exception ex) |
| 263 | + { |
| 264 | + LoadingText = string.Empty; |
| 265 | + this.ShowPopup($"Exception on importing XAPK: {ex.Message}", MainWindow.Instance.LocalizationManager["error"]); |
| 266 | + } |
| 267 | + }); |
| 268 | + } |
| 269 | + |
| 270 | + private void DoLoadArchives(string[]? filesDropped) |
| 271 | + { |
| 272 | + if (filesDropped == null || filesDropped.Length < 1) return; |
182 | 273 |
|
183 | | - new Thread(() => |
| 274 | + _ = Task.Run(() => |
184 | 275 | { |
185 | 276 | string path = "temp/ZIP_COMBINE_" + DateTime.Now.ToString("yyyyMMddHHmm"); |
186 | 277 |
|
@@ -208,11 +299,7 @@ private void DoLoadArchives(string[]? filesDropped) |
208 | 299 | LoadingText = string.Empty; |
209 | 300 | this.ShowPopup($"Exception on combining archives: {ex.Message}", MainWindow.Instance.LocalizationManager["error"]); |
210 | 301 | } |
211 | | - }) |
212 | | - { |
213 | | - IsBackground = true, |
214 | | - Name = "Background Decompressing Thread" |
215 | | - }.Start(); |
| 302 | + }); |
216 | 303 | } |
217 | 304 |
|
218 | 305 | private void DoLoad(string[]? filesDropped) |
@@ -464,53 +551,7 @@ public async void ShowOpenFileDialogXAPK() |
464 | 551 | .Where(s => !string.IsNullOrEmpty(s)) |
465 | 552 | .ToArray(); |
466 | 553 |
|
467 | | - if (result.Length < 1) return; |
468 | | - |
469 | | - _ = Task.Run(() => |
470 | | - { |
471 | | - string xapkExtractPath = "temp/XAPK_" + DateTime.Now.ToString("yyyyMMddHHmm"); |
472 | | - Directory.CreateDirectory(xapkExtractPath); |
473 | | - |
474 | | - try |
475 | | - { |
476 | | - Logger.Log(LogType.Info, LogCategory.Import, $"Decompressing '{result[0]}'"); |
477 | | - |
478 | | - if (!File.Exists(result[0])) |
479 | | - { |
480 | | - Logger.Log(LogType.Error, LogCategory.Import, $"File '{result[0]}' does not exist."); |
481 | | - throw new Exception($"File '{result[0]}' does not exist. Have you tried importing multiple folders?"); |
482 | | - } |
483 | | - |
484 | | - LoadingText = "Decompressing " + result[0]; |
485 | | - |
486 | | - ZipFile.ExtractToDirectory(result[0], xapkExtractPath, true); |
487 | | - |
488 | | - // Post Extract |
489 | | - if (!Directory.Exists(Path.Combine(xapkExtractPath, "Android/obb"))) |
490 | | - throw new Exception("Unable to find Android/obb directory"); |
491 | | - |
492 | | - string? packageName = Path.GetFileName(Directory.GetDirectories(Path.Combine(xapkExtractPath, "Android/obb"))[0]); |
493 | | - |
494 | | - if (packageName == null) throw new Exception("Package name is null"); |
495 | | - Logger.Log(LogType.Info, LogCategory.Import, packageName); |
496 | | - |
497 | | - string obbFile = Directory.GetFiles(Path.Combine(xapkExtractPath, "Android/obb", packageName))[0]; |
498 | | - |
499 | | - string xapkPostExtractPath = "temp/XAPK_POST_" + DateTime.Now.ToString("yyyyMMddHHmm"); |
500 | | - Directory.CreateDirectory(xapkPostExtractPath); |
501 | | - |
502 | | - ZipFile.ExtractToDirectory(obbFile, xapkPostExtractPath, true); |
503 | | - |
504 | | - ZipFile.ExtractToDirectory(Path.Combine(xapkExtractPath, packageName + ".apk"), xapkPostExtractPath, true); |
505 | | - |
506 | | - DoLoad([xapkPostExtractPath]); |
507 | | - } |
508 | | - catch (Exception ex) |
509 | | - { |
510 | | - LoadingText = string.Empty; |
511 | | - this.ShowPopup($"Exception on importing XAPK: {ex.Message}", MainWindow.Instance.LocalizationManager["error"]); |
512 | | - } |
513 | | - }); |
| 554 | + DoLoadXAPK(result); |
514 | 555 | } |
515 | 556 |
|
516 | 557 | //Called from UI |
|
0 commit comments