- [Core] Added new entry.
- [Core] Fix bug with `Keys.json` reading. (#8) - [Core] Improve file fetching.
This commit is contained in:
@@ -110,16 +110,29 @@ namespace AssetStudio
|
|||||||
|
|
||||||
private static IEnumerable<string> LoadFiles(string[] files)
|
private static IEnumerable<string> LoadFiles(string[] files)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < files.Length; i++)
|
string msg;
|
||||||
|
|
||||||
|
var path = Path.GetDirectoryName(Path.GetFullPath(files[0]));
|
||||||
|
ImportHelper.MergeSplitAssets(path);
|
||||||
|
var toReadFile = ImportHelper.ProcessingSplitFiles(files.ToList());
|
||||||
|
|
||||||
|
var filesList = new List<string>(toReadFile);
|
||||||
|
for (int i = 0; i < filesList.Count; i++)
|
||||||
{
|
{
|
||||||
var file = files[i];
|
var file = filesList[i];
|
||||||
assetsManager.LoadFiles(file);
|
assetsManager.LoadFiles(file);
|
||||||
if (assetsManager.assetsFileList.Count > 0)
|
if (assetsManager.assetsFileList.Count > 0)
|
||||||
{
|
{
|
||||||
yield return file;
|
yield return file;
|
||||||
Logger.Info($"[{i + 1}/{files.Length}] Processed {Path.GetFileName(file)}");
|
msg = $"Processed {Path.GetFileName(file)}";
|
||||||
Progress.Report(i + 1, files.Length);
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
filesList.Remove(file);
|
||||||
|
msg = $"Removed {Path.GetFileName(file)}, no assets found";
|
||||||
|
}
|
||||||
|
Logger.Info($"[{i + 1}/{filesList.Count}] {msg}");
|
||||||
|
Progress.Report(i + 1, filesList.Count);
|
||||||
assetsManager.Clear();
|
assetsManager.Clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,23 @@ namespace AssetStudio
|
|||||||
internal HashSet<string> noexistFiles = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
internal HashSet<string> noexistFiles = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||||
internal HashSet<string> assetsFileListHash = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
internal HashSet<string> assetsFileListHash = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
|
||||||
|
public void LoadFiles(string file)
|
||||||
|
{
|
||||||
|
if (Silent)
|
||||||
|
{
|
||||||
|
Logger.Silent = true;
|
||||||
|
Progress.Silent = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Load(new string[] { file });
|
||||||
|
|
||||||
|
if (Silent)
|
||||||
|
{
|
||||||
|
Logger.Silent = false;
|
||||||
|
Progress.Silent = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void LoadFiles(params string[] files)
|
public void LoadFiles(params string[] files)
|
||||||
{
|
{
|
||||||
if (Silent)
|
if (Silent)
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ namespace AssetStudio
|
|||||||
Games.Add(index++, new Game(GameType.HelixWaltz2));
|
Games.Add(index++, new Game(GameType.HelixWaltz2));
|
||||||
Games.Add(index++, new Game(GameType.NetEase));
|
Games.Add(index++, new Game(GameType.NetEase));
|
||||||
Games.Add(index++, new Game(GameType.AnchorPanic));
|
Games.Add(index++, new Game(GameType.AnchorPanic));
|
||||||
|
Games.Add(index++, new Game(GameType.DreamscapeAlbireo));
|
||||||
}
|
}
|
||||||
public static Game GetGame(GameType gameType) => GetGame((int)gameType);
|
public static Game GetGame(GameType gameType) => GetGame((int)gameType);
|
||||||
public static Game GetGame(int index)
|
public static Game GetGame(int index)
|
||||||
@@ -138,7 +139,8 @@ namespace AssetStudio
|
|||||||
ShiningNikki,
|
ShiningNikki,
|
||||||
HelixWaltz2,
|
HelixWaltz2,
|
||||||
NetEase,
|
NetEase,
|
||||||
AnchorPanic
|
AnchorPanic,
|
||||||
|
DreamscapeAlbireo
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class GameTypes
|
public static class GameTypes
|
||||||
|
|||||||
@@ -530,5 +530,66 @@ namespace AssetStudio
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static FileReader DecryptDreamscapeAlbireo(FileReader reader)
|
||||||
|
{
|
||||||
|
var key = new byte[] { 0x1E, 0x1E, 0x01, 0x01, 0xFC };
|
||||||
|
|
||||||
|
var signature = reader.ReadStringToNull(4);
|
||||||
|
if (signature != "MJJ")
|
||||||
|
{
|
||||||
|
reader.Position = 0;
|
||||||
|
return reader;
|
||||||
|
}
|
||||||
|
|
||||||
|
reader.Endian = EndianType.BigEndian;
|
||||||
|
|
||||||
|
var u1 = reader.ReadUInt32();
|
||||||
|
var u2 = reader.ReadUInt32();
|
||||||
|
var u3 = reader.ReadUInt32();
|
||||||
|
var u4 = reader.ReadUInt32();
|
||||||
|
var u5 = reader.ReadUInt32();
|
||||||
|
var u6 = reader.ReadUInt32();
|
||||||
|
|
||||||
|
var flag = Scrample(u4) ^ 0x70020017;
|
||||||
|
var compressedBlocksInfoSize = Scrample(u1) ^ u4;
|
||||||
|
var uncompressedBlocksInfoSize = Scrample(u6) ^ u1;
|
||||||
|
|
||||||
|
var sizeHigh = (u5 & 0xFFFFFF00 | u2 >> 24) ^ u4;
|
||||||
|
var sizeLow = (u5 >> 24 | (u2 << 8)) ^ u1;
|
||||||
|
var size = (long)(sizeHigh << 32 | sizeLow);
|
||||||
|
|
||||||
|
var blocksInfo = reader.ReadBytes((int)compressedBlocksInfoSize);
|
||||||
|
for(int i = 0; i < blocksInfo.Length; i++)
|
||||||
|
{
|
||||||
|
blocksInfo[i] ^= key[i % key.Length];
|
||||||
|
}
|
||||||
|
|
||||||
|
var data = reader.ReadBytes((int)reader.Remaining);
|
||||||
|
|
||||||
|
var buffer = (stackalloc byte[8]);
|
||||||
|
MemoryStream ms = new();
|
||||||
|
ms.Write(Encoding.UTF8.GetBytes("UnityFS\x00"));
|
||||||
|
BinaryPrimitives.WriteUInt32BigEndian(buffer, 6);
|
||||||
|
ms.Write(buffer[..4]);
|
||||||
|
ms.Write(Encoding.UTF8.GetBytes("5.x.x\x00"));
|
||||||
|
ms.Write(Encoding.UTF8.GetBytes("2018.4.2f1\x00"));
|
||||||
|
BinaryPrimitives.WriteInt64BigEndian(buffer, size);
|
||||||
|
ms.Write(buffer);
|
||||||
|
BinaryPrimitives.WriteUInt32BigEndian(buffer, compressedBlocksInfoSize);
|
||||||
|
ms.Write(buffer[..4]);
|
||||||
|
BinaryPrimitives.WriteUInt32BigEndian(buffer, uncompressedBlocksInfoSize);
|
||||||
|
ms.Write(buffer[..4]);
|
||||||
|
BinaryPrimitives.WriteUInt32BigEndian(buffer, flag);
|
||||||
|
ms.Write(buffer[..4]);
|
||||||
|
ms.Write(blocksInfo);
|
||||||
|
ms.Write(data);
|
||||||
|
reader.BaseStream.CopyTo(ms);
|
||||||
|
ms.Position = 0;
|
||||||
|
|
||||||
|
return new FileReader(reader.FullPath, ms);
|
||||||
|
|
||||||
|
static uint Scrample(uint value) => (value >> 5) & 0xFFE000 | (value >> 29) | (value << 14) & 0xFF000000 | (8 * value) & 0x1FF8;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ namespace AssetStudio
|
|||||||
|
|
||||||
static UnityCNManager()
|
static UnityCNManager()
|
||||||
{
|
{
|
||||||
var str = File.ReadAllText(KeysFileName);
|
var str = File.ReadAllText(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, KeysFileName));
|
||||||
Entries = JsonConvert.DeserializeObject<List<UnityCN.Entry>>(str);
|
Entries = JsonConvert.DeserializeObject<List<UnityCN.Entry>>(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -24,7 +24,7 @@ namespace AssetStudio
|
|||||||
Entries.AddRange(entries);
|
Entries.AddRange(entries);
|
||||||
|
|
||||||
var str = JsonConvert.SerializeObject(Entries);
|
var str = JsonConvert.SerializeObject(Entries);
|
||||||
File.WriteAllText(KeysFileName, str);
|
File.WriteAllText(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, KeysFileName), str);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void SetKey(int index)
|
public static void SetKey(int index)
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
@@ -65,7 +66,6 @@ namespace AssetStudioCLI
|
|||||||
|
|
||||||
Logger.Info("Scanning for files...");
|
Logger.Info("Scanning for files...");
|
||||||
var files = o.Input.Attributes.HasFlag(FileAttributes.Directory) ? Directory.GetFiles(o.Input.FullName, "*.*", SearchOption.AllDirectories).OrderBy(x => x.Length).ToArray() : new string[] { o.Input.FullName };
|
var files = o.Input.Attributes.HasFlag(FileAttributes.Directory) ? Directory.GetFiles(o.Input.FullName, "*.*", SearchOption.AllDirectories).OrderBy(x => x.Length).ToArray() : new string[] { o.Input.FullName };
|
||||||
files = files.Where(x => FileReader.IsReadable(x, game)).ToArray();
|
|
||||||
Logger.Info($"Found {files.Length} files");
|
Logger.Info($"Found {files.Length} files");
|
||||||
|
|
||||||
if (o.MapOp.HasFlag(MapOpType.CABMap))
|
if (o.MapOp.HasFlag(MapOpType.CABMap))
|
||||||
@@ -100,7 +100,13 @@ namespace AssetStudioCLI
|
|||||||
if (o.MapOp.Equals(MapOpType.None) || o.MapOp.HasFlag(MapOpType.Load))
|
if (o.MapOp.Equals(MapOpType.None) || o.MapOp.HasFlag(MapOpType.Load))
|
||||||
{
|
{
|
||||||
var i = 0;
|
var i = 0;
|
||||||
foreach (var file in files)
|
|
||||||
|
var path = Path.GetDirectoryName(Path.GetFullPath(files[0]));
|
||||||
|
ImportHelper.MergeSplitAssets(path);
|
||||||
|
var toReadFile = ImportHelper.ProcessingSplitFiles(files.ToList());
|
||||||
|
|
||||||
|
var fileList = new List<string>(toReadFile);
|
||||||
|
foreach (var file in fileList)
|
||||||
{
|
{
|
||||||
assetsManager.LoadFiles(file);
|
assetsManager.LoadFiles(file);
|
||||||
if (assetsManager.assetsFileList.Count > 0)
|
if (assetsManager.assetsFileList.Count > 0)
|
||||||
|
|||||||
@@ -2084,7 +2084,6 @@ namespace AssetStudioGUI
|
|||||||
{
|
{
|
||||||
Logger.Info("Scanning for files...");
|
Logger.Info("Scanning for files...");
|
||||||
var files = Directory.GetFiles(openFolderDialog.Folder, "*.*", SearchOption.AllDirectories).ToArray();
|
var files = Directory.GetFiles(openFolderDialog.Folder, "*.*", SearchOption.AllDirectories).ToArray();
|
||||||
files = files.Where(x => FileReader.IsReadable(x, Studio.Game)).ToArray();
|
|
||||||
Logger.Info($"Found {files.Length} files");
|
Logger.Info($"Found {files.Length} files");
|
||||||
await Task.Run(() => AssetsHelper.BuildCABMap(files, name, openFolderDialog.Folder, Studio.Game));
|
await Task.Run(() => AssetsHelper.BuildCABMap(files, name, openFolderDialog.Folder, Studio.Game));
|
||||||
}
|
}
|
||||||
@@ -2137,6 +2136,10 @@ namespace AssetStudioGUI
|
|||||||
openFolderDialog.Title = "Select Game Folder";
|
openFolderDialog.Title = "Select Game Folder";
|
||||||
if (openFolderDialog.ShowDialog(this) == DialogResult.OK)
|
if (openFolderDialog.ShowDialog(this) == DialogResult.OK)
|
||||||
{
|
{
|
||||||
|
Logger.Info("Scanning for files...");
|
||||||
|
var files = Directory.GetFiles(openFolderDialog.Folder, "*.*", SearchOption.AllDirectories).ToArray();
|
||||||
|
Logger.Info($"Found {files.Length} files");
|
||||||
|
|
||||||
var saveFolderDialog = new OpenFolderDialog();
|
var saveFolderDialog = new OpenFolderDialog();
|
||||||
saveFolderDialog.InitialFolder = saveDirectoryBackup;
|
saveFolderDialog.InitialFolder = saveDirectoryBackup;
|
||||||
saveFolderDialog.Title = "Select Output Folder";
|
saveFolderDialog.Title = "Select Output Folder";
|
||||||
@@ -2152,10 +2155,6 @@ namespace AssetStudioGUI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
saveDirectoryBackup = saveFolderDialog.Folder;
|
saveDirectoryBackup = saveFolderDialog.Folder;
|
||||||
Logger.Info("Scanning for files...");
|
|
||||||
var files = Directory.GetFiles(openFolderDialog.Folder, "*.*", SearchOption.AllDirectories).ToArray();
|
|
||||||
files = files.Where(x => FileReader.IsReadable(x, Studio.Game)).ToArray();
|
|
||||||
Logger.Info($"Found {files.Length} files");
|
|
||||||
await Task.Run(() => AssetsHelper.BuildBoth(files, name, openFolderDialog.Folder, Studio.Game, saveFolderDialog.Folder, exportListType));
|
await Task.Run(() => AssetsHelper.BuildBoth(files, name, openFolderDialog.Folder, Studio.Game, saveFolderDialog.Folder, exportListType));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2275,7 +2274,6 @@ namespace AssetStudioGUI
|
|||||||
{
|
{
|
||||||
Logger.Info("Scanning for files...");
|
Logger.Info("Scanning for files...");
|
||||||
var files = Directory.GetFiles(openFolderDialog.Folder, "*.*", SearchOption.AllDirectories).ToArray();
|
var files = Directory.GetFiles(openFolderDialog.Folder, "*.*", SearchOption.AllDirectories).ToArray();
|
||||||
files = files.Where(x => FileReader.IsReadable(x, Studio.Game)).ToArray();
|
|
||||||
Logger.Info($"Found {files.Length} files");
|
Logger.Info($"Found {files.Length} files");
|
||||||
|
|
||||||
var saveFolderDialog = new OpenFolderDialog();
|
var saveFolderDialog = new OpenFolderDialog();
|
||||||
|
|||||||
Reference in New Issue
Block a user