Changes:
- temp fix for shader class. - added new entry. - more updates to CLI - fixes #3 - add #4
This commit is contained in:
@@ -78,7 +78,7 @@ namespace AssetStudio
|
||||
if (await NeedDownload(version, versionIndex.MappedPath))
|
||||
{
|
||||
Logger.Info("Downloading...");
|
||||
var json = await DownloadString(url, TimeSpan.FromMinutes(1));
|
||||
var json = await DownloadString(url, TimeSpan.FromMinutes(2));
|
||||
if (string.IsNullOrEmpty(json))
|
||||
{
|
||||
Logger.Warning("Could not load AI !!");
|
||||
|
||||
@@ -8,6 +8,7 @@ using Newtonsoft.Json.Converters;
|
||||
using Newtonsoft.Json;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Xml;
|
||||
using System.Text;
|
||||
|
||||
namespace AssetStudio
|
||||
{
|
||||
@@ -82,10 +83,11 @@ namespace AssetStudio
|
||||
|
||||
public static void BuildMap(string[] files, string mapName, string baseFolder, Game game)
|
||||
{
|
||||
Logger.Info($"Processing...");
|
||||
Logger.Info($"Building Map...");
|
||||
try
|
||||
{
|
||||
Map.Clear();
|
||||
Progress.Reset();
|
||||
var collision = 0;
|
||||
BaseFolder = baseFolder;
|
||||
assetsManager.Game = game;
|
||||
@@ -118,7 +120,8 @@ namespace AssetStudio
|
||||
}
|
||||
Map.Add(assetsFile.fileName, entry);
|
||||
}
|
||||
Logger.Info($"Processed {Path.GetFileName(file)}");
|
||||
Logger.Info($"[{i + 1}/{files.Length}] Processed {Path.GetFileName(file)}");
|
||||
Progress.Report(i + 1, files.Length);
|
||||
}
|
||||
assetsManager.Clear();
|
||||
}
|
||||
@@ -156,7 +159,9 @@ namespace AssetStudio
|
||||
|
||||
public static void BuildBoth(string[] files, string mapName, string baseFolder, Game game, string savePath, ExportListType exportListType, ManualResetEvent resetEvent = null, Regex[] nameFilters = null, Regex[] containerFilters = null)
|
||||
{
|
||||
Logger.Info($"Building Both...");
|
||||
Map.Clear();
|
||||
Progress.Reset();
|
||||
var collision = 0;
|
||||
BaseFolder = baseFolder;
|
||||
assetsManager.Game = game;
|
||||
@@ -203,74 +208,89 @@ namespace AssetStudio
|
||||
Source = file,
|
||||
PathID = objectReader.m_PathID,
|
||||
Type = objectReader.type,
|
||||
Container = ""
|
||||
Container = string.Empty,
|
||||
Name = string.Empty
|
||||
};
|
||||
|
||||
var exportable = true;
|
||||
switch (objectReader.type)
|
||||
try
|
||||
{
|
||||
case ClassIDType.AssetBundle:
|
||||
var assetBundle = new AssetBundle(objectReader);
|
||||
foreach (var m_Container in assetBundle.m_Container)
|
||||
{
|
||||
var preloadIndex = m_Container.Value.preloadIndex;
|
||||
var preloadSize = m_Container.Value.preloadSize;
|
||||
var preloadEnd = preloadIndex + preloadSize;
|
||||
for (int k = preloadIndex; k < preloadEnd; k++)
|
||||
switch (objectReader.type)
|
||||
{
|
||||
case ClassIDType.AssetBundle:
|
||||
var assetBundle = new AssetBundle(objectReader);
|
||||
foreach (var m_Container in assetBundle.m_Container)
|
||||
{
|
||||
containers.Add((assetBundle.m_PreloadTable[k], m_Container.Key));
|
||||
var preloadIndex = m_Container.Value.preloadIndex;
|
||||
var preloadSize = m_Container.Value.preloadSize;
|
||||
var preloadEnd = preloadIndex + preloadSize;
|
||||
for (int k = preloadIndex; k < preloadEnd; k++)
|
||||
{
|
||||
containers.Add((assetBundle.m_PreloadTable[k], m_Container.Key));
|
||||
}
|
||||
}
|
||||
}
|
||||
obj = null;
|
||||
asset.Name = assetBundle.m_Name;
|
||||
exportable = false;
|
||||
break;
|
||||
case ClassIDType.GameObject:
|
||||
var gameObject = new GameObject(objectReader);
|
||||
obj = gameObject;
|
||||
asset.Name = gameObject.m_Name;
|
||||
exportable = false;
|
||||
break;
|
||||
case ClassIDType.Shader:
|
||||
asset.Name = objectReader.ReadAlignedString();
|
||||
if (string.IsNullOrEmpty(asset.Name))
|
||||
{
|
||||
var m_parsedForm = new SerializedShader(objectReader);
|
||||
asset.Name = m_parsedForm.m_Name;
|
||||
}
|
||||
break;
|
||||
case ClassIDType.Animator:
|
||||
var component = new PPtr<Object>(objectReader);
|
||||
animators.Add((component, asset));
|
||||
break;
|
||||
case ClassIDType.MiHoYoBinData:
|
||||
var MiHoYoBinData = new MiHoYoBinData(objectReader);
|
||||
obj = MiHoYoBinData;
|
||||
exportable = true;
|
||||
break;
|
||||
case ClassIDType.IndexObject:
|
||||
var indexObject = new IndexObject(objectReader);
|
||||
obj = null;
|
||||
foreach (var index in indexObject.AssetMap)
|
||||
{
|
||||
mihoyoBinDataNames.Add((index.Value.Object, index.Key));
|
||||
}
|
||||
asset.Name = "IndexObject";
|
||||
break;
|
||||
case ClassIDType.Font:
|
||||
case ClassIDType.Material:
|
||||
case ClassIDType.Texture:
|
||||
case ClassIDType.Mesh:
|
||||
case ClassIDType.Sprite:
|
||||
case ClassIDType.TextAsset:
|
||||
case ClassIDType.Texture2D:
|
||||
case ClassIDType.VideoClip:
|
||||
case ClassIDType.AudioClip:
|
||||
asset.Name = objectReader.ReadAlignedString();
|
||||
break;
|
||||
default:
|
||||
exportable = false;
|
||||
break;
|
||||
obj = null;
|
||||
asset.Name = assetBundle.m_Name;
|
||||
exportable = false;
|
||||
break;
|
||||
case ClassIDType.GameObject:
|
||||
var gameObject = new GameObject(objectReader);
|
||||
obj = gameObject;
|
||||
asset.Name = gameObject.m_Name;
|
||||
exportable = false;
|
||||
break;
|
||||
case ClassIDType.Shader:
|
||||
asset.Name = objectReader.ReadAlignedString();
|
||||
if (string.IsNullOrEmpty(asset.Name))
|
||||
{
|
||||
var m_parsedForm = new SerializedShader(objectReader);
|
||||
asset.Name = m_parsedForm.m_Name;
|
||||
}
|
||||
break;
|
||||
case ClassIDType.Animator:
|
||||
var component = new PPtr<Object>(objectReader);
|
||||
animators.Add((component, asset));
|
||||
break;
|
||||
case ClassIDType.MiHoYoBinData:
|
||||
var MiHoYoBinData = new MiHoYoBinData(objectReader);
|
||||
obj = MiHoYoBinData;
|
||||
exportable = true;
|
||||
break;
|
||||
case ClassIDType.IndexObject:
|
||||
var indexObject = new IndexObject(objectReader);
|
||||
obj = null;
|
||||
foreach (var index in indexObject.AssetMap)
|
||||
{
|
||||
mihoyoBinDataNames.Add((index.Value.Object, index.Key));
|
||||
}
|
||||
asset.Name = "IndexObject";
|
||||
break;
|
||||
case ClassIDType.Font:
|
||||
case ClassIDType.Material:
|
||||
case ClassIDType.Texture:
|
||||
case ClassIDType.Mesh:
|
||||
case ClassIDType.Sprite:
|
||||
case ClassIDType.TextAsset:
|
||||
case ClassIDType.Texture2D:
|
||||
case ClassIDType.VideoClip:
|
||||
case ClassIDType.AudioClip:
|
||||
asset.Name = objectReader.ReadAlignedString();
|
||||
break;
|
||||
default:
|
||||
exportable = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine("Unable to load object")
|
||||
.AppendLine($"Assets {assetsFile.fileName}")
|
||||
.AppendLine($"Path {assetsFile.originalPath}")
|
||||
.AppendLine($"Type {objectReader.type}")
|
||||
.AppendLine($"PathID {objectReader.m_PathID}")
|
||||
.Append(e);
|
||||
Logger.Error(sb.ToString());
|
||||
}
|
||||
if (obj != null)
|
||||
{
|
||||
@@ -319,7 +339,8 @@ namespace AssetStudio
|
||||
}
|
||||
}
|
||||
}
|
||||
Logger.Info($"Processed {Path.GetFileName(file)}");
|
||||
Logger.Info($"[{i + 1}/{files.Length}] Processed {Path.GetFileName(file)}");
|
||||
Progress.Report(i + 1, files.Length);
|
||||
}
|
||||
assetsManager.Clear();
|
||||
}
|
||||
@@ -421,6 +442,7 @@ namespace AssetStudio
|
||||
|
||||
public static AssetEntry[] BuildAssetMap(string[] files, Game game, Regex[] nameFilters = null, Regex[] containerFilters = null)
|
||||
{
|
||||
Progress.Reset();
|
||||
assetsManager.Game = game;
|
||||
var assets = new List<AssetEntry>();
|
||||
for (int i = 0; i < files.Length; i++)
|
||||
@@ -448,70 +470,84 @@ namespace AssetStudio
|
||||
};
|
||||
|
||||
var exportable = true;
|
||||
switch (objectReader.type)
|
||||
try
|
||||
{
|
||||
case ClassIDType.AssetBundle:
|
||||
var assetBundle = new AssetBundle(objectReader);
|
||||
foreach (var m_Container in assetBundle.m_Container)
|
||||
{
|
||||
var preloadIndex = m_Container.Value.preloadIndex;
|
||||
var preloadSize = m_Container.Value.preloadSize;
|
||||
var preloadEnd = preloadIndex + preloadSize;
|
||||
for (int k = preloadIndex; k < preloadEnd; k++)
|
||||
switch (objectReader.type)
|
||||
{
|
||||
case ClassIDType.AssetBundle:
|
||||
var assetBundle = new AssetBundle(objectReader);
|
||||
foreach (var m_Container in assetBundle.m_Container)
|
||||
{
|
||||
containers.Add((assetBundle.m_PreloadTable[k], m_Container.Key));
|
||||
var preloadIndex = m_Container.Value.preloadIndex;
|
||||
var preloadSize = m_Container.Value.preloadSize;
|
||||
var preloadEnd = preloadIndex + preloadSize;
|
||||
for (int k = preloadIndex; k < preloadEnd; k++)
|
||||
{
|
||||
containers.Add((assetBundle.m_PreloadTable[k], m_Container.Key));
|
||||
}
|
||||
}
|
||||
}
|
||||
obj = null;
|
||||
asset.Name = assetBundle.m_Name;
|
||||
exportable = false;
|
||||
break;
|
||||
case ClassIDType.GameObject:
|
||||
var gameObject = new GameObject(objectReader);
|
||||
obj = gameObject;
|
||||
asset.Name = gameObject.m_Name;
|
||||
exportable = false;
|
||||
break;
|
||||
case ClassIDType.Shader:
|
||||
asset.Name = objectReader.ReadAlignedString();
|
||||
if (string.IsNullOrEmpty(asset.Name))
|
||||
{
|
||||
var m_parsedForm = new SerializedShader(objectReader);
|
||||
asset.Name = m_parsedForm.m_Name;
|
||||
}
|
||||
break;
|
||||
case ClassIDType.Animator:
|
||||
var component = new PPtr<Object>(objectReader);
|
||||
animators.Add((component, asset));
|
||||
break;
|
||||
case ClassIDType.MiHoYoBinData:
|
||||
var MiHoYoBinData = new MiHoYoBinData(objectReader);
|
||||
obj = MiHoYoBinData;
|
||||
exportable = true;
|
||||
break;
|
||||
case ClassIDType.IndexObject:
|
||||
var indexObject = new IndexObject(objectReader);
|
||||
obj = null;
|
||||
foreach (var index in indexObject.AssetMap)
|
||||
{
|
||||
mihoyoBinDataNames.Add((index.Value.Object, index.Key));
|
||||
}
|
||||
asset.Name = "IndexObject";
|
||||
break;
|
||||
case ClassIDType.Font:
|
||||
case ClassIDType.Material:
|
||||
case ClassIDType.Texture:
|
||||
case ClassIDType.Mesh:
|
||||
case ClassIDType.Sprite:
|
||||
case ClassIDType.TextAsset:
|
||||
case ClassIDType.Texture2D:
|
||||
case ClassIDType.VideoClip:
|
||||
case ClassIDType.AudioClip:
|
||||
asset.Name = objectReader.ReadAlignedString();
|
||||
break;
|
||||
default:
|
||||
exportable = false;
|
||||
break;
|
||||
obj = null;
|
||||
asset.Name = assetBundle.m_Name;
|
||||
exportable = false;
|
||||
break;
|
||||
case ClassIDType.GameObject:
|
||||
var gameObject = new GameObject(objectReader);
|
||||
obj = gameObject;
|
||||
asset.Name = gameObject.m_Name;
|
||||
exportable = false;
|
||||
break;
|
||||
case ClassIDType.Shader:
|
||||
asset.Name = objectReader.ReadAlignedString();
|
||||
if (string.IsNullOrEmpty(asset.Name))
|
||||
{
|
||||
var m_parsedForm = new SerializedShader(objectReader);
|
||||
asset.Name = m_parsedForm.m_Name;
|
||||
}
|
||||
break;
|
||||
case ClassIDType.Animator:
|
||||
var component = new PPtr<Object>(objectReader);
|
||||
animators.Add((component, asset));
|
||||
break;
|
||||
case ClassIDType.MiHoYoBinData:
|
||||
var MiHoYoBinData = new MiHoYoBinData(objectReader);
|
||||
obj = MiHoYoBinData;
|
||||
exportable = true;
|
||||
break;
|
||||
case ClassIDType.IndexObject:
|
||||
var indexObject = new IndexObject(objectReader);
|
||||
obj = null;
|
||||
foreach (var index in indexObject.AssetMap)
|
||||
{
|
||||
mihoyoBinDataNames.Add((index.Value.Object, index.Key));
|
||||
}
|
||||
asset.Name = "IndexObject";
|
||||
break;
|
||||
case ClassIDType.Font:
|
||||
case ClassIDType.Material:
|
||||
case ClassIDType.Texture:
|
||||
case ClassIDType.Mesh:
|
||||
case ClassIDType.Sprite:
|
||||
case ClassIDType.TextAsset:
|
||||
case ClassIDType.Texture2D:
|
||||
case ClassIDType.VideoClip:
|
||||
case ClassIDType.AudioClip:
|
||||
asset.Name = objectReader.ReadAlignedString();
|
||||
break;
|
||||
default:
|
||||
exportable = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine("Unable to load object")
|
||||
.AppendLine($"Assets {assetsFile.fileName}")
|
||||
.AppendLine($"Path {assetsFile.originalPath}")
|
||||
.AppendLine($"Type {objectReader.type}")
|
||||
.AppendLine($"PathID {objectReader.m_PathID}")
|
||||
.Append(e);
|
||||
Logger.Error(sb.ToString());
|
||||
}
|
||||
if (obj != null)
|
||||
{
|
||||
@@ -560,7 +596,8 @@ namespace AssetStudio
|
||||
}
|
||||
}
|
||||
}
|
||||
Logger.Info($"Processed {Path.GetFileName(file)}");
|
||||
Logger.Info($"[{i + 1}/{files.Length}] Processed {Path.GetFileName(file)}");
|
||||
Progress.Report(i + 1, files.Length);
|
||||
}
|
||||
assetsManager.Clear();
|
||||
}
|
||||
|
||||
@@ -107,11 +107,6 @@ namespace AssetStudio
|
||||
Logger.Info("Loading files has been aborted !!");
|
||||
break;
|
||||
}
|
||||
if (!SkipProcess && !tokenSource.IsCancellationRequested)
|
||||
{
|
||||
ReadAssets();
|
||||
ProcessAssets();
|
||||
}
|
||||
}
|
||||
|
||||
importFiles.Clear();
|
||||
@@ -120,12 +115,12 @@ namespace AssetStudio
|
||||
assetsFileListHash.Clear();
|
||||
AssetsHelper.ClearOffsets();
|
||||
|
||||
//if (!SkipProcess && !tokenSource.IsCancellationRequested)
|
||||
//{
|
||||
// ReadAssets();
|
||||
// ProcessAssets();
|
||||
//}
|
||||
if (!SkipProcess && !tokenSource.IsCancellationRequested)
|
||||
{
|
||||
ReadAssets();
|
||||
ProcessAssets();
|
||||
}
|
||||
}
|
||||
|
||||
private void LoadFile(string fullName)
|
||||
{
|
||||
@@ -177,36 +172,36 @@ namespace AssetStudio
|
||||
assetsFileList.Add(assetsFile);
|
||||
assetsFileListHash.Add(assetsFile.fileName);
|
||||
|
||||
foreach (var sharedFile in assetsFile.m_Externals)
|
||||
{
|
||||
var sharedFileName = sharedFile.fileName;
|
||||
foreach (var sharedFile in assetsFile.m_Externals)
|
||||
{
|
||||
var sharedFileName = sharedFile.fileName;
|
||||
|
||||
if (!importFilesHash.Contains(sharedFileName))
|
||||
if (!importFilesHash.Contains(sharedFileName))
|
||||
{
|
||||
var sharedFilePath = Path.Combine(Path.GetDirectoryName(reader.FullPath), sharedFileName);
|
||||
if (!noexistFiles.Contains(sharedFilePath))
|
||||
{
|
||||
var sharedFilePath = Path.Combine(Path.GetDirectoryName(reader.FullPath), sharedFileName);
|
||||
if (!noexistFiles.Contains(sharedFilePath))
|
||||
if (!File.Exists(sharedFilePath))
|
||||
{
|
||||
if (!File.Exists(sharedFilePath))
|
||||
var findFiles = Directory.GetFiles(Path.GetDirectoryName(reader.FullPath), sharedFileName, SearchOption.AllDirectories);
|
||||
if (findFiles.Length > 0)
|
||||
{
|
||||
var findFiles = Directory.GetFiles(Path.GetDirectoryName(reader.FullPath), sharedFileName, SearchOption.AllDirectories);
|
||||
if (findFiles.Length > 0)
|
||||
{
|
||||
sharedFilePath = findFiles[0];
|
||||
}
|
||||
}
|
||||
if (File.Exists(sharedFilePath))
|
||||
{
|
||||
importFiles.Add(sharedFilePath);
|
||||
importFilesHash.Add(sharedFileName);
|
||||
}
|
||||
else
|
||||
{
|
||||
noexistFiles.Add(sharedFilePath);
|
||||
sharedFilePath = findFiles[0];
|
||||
}
|
||||
}
|
||||
if (File.Exists(sharedFilePath))
|
||||
{
|
||||
importFiles.Add(sharedFilePath);
|
||||
importFilesHash.Add(sharedFileName);
|
||||
}
|
||||
else
|
||||
{
|
||||
noexistFiles.Add(sharedFilePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Error($"Error while reading assets file {reader.FullPath}", e);
|
||||
@@ -237,37 +232,37 @@ namespace AssetStudio
|
||||
assetsFileList.Add(assetsFile);
|
||||
assetsFileListHash.Add(assetsFile.fileName);
|
||||
|
||||
//if (ResolveDependencies)
|
||||
//{
|
||||
// foreach (var sharedFile in assetsFile.m_Externals)
|
||||
// {
|
||||
// var sharedFileName = sharedFile.fileName;
|
||||
//
|
||||
// if (!importFilesHash.Contains(sharedFileName))
|
||||
// {
|
||||
// var sharedFilePath = Path.Combine(Path.GetDirectoryName(originalPath), sharedFileName);
|
||||
// if (!noexistFiles.Contains(sharedFilePath))
|
||||
// {
|
||||
// if (AssetsHelper.TryAdd(sharedFileName, out var path))
|
||||
// {
|
||||
// sharedFilePath = path;
|
||||
// }
|
||||
// if (File.Exists(sharedFilePath))
|
||||
// {
|
||||
// if (!importFiles.Contains(sharedFilePath))
|
||||
// {
|
||||
// importFiles.Add(sharedFilePath);
|
||||
// }
|
||||
// importFilesHash.Add(sharedFileName);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// noexistFiles.Add(sharedFilePath);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
if (ResolveDependencies)
|
||||
{
|
||||
foreach (var sharedFile in assetsFile.m_Externals)
|
||||
{
|
||||
var sharedFileName = sharedFile.fileName;
|
||||
|
||||
if (!importFilesHash.Contains(sharedFileName))
|
||||
{
|
||||
var sharedFilePath = Path.Combine(Path.GetDirectoryName(originalPath), sharedFileName);
|
||||
if (!noexistFiles.Contains(sharedFilePath))
|
||||
{
|
||||
if (AssetsHelper.TryAdd(sharedFileName, out var path))
|
||||
{
|
||||
sharedFilePath = path;
|
||||
}
|
||||
if (File.Exists(sharedFilePath))
|
||||
{
|
||||
if (!importFiles.Contains(sharedFilePath))
|
||||
{
|
||||
importFiles.Add(sharedFilePath);
|
||||
}
|
||||
importFilesHash.Add(sharedFileName);
|
||||
}
|
||||
else
|
||||
{
|
||||
noexistFiles.Add(sharedFilePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -279,9 +274,12 @@ namespace AssetStudio
|
||||
Logger.Info($"Skipping {originalPath} ({reader.FileName})");
|
||||
}
|
||||
|
||||
private void LoadBundleFile(FileReader reader, string originalPath = null, long originalOffset = 0)
|
||||
private void LoadBundleFile(FileReader reader, string originalPath = null, long originalOffset = 0, bool log = true)
|
||||
{
|
||||
Logger.Info("Loading " + reader.FullPath);
|
||||
if (log)
|
||||
{
|
||||
Logger.Info("Loading " + reader.FullPath);
|
||||
}
|
||||
try
|
||||
{
|
||||
var bundleFile = new BundleFile(reader, Game);
|
||||
@@ -459,15 +457,18 @@ namespace AssetStudio
|
||||
Logger.Info("Loading " + reader.FullPath);
|
||||
try
|
||||
{
|
||||
using var stream = new BlockStream(reader.BaseStream, 0);
|
||||
using var stream = new SubStream(reader.BaseStream, 0);
|
||||
if (AssetsHelper.TryGet(reader.FullPath, out var offsets))
|
||||
{
|
||||
foreach (var offset in offsets)
|
||||
{
|
||||
var name = offset.ToString("X8");
|
||||
Logger.Info($"Loading Block {name}");
|
||||
|
||||
stream.Offset = offset;
|
||||
var dummyPath = Path.Combine(reader.FileName, offset.ToString("X8"));
|
||||
var dummyPath = Path.Combine(Path.GetDirectoryName(reader.FullPath), name);
|
||||
var subReader = new FileReader(dummyPath, stream, true);
|
||||
LoadBundleFile(subReader, reader.FullPath, offset);
|
||||
LoadBundleFile(subReader, reader.FullPath, offset, false);
|
||||
}
|
||||
AssetsHelper.Remove(reader.FullPath);
|
||||
}
|
||||
@@ -475,12 +476,15 @@ namespace AssetStudio
|
||||
{
|
||||
do
|
||||
{
|
||||
stream.Offset = stream.RelativePosition;
|
||||
var dummyPath = Path.Combine(reader.FileName, stream.RelativePosition.ToString("X8"));
|
||||
var name = stream.AbsolutePosition.ToString("X8");
|
||||
Logger.Info($"Loading Block {name}");
|
||||
|
||||
stream.Offset = stream.AbsolutePosition;
|
||||
var dummyPath = Path.Combine(Path.GetDirectoryName(reader.FullPath), name);
|
||||
var subReader = new FileReader(dummyPath, stream, true);
|
||||
LoadBundleFile(subReader, reader.FullPath, stream.RelativePosition);
|
||||
LoadBundleFile(subReader, reader.FullPath, stream.AbsolutePosition, false);
|
||||
} while (stream.Remaining > 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -501,16 +505,19 @@ namespace AssetStudio
|
||||
{
|
||||
foreach (var offset in offsets)
|
||||
{
|
||||
var name = offset.ToString("X8");
|
||||
Logger.Info($"Loading Block {name}");
|
||||
|
||||
stream.Offset = offset;
|
||||
var dummyPath = Path.Combine(reader.FileName, offset.ToString("X8"));
|
||||
var dummyPath = Path.Combine(Path.GetDirectoryName(reader.FullPath), name);
|
||||
var subReader = new FileReader(dummyPath, stream, true);
|
||||
switch (subReader.FileType)
|
||||
{
|
||||
case FileType.BundleFile:
|
||||
LoadBundleFile(subReader, reader.FullPath, offset);
|
||||
LoadBundleFile(subReader, reader.FullPath, offset, false);
|
||||
break;
|
||||
case FileType.Mhy0File:
|
||||
LoadMhy0File(subReader, reader.FullPath, offset);
|
||||
LoadMhy0File(subReader, reader.FullPath, offset, false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -520,18 +527,22 @@ namespace AssetStudio
|
||||
{
|
||||
do
|
||||
{
|
||||
stream.Offset = stream.RelativePosition;
|
||||
var dummyPath = Path.Combine(reader.FileName, stream.RelativePosition.ToString("X8"));
|
||||
var name = stream.Position.ToString("X8");
|
||||
Logger.Info($"Loading Block {name}");
|
||||
|
||||
var dummyPath = Path.Combine(Path.GetDirectoryName(reader.FullPath), name);
|
||||
var subReader = new FileReader(dummyPath, stream, true);
|
||||
switch (subReader.FileType)
|
||||
{
|
||||
case FileType.BundleFile:
|
||||
LoadBundleFile(subReader, reader.FullPath, stream.RelativePosition);
|
||||
LoadBundleFile(subReader, reader.FullPath, stream.Position, false);
|
||||
break;
|
||||
case FileType.Mhy0File:
|
||||
LoadMhy0File(subReader, reader.FullPath, stream.RelativePosition);
|
||||
LoadMhy0File(subReader, reader.FullPath, stream.Position, false);
|
||||
break;
|
||||
}
|
||||
|
||||
stream.Offset += stream.Position;
|
||||
} while (stream.Remaining > 0);
|
||||
}
|
||||
}
|
||||
@@ -548,9 +559,12 @@ namespace AssetStudio
|
||||
reader.Dispose();
|
||||
}
|
||||
}
|
||||
private void LoadMhy0File(FileReader reader, string originalPath = null, long originalOffset = 0)
|
||||
private void LoadMhy0File(FileReader reader, string originalPath = null, long originalOffset = 0, bool log = true)
|
||||
{
|
||||
Logger.Info("Loading " + reader.FullPath);
|
||||
if (log)
|
||||
{
|
||||
Logger.Info("Loading " + reader.FullPath);
|
||||
}
|
||||
try
|
||||
{
|
||||
var mhy0File = new Mhy0File(reader, reader.FullPath, (Mhy0)Game);
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace AssetStudio
|
||||
{
|
||||
public class BlockStream : Stream
|
||||
{
|
||||
private readonly Stream _baseStream;
|
||||
private readonly long _origin;
|
||||
private long _startPosition;
|
||||
|
||||
public override bool CanRead => _baseStream.CanRead;
|
||||
public override bool CanSeek => _baseStream.CanSeek;
|
||||
public override bool CanWrite => false;
|
||||
|
||||
public override long Length => _baseStream.Length - _startPosition;
|
||||
|
||||
public override long Position
|
||||
{
|
||||
get => _baseStream.Position - _startPosition;
|
||||
set => Seek(value, SeekOrigin.Begin);
|
||||
}
|
||||
|
||||
public long Offset
|
||||
{
|
||||
get => _startPosition;
|
||||
set => _startPosition = value + _origin;
|
||||
}
|
||||
|
||||
public long RelativePosition => _baseStream.Position - _origin;
|
||||
public long Remaining => Length - Position;
|
||||
|
||||
public BlockStream(Stream stream, long offset)
|
||||
{
|
||||
_baseStream = stream;
|
||||
_origin = offset;
|
||||
_startPosition = offset;
|
||||
Seek(0, SeekOrigin.Begin);
|
||||
}
|
||||
|
||||
public override long Seek(long offset, SeekOrigin origin)
|
||||
{
|
||||
var target = origin switch
|
||||
{
|
||||
SeekOrigin.Begin => offset + _startPosition,
|
||||
SeekOrigin.Current => offset + _baseStream.Position,
|
||||
SeekOrigin.End => offset + Length,
|
||||
_ => throw new NotSupportedException()
|
||||
};
|
||||
|
||||
_baseStream.Seek(target, SeekOrigin.Begin);
|
||||
return Position;
|
||||
}
|
||||
public override int Read(byte[] buffer, int offset, int count) => _baseStream.Read(buffer, offset, count);
|
||||
public override void Write(byte[] buffer, int offset, int count) => throw new NotImplementedException();
|
||||
public override void SetLength(long value) => throw new NotImplementedException();
|
||||
public override void Flush() => throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
@@ -112,7 +112,7 @@ namespace AssetStudio
|
||||
switch (header.signature)
|
||||
{
|
||||
case "UnityFS":
|
||||
if (Game.Type.IsBH3())
|
||||
if (Game.Type.IsBH3Group())
|
||||
{
|
||||
var version = reader.ReadUInt32();
|
||||
if (version > 11)
|
||||
@@ -277,7 +277,7 @@ namespace AssetStudio
|
||||
|
||||
private void ReadHeader(FileReader reader)
|
||||
{
|
||||
if (Game.Type.IsBH3() && XORShift128.Init)
|
||||
if ((Game.Type.IsBH3Group()) && XORShift128.Init)
|
||||
{
|
||||
m_Header.flags = (ArchiveFlags)reader.ReadUInt32();
|
||||
m_Header.size = reader.ReadInt64();
|
||||
|
||||
@@ -672,7 +672,7 @@ namespace AssetStudio
|
||||
{
|
||||
m_ConstantClip = new ConstantClip(reader);
|
||||
}
|
||||
if (reader.Game.Type.IsGIGroup() || reader.Game.Type.IsBH3() || reader.Game.Type.IsZZZCB1())
|
||||
if (reader.Game.Type.IsGIGroup() || reader.Game.Type.IsBH3Group() || reader.Game.Type.IsZZZCB1())
|
||||
{
|
||||
m_ACLClip.Read(reader);
|
||||
}
|
||||
|
||||
@@ -41,26 +41,6 @@ namespace AssetStudio
|
||||
var name = m_External.fileName;
|
||||
if (!assetsFileIndexCache.TryGetValue(name, out index))
|
||||
{
|
||||
if (assetsManager.ResolveDependencies && !assetsManager.importFilesHash.Contains(name))
|
||||
{
|
||||
var sharedFilePath = Path.Combine(Path.GetDirectoryName(assetsFile.originalPath), name);
|
||||
if (!assetsManager.noexistFiles.Contains(sharedFilePath))
|
||||
{
|
||||
if (TryAdd(name, out var path))
|
||||
{
|
||||
sharedFilePath = path;
|
||||
}
|
||||
if (File.Exists(sharedFilePath))
|
||||
{
|
||||
assetsManager.importFilesHash.Add(name);
|
||||
assetsManager.LoadFiles(sharedFilePath);
|
||||
}
|
||||
else
|
||||
{
|
||||
assetsManager.noexistFiles.Add(sharedFilePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
index = assetsFileList.FindIndex(x => x.fileName.Equals(name, StringComparison.OrdinalIgnoreCase));
|
||||
assetsFileIndexCache.Add(name, index);
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ namespace AssetStudio
|
||||
{
|
||||
var m_DynamicOccludee = reader.ReadByte();
|
||||
}
|
||||
if (reader.Game.Type.IsBH3())
|
||||
if (reader.Game.Type.IsBH3Group())
|
||||
{
|
||||
var m_AllowHalfResolution = reader.ReadByte();
|
||||
}
|
||||
|
||||
@@ -585,7 +585,7 @@ namespace AssetStudio
|
||||
m_BlobIndex = reader.ReadUInt32();
|
||||
m_Channels = new ParserBindChannels(reader);
|
||||
|
||||
if ((version[0] >= 2019 && version[0] < 2021) || (version[0] == 2021 && version[1] < 2)) //2019 ~2021.1
|
||||
if ((version[0] >= 2019 && version[0] < 2021) || (version[0] == 2021 && version[1] < 2) || reader.Match("E99740711222CD922E9A6F92FF1EB07A") || reader.Match("450A058C218DAF000647948F2F59DA6D")) //2019 ~2021.1
|
||||
{
|
||||
var m_GlobalKeywordIndices = reader.ReadUInt16Array();
|
||||
reader.AlignStream();
|
||||
@@ -605,17 +605,6 @@ namespace AssetStudio
|
||||
m_GpuProgramType = (ShaderGpuProgramType)reader.ReadSByte();
|
||||
reader.AlignStream();
|
||||
|
||||
if (reader.Game.Type.IsGI() && (m_GpuProgramType == ShaderGpuProgramType.Unknown || !Enum.IsDefined(typeof(ShaderGpuProgramType), m_GpuProgramType)))
|
||||
{
|
||||
reader.Position -= 4;
|
||||
var m_LocalKeywordIndices = reader.ReadUInt16Array();
|
||||
reader.AlignStream();
|
||||
|
||||
m_ShaderHardwareTier = reader.ReadSByte();
|
||||
m_GpuProgramType = (ShaderGpuProgramType)reader.ReadSByte();
|
||||
reader.AlignStream();
|
||||
}
|
||||
|
||||
if ((version[0] == 2020 && version[1] > 3) ||
|
||||
(version[0] == 2020 && version[1] == 3 && version[2] >= 2) || //2020.3.2f1 and up
|
||||
(version[0] > 2021) ||
|
||||
@@ -697,6 +686,16 @@ namespace AssetStudio
|
||||
var m_ShaderRequirements = reader.ReadInt32();
|
||||
}
|
||||
}
|
||||
|
||||
if (reader.Match("E99740711222CD922E9A6F92FF1EB07A"))
|
||||
{
|
||||
int numInstancedStructuredBuffers = reader.ReadInt32();
|
||||
var m_InstancedStructuredBuffers = new ConstantBuffer[numInstancedStructuredBuffers];
|
||||
for (int i = 0; i < numInstancedStructuredBuffers; i++)
|
||||
{
|
||||
m_InstancedStructuredBuffers[i] = new ConstantBuffer(reader);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ namespace AssetStudio
|
||||
{
|
||||
public static class BlkUtils
|
||||
{
|
||||
private const int DataPos = 0x2A;
|
||||
private const int DataOffset = 0x2A;
|
||||
private const int KeySize = 0x1000;
|
||||
private const int SeedBlockSize = 0x800;
|
||||
|
||||
@@ -54,7 +54,7 @@ namespace AssetStudio
|
||||
BinaryPrimitives.WriteUInt64LittleEndian(xorpad.AsSpan(i, 8), mt64.Int64());
|
||||
}
|
||||
|
||||
return new XORStream(reader.BaseStream, DataPos, xorpad);
|
||||
return new XORStream(reader.BaseStream, DataOffset, xorpad);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -126,6 +126,14 @@ namespace AssetStudio
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool IsReadable(string path, Game game)
|
||||
{
|
||||
var reader = new FileReader(path);
|
||||
reader = reader.PreProcessing(game);
|
||||
reader.Dispose();
|
||||
return reader.FileType != FileType.ResourceFile;
|
||||
}
|
||||
}
|
||||
|
||||
public static class FileReaderExtensions
|
||||
|
||||
@@ -19,6 +19,7 @@ namespace AssetStudio
|
||||
Games.Add(index++, new Blk(GameType.GI_CB3, GI_CBXExpansionKey, initVector: GI_CBXInitVector, initSeed: GI_CBXInitSeed));
|
||||
Games.Add(index++, new Mhy0(GameType.GI_CB3Pre, GI_CBXMhy0ShiftRow, GI_CBXMhy0Key, GI_CBXMhy0Mul, GI_CBXExpansionKey, GI_CBXSBox, GI_CBXInitVector, GI_CBXInitSeed));
|
||||
Games.Add(index++, new Mr0k(GameType.BH3, BH3ExpansionKey, BH3SBox, BH3InitVector, BH3BlockKey));
|
||||
Games.Add(index++, new Mr0k(GameType.BH3_Pre, PackExpansionKey, blockKey: PackBlockKey));
|
||||
Games.Add(index++, new Mr0k(GameType.SR_CB2, Mr0kExpansionKey, initVector: Mr0kInitVector, blockKey: Mr0kBlockKey));
|
||||
Games.Add(index++, new Mr0k(GameType.SR_CB3, Mr0kExpansionKey, initVector: Mr0kInitVector, blockKey: Mr0kBlockKey));
|
||||
Games.Add(index++, new Mr0k(GameType.ZZZ_CB1, Mr0kExpansionKey, initVector: Mr0kInitVector, blockKey: Mr0kBlockKey));
|
||||
@@ -120,6 +121,7 @@ namespace AssetStudio
|
||||
GI_CB3,
|
||||
GI_CB3Pre,
|
||||
BH3,
|
||||
BH3_Pre,
|
||||
ZZZ_CB1,
|
||||
SR_CB2,
|
||||
SR_CB3,
|
||||
@@ -143,6 +145,7 @@ namespace AssetStudio
|
||||
public static bool IsGICB3(this GameType type) => type == GameType.GI_CB3;
|
||||
public static bool IsGICB3Pre(this GameType type) => type == GameType.GI_CB3Pre;
|
||||
public static bool IsBH3(this GameType type) => type == GameType.BH3;
|
||||
public static bool IsBH3Pre(this GameType type) => type == GameType.BH3_Pre;
|
||||
public static bool IsZZZCB1(this GameType type) => type == GameType.ZZZ_CB1;
|
||||
public static bool IsSRCB2(this GameType type) => type == GameType.SR_CB2;
|
||||
public static bool IsSRCB3(this GameType type) => type == GameType.SR_CB3;
|
||||
@@ -161,6 +164,12 @@ namespace AssetStudio
|
||||
_ => false,
|
||||
};
|
||||
|
||||
public static bool IsBH3Group(this GameType type) => type switch
|
||||
{
|
||||
GameType.BH3 or GameType.BH3_Pre => true,
|
||||
_ => false,
|
||||
};
|
||||
|
||||
public static bool IsSRGroup(this GameType type) => type switch
|
||||
{
|
||||
GameType.SR_CB2 or GameType.SR_CB3 => true,
|
||||
@@ -169,7 +178,7 @@ namespace AssetStudio
|
||||
|
||||
public static bool IsBlockFile(this GameType type) => type switch
|
||||
{
|
||||
GameType.BH3 or GameType.SR_CB3 or GameType.GI_Pack or GameType.TOT => true,
|
||||
GameType.BH3 or GameType.BH3_Pre or GameType.SR_CB3 or GameType.GI_Pack or GameType.TOT => true,
|
||||
_ => false,
|
||||
};
|
||||
|
||||
|
||||
@@ -279,7 +279,7 @@ namespace AssetStudio
|
||||
var idx = data.Search("UnityFS");
|
||||
if (idx != -1)
|
||||
{
|
||||
stream = new BlockStream(stream, idx);
|
||||
stream = new SubStream(stream, idx);
|
||||
}
|
||||
|
||||
return new FileReader(reader.FullPath, stream);
|
||||
@@ -295,11 +295,11 @@ namespace AssetStudio
|
||||
var idx2 = data[(idx + 1)..].Search("UnityFS");
|
||||
if (idx2 != -1)
|
||||
{
|
||||
stream = new BlockStream(stream, idx + idx2 + 1);
|
||||
stream = new SubStream(stream, idx + idx2 + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
stream = new BlockStream(stream, idx);
|
||||
stream = new SubStream(stream, idx);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -371,7 +371,7 @@ namespace AssetStudio
|
||||
reader.Position = 0;
|
||||
return reader;
|
||||
}
|
||||
var stream = new BlockStream(reader.BaseStream, idx);
|
||||
var stream = new SubStream(reader.BaseStream, idx);
|
||||
return new FileReader(reader.FullPath, stream);
|
||||
}
|
||||
public static FileReader ParseHelixWaltz2(FileReader reader)
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace AssetStudio
|
||||
public int[] version => assetsFile.version;
|
||||
public BuildType buildType => assetsFile.buildType;
|
||||
|
||||
public ObjectReader(EndianBinaryReader reader, SerializedFile assetsFile, ObjectInfo objectInfo, Game game) : base(reader.BaseStream, reader.Endian)
|
||||
public ObjectReader(EndianBinaryReader reader, SerializedFile assetsFile, ObjectInfo objectInfo, Game game) : base(new SubStream(reader.BaseStream, objectInfo.byteStart, objectInfo.byteSize), reader.Endian)
|
||||
{
|
||||
this.assetsFile = assetsFile;
|
||||
Game = game;
|
||||
@@ -41,9 +41,11 @@ namespace AssetStudio
|
||||
m_Version = assetsFile.header.m_Version;
|
||||
}
|
||||
|
||||
public bool Match(string hash) => Convert.ToHexString(serializedType.m_OldTypeHash) == hash;
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
Position = byteStart;
|
||||
Position = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
103
AssetStudio/SubStream.cs
Normal file
103
AssetStudio/SubStream.cs
Normal file
@@ -0,0 +1,103 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace AssetStudio
|
||||
{
|
||||
public class SubStream : Stream
|
||||
{
|
||||
private readonly Stream _baseStream;
|
||||
private long _offset;
|
||||
private long _size;
|
||||
|
||||
public override bool CanRead => _baseStream.CanRead;
|
||||
public override bool CanSeek => _baseStream.CanSeek;
|
||||
public override bool CanWrite => false;
|
||||
|
||||
public long Size
|
||||
{
|
||||
get => _size;
|
||||
set
|
||||
{
|
||||
if (value < 0 || value > _baseStream.Length || value + _offset > _baseStream.Length)
|
||||
{
|
||||
throw new IOException($"{nameof(Size)} is out of stream bound");
|
||||
}
|
||||
_size = value;
|
||||
}
|
||||
}
|
||||
|
||||
public long Offset
|
||||
{
|
||||
get => _offset;
|
||||
set
|
||||
{
|
||||
if (value < 0 || value > _baseStream.Length)
|
||||
{
|
||||
throw new IOException($"{nameof(Offset)} is out of stream bound");
|
||||
}
|
||||
if (value + _size > _baseStream.Length)
|
||||
{
|
||||
_size = _baseStream.Length - value;
|
||||
}
|
||||
_offset = value;
|
||||
}
|
||||
}
|
||||
public long AbsolutePosition => _baseStream.Position;
|
||||
public long Remaining => Length - Position;
|
||||
|
||||
public override long Length => Size;
|
||||
public override long Position
|
||||
{
|
||||
get => _baseStream.Position - _offset;
|
||||
set => Seek(value, SeekOrigin.Begin);
|
||||
}
|
||||
|
||||
public SubStream(Stream stream, long offset)
|
||||
{
|
||||
_baseStream = stream;
|
||||
|
||||
Offset = offset;
|
||||
Size = _baseStream.Length - _offset;
|
||||
Seek(0, SeekOrigin.Begin);
|
||||
}
|
||||
|
||||
public SubStream(Stream stream, long offset, long size)
|
||||
{
|
||||
_baseStream = stream;
|
||||
|
||||
Offset = offset;
|
||||
Size = size;
|
||||
Seek(0, SeekOrigin.Begin);
|
||||
}
|
||||
|
||||
public override long Seek(long offset, SeekOrigin origin)
|
||||
{
|
||||
if (offset > _size)
|
||||
{
|
||||
throw new IOException("Unable to seek beyond stream bound");
|
||||
}
|
||||
|
||||
var target = origin switch
|
||||
{
|
||||
SeekOrigin.Begin => offset + _offset,
|
||||
SeekOrigin.Current => offset + Position,
|
||||
SeekOrigin.End => offset + _size,
|
||||
_ => throw new NotSupportedException()
|
||||
};
|
||||
|
||||
_baseStream.Seek(target, SeekOrigin.Begin);
|
||||
return Position;
|
||||
}
|
||||
public override int Read(byte[] buffer, int offset, int count)
|
||||
{
|
||||
if (offset > _size || Position + count > _size)
|
||||
{
|
||||
throw new IOException("Unable to read beyond stream bound");
|
||||
}
|
||||
return _baseStream.Read(buffer, offset, count);
|
||||
}
|
||||
public override void Write(byte[] buffer, int offset, int count) => throw new NotImplementedException();
|
||||
public override void SetLength(long value) => throw new NotImplementedException();
|
||||
public override void Flush() => throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
@@ -2,18 +2,20 @@
|
||||
|
||||
namespace AssetStudio
|
||||
{
|
||||
public class XORStream : BlockStream
|
||||
public class XORStream : SubStream
|
||||
{
|
||||
private readonly byte[] _xorpad;
|
||||
private readonly long _offset;
|
||||
|
||||
public XORStream(Stream stream, long pos, byte[] xorpad) : base(stream, pos)
|
||||
public XORStream(Stream stream, long offset, byte[] xorpad) : base(stream, offset)
|
||||
{
|
||||
_xorpad = xorpad;
|
||||
_offset = offset;
|
||||
}
|
||||
|
||||
public override int Read(byte[] buffer, int offset, int count)
|
||||
{
|
||||
var pos = RelativePosition;
|
||||
var pos = AbsolutePosition - _offset;
|
||||
var read = base.Read(buffer, offset, count);
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
|
||||
@@ -79,8 +79,9 @@ namespace AssetStudioCLI
|
||||
assemblyLoader.Load(o.DummyDllFolder.FullName);
|
||||
}
|
||||
|
||||
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 };
|
||||
files = files.Where(x => FileReader.IsReadable(x, game)).ToArray();
|
||||
Logger.Info(string.Format("Found {0} file(s)", files.Length));
|
||||
|
||||
if (o.MapOp.HasFlag(MapOpType.Build))
|
||||
@@ -107,6 +108,12 @@ namespace AssetStudioCLI
|
||||
AssetsHelper.ExportAssetsMap(assets, o.MapName, o.Output.FullName, o.MapType, resetEvent);
|
||||
resetEvent.WaitOne();
|
||||
}
|
||||
if (o.MapOp.HasFlag(MapOpType.Both))
|
||||
{
|
||||
var resetEvent = new ManualResetEvent(false);
|
||||
AssetsHelper.BuildBoth(files, o.MapName, o.Input.FullName, game, o.Output.FullName, o.MapType, resetEvent, o.NameFilter, o.ContainerFilter);
|
||||
resetEvent.WaitOne();
|
||||
}
|
||||
if (o.MapOp.Equals(MapOpType.None) || o.MapOp.HasFlag(MapOpType.Load))
|
||||
{
|
||||
var i = 0;
|
||||
|
||||
@@ -20,9 +20,9 @@ namespace AssetStudioCLI
|
||||
None,
|
||||
Load,
|
||||
Build,
|
||||
Both,
|
||||
List,
|
||||
All = Build | Load | List
|
||||
List = 4,
|
||||
Both = 8,
|
||||
All = Both | Load,
|
||||
}
|
||||
|
||||
public enum AssetGroupOption
|
||||
@@ -127,8 +127,8 @@ namespace AssetStudioCLI
|
||||
using var stream = BlkUtils.Decrypt(reader, (Blk)Game);
|
||||
do
|
||||
{
|
||||
stream.Offset = stream.RelativePosition;
|
||||
var dummyPath = Path.Combine(reader.FullPath, stream.RelativePosition.ToString("X8"));
|
||||
stream.Offset = stream.AbsolutePosition;
|
||||
var dummyPath = Path.Combine(reader.FullPath, stream.AbsolutePosition.ToString("X8"));
|
||||
var subReader = new FileReader(dummyPath, stream, true);
|
||||
var subSavePath = Path.Combine(savePath, reader.FileName + "_unpacked");
|
||||
switch (subReader.FileType)
|
||||
@@ -153,12 +153,12 @@ namespace AssetStudioCLI
|
||||
{
|
||||
int total = 0;
|
||||
Logger.Info($"Decompressing {reader.FileName} ...");
|
||||
using var stream = new BlockStream(reader.BaseStream, 0);
|
||||
using var stream = new SubStream(reader.BaseStream, 0);
|
||||
do
|
||||
{
|
||||
stream.Offset = stream.RelativePosition;
|
||||
stream.Offset = stream.AbsolutePosition;
|
||||
var subSavePath = Path.Combine(savePath, reader.FileName + "_unpacked");
|
||||
var dummyPath = Path.Combine(reader.FullPath, stream.RelativePosition.ToString("X8"));
|
||||
var dummyPath = Path.Combine(reader.FullPath, stream.AbsolutePosition.ToString("X8"));
|
||||
var subReader = new FileReader(dummyPath, stream, true);
|
||||
total += ExtractBundleFile(subReader, subSavePath);
|
||||
} while (stream.Remaining > 0);
|
||||
|
||||
@@ -1899,8 +1899,9 @@ namespace AssetStudioGUI
|
||||
openFolderDialog.Title = "Select Game Folder";
|
||||
if (openFolderDialog.ShowDialog(this) == DialogResult.OK)
|
||||
{
|
||||
Logger.Info("Scanning for files");
|
||||
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.BuildMap(files, name, openFolderDialog.Folder, Studio.Game));
|
||||
}
|
||||
@@ -2017,8 +2018,9 @@ namespace AssetStudioGUI
|
||||
openFolderDialog.Title = $"Select Game Folder";
|
||||
if (openFolderDialog.ShowDialog(this) == DialogResult.OK)
|
||||
{
|
||||
Logger.Info("Scanning for files");
|
||||
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");
|
||||
|
||||
var saveFolderDialog = new OpenFolderDialog();
|
||||
@@ -2317,7 +2319,7 @@ namespace AssetStudioGUI
|
||||
private void InitOpenTK()
|
||||
{
|
||||
ChangeGLSize(glControl.Size);
|
||||
GL.ClearColor(Color4.Darkgray);
|
||||
GL.ClearColor(Color4.Cadetblue);
|
||||
pgmID = GL.CreateProgram();
|
||||
LoadShader("vs", ShaderType.VertexShader, pgmID, out ShaderHandle vsID);
|
||||
LoadShader("fs", ShaderType.FragmentShader, pgmID, out ShaderHandle fsID);
|
||||
|
||||
@@ -128,8 +128,8 @@ namespace AssetStudioGUI
|
||||
using var stream = BlkUtils.Decrypt(reader, (Blk)Game);
|
||||
do
|
||||
{
|
||||
stream.Offset = stream.RelativePosition;
|
||||
var dummyPath = Path.Combine(reader.FullPath, stream.RelativePosition.ToString("X8"));
|
||||
stream.Offset = stream.AbsolutePosition;
|
||||
var dummyPath = Path.Combine(reader.FullPath, stream.AbsolutePosition.ToString("X8"));
|
||||
var subReader = new FileReader(dummyPath, stream, true);
|
||||
var subSavePath = Path.Combine(savePath, reader.FileName + "_unpacked");
|
||||
switch (subReader.FileType)
|
||||
@@ -154,12 +154,12 @@ namespace AssetStudioGUI
|
||||
{
|
||||
int total = 0;
|
||||
StatusStripUpdate($"Decompressing {reader.FileName} ...");
|
||||
using var stream = new BlockStream(reader.BaseStream, 0);
|
||||
using var stream = new SubStream(reader.BaseStream, 0);
|
||||
do
|
||||
{
|
||||
stream.Offset = stream.RelativePosition;
|
||||
stream.Offset = stream.AbsolutePosition;
|
||||
var subSavePath = Path.Combine(savePath, reader.FileName + "_unpacked");
|
||||
var dummyPath = Path.Combine(reader.FullPath, stream.RelativePosition.ToString("X8"));
|
||||
var dummyPath = Path.Combine(reader.FullPath, stream.AbsolutePosition.ToString("X8"));
|
||||
var subReader = new FileReader(dummyPath, stream, true);
|
||||
total += ExtractBundleFile(subReader, subSavePath);
|
||||
} while (stream.Remaining > 0);
|
||||
|
||||
Reference in New Issue
Block a user