Skip to content

Commit ebf6ae6

Browse files
committed
XAPK support rewrite
1 parent cfd9ab0 commit ebf6ae6

File tree

1 file changed

+98
-57
lines changed

1 file changed

+98
-57
lines changed

Source/AssetRipper.GUI/MainWindow.ViewModel.cs

Lines changed: 98 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,14 @@
55
using AssetRipper.GUI.Extensions;
66
using AssetRipper.GUI.Managers;
77
using AssetRipper.Import.Logging;
8+
using AssetRipper.SourceGenerated.NativeEnums.Images.Crunch;
89
using Avalonia.Input;
910
using Avalonia.Platform.Storage;
1011
using Avalonia.Threading;
1112
using System.Collections.ObjectModel;
1213
using System.Diagnostics;
1314
using System.IO.Compression;
15+
using System.Text.Json.Nodes;
1416

1517
namespace AssetRipper.GUI
1618
{
@@ -170,17 +172,106 @@ public void OnFileDropped(DragEventArgs e)
170172

171173
string[]? filesDropped = e.Data.GetFileNames()?.ToArray();
172174

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+
173182
DoLoad(filesDropped);
174183
}
175184

176-
private void DoLoadArchives(string[]? filesDropped)
185+
private void DoLoadXAPK(string[]? files)
177186
{
178-
if (filesDropped == null || filesDropped.Length < 1)
187+
if (files.Length < 1) return;
188+
189+
_ = Task.Run(() =>
179190
{
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;
182273

183-
new Thread(() =>
274+
_ = Task.Run(() =>
184275
{
185276
string path = "temp/ZIP_COMBINE_" + DateTime.Now.ToString("yyyyMMddHHmm");
186277

@@ -208,11 +299,7 @@ private void DoLoadArchives(string[]? filesDropped)
208299
LoadingText = string.Empty;
209300
this.ShowPopup($"Exception on combining archives: {ex.Message}", MainWindow.Instance.LocalizationManager["error"]);
210301
}
211-
})
212-
{
213-
IsBackground = true,
214-
Name = "Background Decompressing Thread"
215-
}.Start();
302+
});
216303
}
217304

218305
private void DoLoad(string[]? filesDropped)
@@ -464,53 +551,7 @@ public async void ShowOpenFileDialogXAPK()
464551
.Where(s => !string.IsNullOrEmpty(s))
465552
.ToArray();
466553

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);
514555
}
515556

516557
//Called from UI

0 commit comments

Comments
 (0)