mirror of
https://github.com/aelurum/AssetStudio.git
synced 2025-07-20 19:44:16 -04:00
Merge branch 'AssetStudioMod' into ArknightsStudio
This commit is contained in:
@ -7,7 +7,7 @@ using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
using static AssetStudioCLI.Exporter;
|
||||
using static CubismLive2DExtractor.Live2DExtractor;
|
||||
using Ansi = AssetStudioCLI.CLIAnsiColors;
|
||||
using Ansi = AssetStudio.ColorConsole;
|
||||
|
||||
namespace AssetStudioCLI
|
||||
{
|
||||
@ -62,6 +62,7 @@ namespace AssetStudioCLI
|
||||
var i = 0;
|
||||
foreach (var assetsFile in assetsManager.assetsFileList)
|
||||
{
|
||||
var preloadTable = Array.Empty<PPtr<AssetStudio.Object>>();
|
||||
foreach (var asset in assetsFile.Objects)
|
||||
{
|
||||
var assetItem = new AssetItem(asset);
|
||||
@ -70,22 +71,31 @@ namespace AssetStudioCLI
|
||||
var isExportable = false;
|
||||
switch (asset)
|
||||
{
|
||||
case PreloadData m_PreloadData:
|
||||
preloadTable = m_PreloadData.m_Assets;
|
||||
break;
|
||||
case AssetBundle m_AssetBundle:
|
||||
var isStreamedSceneAssetBundle = m_AssetBundle.m_IsStreamedSceneAssetBundle;
|
||||
if (!isStreamedSceneAssetBundle)
|
||||
{
|
||||
preloadTable = m_AssetBundle.m_PreloadTable;
|
||||
}
|
||||
assetItem.Text = string.IsNullOrEmpty(m_AssetBundle.m_AssetBundleName) ? m_AssetBundle.m_Name : m_AssetBundle.m_AssetBundleName;
|
||||
|
||||
foreach (var m_Container in m_AssetBundle.m_Container)
|
||||
{
|
||||
var preloadIndex = m_Container.Value.preloadIndex;
|
||||
var preloadSize = m_Container.Value.preloadSize;
|
||||
var preloadSize = isStreamedSceneAssetBundle ? preloadTable.Length : m_Container.Value.preloadSize;
|
||||
var preloadEnd = preloadIndex + preloadSize;
|
||||
for (int k = preloadIndex; k < preloadEnd; k++)
|
||||
for (var k = preloadIndex; k < preloadEnd; k++)
|
||||
{
|
||||
var pptr = m_AssetBundle.m_PreloadTable[k];
|
||||
var pptr = preloadTable[k];
|
||||
if (pptr.TryGet(out var obj))
|
||||
{
|
||||
containers[obj] = m_Container.Key;
|
||||
}
|
||||
}
|
||||
}
|
||||
assetItem.Text = m_AssetBundle.m_Name;
|
||||
break;
|
||||
case ResourceManager m_ResourceManager:
|
||||
foreach (var m_Container in m_ResourceManager.m_Container)
|
||||
@ -110,7 +120,7 @@ namespace AssetStudioCLI
|
||||
if (!string.IsNullOrEmpty(m_VideoClip.m_OriginalPath))
|
||||
assetItem.FullSize = asset.byteSize + m_VideoClip.m_ExternalResources.m_Size;
|
||||
assetItem.Text = m_VideoClip.m_Name;
|
||||
break;
|
||||
break;
|
||||
case Shader m_Shader:
|
||||
assetItem.Text = m_Shader.m_ParsedForm?.m_Name ?? m_Shader.m_Name;
|
||||
break;
|
||||
@ -153,11 +163,11 @@ namespace AssetStudioCLI
|
||||
}
|
||||
foreach (var asset in loadedAssetsList)
|
||||
{
|
||||
if (containers.ContainsKey(asset.Asset))
|
||||
if (containers.TryGetValue(asset.Asset, out var container))
|
||||
{
|
||||
asset.Container = containers[asset.Asset];
|
||||
asset.Container = container;
|
||||
|
||||
if (asset.Type == ClassIDType.MonoBehaviour && asset.Container.Contains("/arts/charportraits/portraits"))
|
||||
if (asset.Type == ClassIDType.MonoBehaviour && container.Contains("/arts/charportraits/portraits"))
|
||||
{
|
||||
var portraitsList = Arknights.AkSpriteHelper.GeneratePortraits(asset);
|
||||
foreach (var portrait in portraitsList)
|
||||
@ -618,6 +628,8 @@ namespace AssetStudioCLI
|
||||
{
|
||||
var baseDestPath = Path.Combine(CLIOptions.o_outputFolder.Value, "Live2DOutput");
|
||||
var useFullContainerPath = false;
|
||||
var motionMode = CLIOptions.o_l2dMotionMode.Value;
|
||||
var forceBezier = CLIOptions.f_l2dForceBezier.Value;
|
||||
|
||||
Progress.Reset();
|
||||
Logger.Info($"Searching for Live2D files...");
|
||||
@ -631,6 +643,7 @@ namespace AssetStudioCLI
|
||||
}
|
||||
return false;
|
||||
}).Select(x => x.Asset).ToArray();
|
||||
|
||||
if (cubismMocs.Length == 0)
|
||||
{
|
||||
Logger.Default.Log(LoggerEvent.Info, "Live2D Cubism models were not found.", ignoreLevel: true);
|
||||
@ -638,7 +651,18 @@ namespace AssetStudioCLI
|
||||
}
|
||||
if (cubismMocs.Length > 1)
|
||||
{
|
||||
var basePathSet = cubismMocs.Select(x => containers[x].Substring(0, containers[x].LastIndexOf("/"))).ToHashSet();
|
||||
var basePathSet = cubismMocs.Select(x =>
|
||||
{
|
||||
var pathLen = containers.TryGetValue(x, out var itemContainer) ? itemContainer.LastIndexOf("/") : 0;
|
||||
pathLen = pathLen < 0 ? containers[x].Length : pathLen;
|
||||
return itemContainer?.Substring(0, pathLen);
|
||||
}).ToHashSet();
|
||||
|
||||
if (basePathSet.All(x => x == null))
|
||||
{
|
||||
Logger.Error($"Live2D Cubism export error: Cannot find any model related files.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (basePathSet.Count != cubismMocs.Length)
|
||||
{
|
||||
@ -646,9 +670,16 @@ namespace AssetStudioCLI
|
||||
Logger.Debug($"useFullContainerPath: {useFullContainerPath}");
|
||||
}
|
||||
}
|
||||
var basePathList = useFullContainerPath ?
|
||||
cubismMocs.Select(x => containers[x]).ToList() :
|
||||
cubismMocs.Select(x => containers[x].Substring(0, containers[x].LastIndexOf("/"))).ToList();
|
||||
|
||||
var basePathList = cubismMocs.Select(x =>
|
||||
{
|
||||
containers.TryGetValue(x, out var container);
|
||||
container = useFullContainerPath
|
||||
? container
|
||||
: container?.Substring(0, container.LastIndexOf("/"));
|
||||
return container;
|
||||
}).Where(x => x != null).ToList();
|
||||
|
||||
var lookup = containers.ToLookup(
|
||||
x => basePathList.Find(b => x.Value.Contains(b) && x.Value.Split('/').Any(y => y == b.Substring(b.LastIndexOf("/") + 1))),
|
||||
x => x.Key
|
||||
@ -656,31 +687,31 @@ namespace AssetStudioCLI
|
||||
|
||||
var totalModelCount = lookup.LongCount(x => x.Key != null);
|
||||
Logger.Info($"Found {totalModelCount} model(s).");
|
||||
var name = "";
|
||||
var modelCounter = 0;
|
||||
foreach (var assets in lookup)
|
||||
{
|
||||
var container = assets.Key;
|
||||
if (container == null)
|
||||
var srcContainer = assets.Key;
|
||||
if (srcContainer == null)
|
||||
continue;
|
||||
name = container;
|
||||
var container = srcContainer;
|
||||
|
||||
Logger.Info($"[{modelCounter + 1}/{totalModelCount}] Exporting Live2D: \"{container.Color(Ansi.BrightCyan)}\"");
|
||||
Logger.Info($"[{modelCounter + 1}/{totalModelCount}] Exporting Live2D: \"{srcContainer.Color(Ansi.BrightCyan)}\"");
|
||||
try
|
||||
{
|
||||
var modelName = useFullContainerPath ? Path.GetFileNameWithoutExtension(container) : container.Substring(container.LastIndexOf('/') + 1);
|
||||
container = Path.HasExtension(container) ? container.Replace(Path.GetExtension(container), "") : container;
|
||||
var destPath = Path.Combine(baseDestPath, container) + Path.DirectorySeparatorChar;
|
||||
|
||||
ExtractLive2D(assets, destPath, modelName, assemblyLoader);
|
||||
ExtractLive2D(assets, destPath, modelName, assemblyLoader, motionMode, forceBezier);
|
||||
modelCounter++;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error($"Live2D model export error: \"{name}\"", ex);
|
||||
Logger.Error($"Live2D model export error: \"{srcContainer}\"", ex);
|
||||
}
|
||||
Progress.Report(modelCounter, (int)totalModelCount);
|
||||
}
|
||||
|
||||
var status = modelCounter > 0 ?
|
||||
$"Finished exporting [{modelCounter}/{totalModelCount}] Live2D model(s) to \"{CLIOptions.o_outputFolder.Value.Color(Ansi.BrightCyan)}\"" :
|
||||
"Nothing exported.";
|
||||
|
Reference in New Issue
Block a user