improve export

This commit is contained in:
Perfare 2020-08-06 21:07:37 +08:00
parent 1766dcbdeb
commit 4e97b4b898
5 changed files with 77 additions and 74 deletions

View File

@ -86,7 +86,7 @@ namespace AssetStudio
foreach (var sharedFile in assetsFile.m_Externals) foreach (var sharedFile in assetsFile.m_Externals)
{ {
var sharedFilePath = Path.GetDirectoryName(fullName) + "\\" + sharedFile.fileName; var sharedFilePath = Path.Combine(Path.GetDirectoryName(fullName), sharedFile.fileName);
var sharedFileName = sharedFile.fileName; var sharedFileName = sharedFile.fileName;
if (!importFilesHash.Contains(sharedFileName)) if (!importFilesHash.Contains(sharedFileName))
@ -189,7 +189,7 @@ namespace AssetStudio
var webFile = new WebFile(reader); var webFile = new WebFile(reader);
foreach (var file in webFile.fileList) foreach (var file in webFile.fileList)
{ {
var dummyPath = Path.GetDirectoryName(fullName) + "\\" + file.fileName; var dummyPath = Path.Combine(Path.GetDirectoryName(fullName), file.fileName);
switch (CheckFileType(file.stream, out var fileReader)) switch (CheckFileType(file.stream, out var fileReader))
{ {
case FileType.AssetsFile: case FileType.AssetsFile:

View File

@ -20,8 +20,8 @@ namespace AssetStudio
foreach (var splitFile in splitFiles) foreach (var splitFile in splitFiles)
{ {
var destFile = Path.GetFileNameWithoutExtension(splitFile); var destFile = Path.GetFileNameWithoutExtension(splitFile);
var destPath = Path.GetDirectoryName(splitFile) + "\\"; var destPath = Path.GetDirectoryName(splitFile);
var destFull = destPath + destFile; var destFull = Path.Combine(destPath, destFile);
if (!File.Exists(destFull)) if (!File.Exists(destFull))
{ {
var splitParts = Directory.GetFiles(destPath, destFile + ".split*"); var splitParts = Directory.GetFiles(destPath, destFile + ".split*");
@ -43,7 +43,7 @@ namespace AssetStudio
public static string[] ProcessingSplitFiles(List<string> selectFile) public static string[] ProcessingSplitFiles(List<string> selectFile)
{ {
var splitFiles = selectFile.Where(x => x.Contains(".split")) var splitFiles = selectFile.Where(x => x.Contains(".split"))
.Select(x => Path.GetDirectoryName(x) + "\\" + Path.GetFileNameWithoutExtension(x)) .Select(x => Path.Combine(Path.GetDirectoryName(x), Path.GetFileNameWithoutExtension(x)))
.Distinct() .Distinct()
.ToList(); .ToList();
selectFile.RemoveAll(x => x.Contains(".split")); selectFile.RemoveAll(x => x.Contains(".split"));

View File

@ -332,7 +332,7 @@ namespace AssetStudioGUI
Progress.Reset(); Progress.Reset();
foreach (TypeTreeItem item in classesListView.Items) foreach (TypeTreeItem item in classesListView.Items)
{ {
var versionPath = savePath + "\\" + item.Group.Header; var versionPath = Path.Combine(savePath, item.Group.Header);
Directory.CreateDirectory(versionPath); Directory.CreateDirectory(versionPath);
var saveFile = $"{versionPath}\\{item.SubItems[1].Text} {item.Text}.txt"; var saveFile = $"{versionPath}\\{item.SubItems[1].Text} {item.Text}.txt";
@ -1422,7 +1422,7 @@ namespace AssetStudioGUI
var saveFolderDialog1 = new OpenFolderDialog(); var saveFolderDialog1 = new OpenFolderDialog();
if (saveFolderDialog1.ShowDialog(this) == DialogResult.OK) if (saveFolderDialog1.ShowDialog(this) == DialogResult.OK)
{ {
var savePath = saveFolderDialog1.Folder + "\\"; var savePath = saveFolderDialog1.Folder + Path.DirectorySeparatorChar;
ExportSplitObjects(savePath, sceneTreeView.Nodes); ExportSplitObjects(savePath, sceneTreeView.Nodes);
} }
} }

View File

@ -10,7 +10,7 @@ namespace AssetStudioGUI
{ {
internal static class Exporter internal static class Exporter
{ {
public static bool ExportTexture2D(AssetItem item, string exportPathName) public static bool ExportTexture2D(AssetItem item, string exportPath)
{ {
var m_Texture2D = (Texture2D)item.Asset; var m_Texture2D = (Texture2D)item.Asset;
if (Properties.Settings.Default.convertTexture) if (Properties.Settings.Default.convertTexture)
@ -36,25 +36,25 @@ namespace AssetStudioGUI
tga = true; tga = true;
break; break;
} }
var exportFullName = exportPathName + item.Text + "." + ext.ToLower(); if (!TryExportFile(exportPath, item, "." + ext.ToLower(), out var exportFullPath))
if (ExportFileExists(exportFullName))
return false; return false;
if (tga) if (tga)
{ {
var file = new TGA(bitmap); var file = new TGA(bitmap);
file.Save(exportFullName); file.Save(exportFullPath);
} }
else else
bitmap.Save(exportFullName, format); {
bitmap.Save(exportFullPath, format);
}
bitmap.Dispose(); bitmap.Dispose();
return true; return true;
} }
else else
{ {
var exportFullName = exportPathName + item.Text + ".tex"; if (!TryExportFile(exportPath, item, ".tex", out var exportFullPath))
if (ExportFileExists(exportFullName))
return false; return false;
File.WriteAllBytes(exportFullName, m_Texture2D.image_data.GetData()); File.WriteAllBytes(exportFullPath, m_Texture2D.image_data.GetData());
return true; return true;
} }
} }
@ -68,28 +68,25 @@ namespace AssetStudioGUI
var converter = new AudioClipConverter(m_AudioClip); var converter = new AudioClipConverter(m_AudioClip);
if (Properties.Settings.Default.convertAudio && converter.IsSupport) if (Properties.Settings.Default.convertAudio && converter.IsSupport)
{ {
var exportFullName = exportPath + item.Text + ".wav"; if (!TryExportFile(exportPath, item, ".wav", out var exportFullPath))
if (ExportFileExists(exportFullName))
return false; return false;
var buffer = converter.ConvertToWav(); var buffer = converter.ConvertToWav();
if (buffer == null) if (buffer == null)
return false; return false;
File.WriteAllBytes(exportFullName, buffer); File.WriteAllBytes(exportFullPath, buffer);
} }
else else
{ {
var exportFullName = exportPath + item.Text + converter.GetExtensionName(); if (!TryExportFile(exportPath, item, converter.GetExtensionName(), out var exportFullPath))
if (ExportFileExists(exportFullName))
return false; return false;
File.WriteAllBytes(exportFullName, m_AudioData); File.WriteAllBytes(exportFullPath, m_AudioData);
} }
return true; return true;
} }
public static bool ExportShader(AssetItem item, string exportPath) public static bool ExportShader(AssetItem item, string exportPath)
{ {
var exportFullName = exportPath + item.Text + ".shader"; if (!TryExportFile(exportPath, item, ".shader", out var exportFullPath))
if (ExportFileExists(exportFullName))
return false; return false;
var m_Shader = (Shader)item.Asset; var m_Shader = (Shader)item.Asset;
if (m_Shader.compressedBlob != null) //5.5 and up if (m_Shader.compressedBlob != null) //5.5 and up
@ -104,7 +101,7 @@ namespace AssetStudioGUI
else else
{ {
var str = ShaderConverter.Convert(m_Shader); var str = ShaderConverter.Convert(m_Shader);
File.WriteAllText(exportFullName, str); File.WriteAllText(exportFullPath, str);
} }
return true; return true;
} }
@ -120,21 +117,19 @@ namespace AssetStudioGUI
extension = Path.GetExtension(item.Container); extension = Path.GetExtension(item.Container);
} }
} }
var exportFullName = exportPath + item.Text + extension; if (!TryExportFile(exportPath, item, extension, out var exportFullPath))
if (ExportFileExists(exportFullName))
return false; return false;
File.WriteAllBytes(exportFullName, m_TextAsset.m_Script); File.WriteAllBytes(exportFullPath, m_TextAsset.m_Script);
return true; return true;
} }
public static bool ExportMonoBehaviour(AssetItem item, string exportPath) public static bool ExportMonoBehaviour(AssetItem item, string exportPath)
{ {
var exportFullName = exportPath + item.Text + ".txt"; if (!TryExportFile(exportPath, item, ".txt", out var exportFullPath))
if (ExportFileExists(exportFullName))
return false; return false;
var m_MonoBehaviour = (MonoBehaviour)item.Asset; var m_MonoBehaviour = (MonoBehaviour)item.Asset;
var str = m_MonoBehaviour.Dump() ?? Studio.GetScriptString(item.Asset.reader); var str = m_MonoBehaviour.Dump() ?? Studio.GetScriptString(item.Asset.reader);
File.WriteAllText(exportFullName, str); File.WriteAllText(exportFullPath, str);
return true; return true;
} }
@ -148,10 +143,9 @@ namespace AssetStudioGUI
{ {
extension = ".otf"; extension = ".otf";
} }
var exportFullName = exportPath + item.Text + extension; if (!TryExportFile(exportPath, item, extension, out var exportFullPath))
if (ExportFileExists(exportFullName))
return false; return false;
File.WriteAllBytes(exportFullName, m_Font.m_FontData); File.WriteAllBytes(exportFullPath, m_Font.m_FontData);
return true; return true;
} }
return false; return false;
@ -162,8 +156,7 @@ namespace AssetStudioGUI
var m_Mesh = (Mesh)item.Asset; var m_Mesh = (Mesh)item.Asset;
if (m_Mesh.m_VertexCount <= 0) if (m_Mesh.m_VertexCount <= 0)
return false; return false;
var exportFullName = exportPath + item.Text + ".obj"; if (!TryExportFile(exportPath, item, ".obj", out var exportFullPath))
if (ExportFileExists(exportFullName))
return false; return false;
var sb = new StringBuilder(); var sb = new StringBuilder();
sb.AppendLine("g " + m_Mesh.m_Name); sb.AppendLine("g " + m_Mesh.m_Name);
@ -235,7 +228,7 @@ namespace AssetStudioGUI
#endregion #endregion
sb.Replace("NaN", "0"); sb.Replace("NaN", "0");
File.WriteAllText(exportFullName, sb.ToString()); File.WriteAllText(exportFullPath, sb.ToString());
return true; return true;
} }
@ -245,10 +238,9 @@ namespace AssetStudioGUI
var m_VideoData = m_VideoClip.m_VideoData.GetData(); var m_VideoData = m_VideoClip.m_VideoData.GetData();
if (m_VideoData != null && m_VideoData.Length != 0) if (m_VideoData != null && m_VideoData.Length != 0)
{ {
var exportFullName = exportPath + item.Text + Path.GetExtension(m_VideoClip.m_OriginalPath); if (!TryExportFile(exportPath, item, Path.GetExtension(m_VideoClip.m_OriginalPath), out var exportFullPath))
if (ExportFileExists(exportFullName))
return false; return false;
File.WriteAllBytes(exportFullName, m_VideoData); File.WriteAllBytes(exportFullPath, m_VideoData);
return true; return true;
} }
return false; return false;
@ -257,10 +249,9 @@ namespace AssetStudioGUI
public static bool ExportMovieTexture(AssetItem item, string exportPath) public static bool ExportMovieTexture(AssetItem item, string exportPath)
{ {
var m_MovieTexture = (MovieTexture)item.Asset; var m_MovieTexture = (MovieTexture)item.Asset;
var exportFullName = exportPath + item.Text + ".ogv"; if (!TryExportFile(exportPath, item, ".ogv", out var exportFullPath))
if (ExportFileExists(exportFullName))
return false; return false;
File.WriteAllBytes(exportFullName, m_MovieTexture.m_MovieData); File.WriteAllBytes(exportFullPath, m_MovieTexture.m_MovieData);
return true; return true;
} }
@ -284,8 +275,7 @@ namespace AssetStudioGUI
tga = true; tga = true;
break; break;
} }
var exportFullName = exportPath + item.Text + "." + type.ToLower(); if (!TryExportFile(exportPath, item, "." + type.ToLower(), out var exportFullPath))
if (ExportFileExists(exportFullName))
return false; return false;
var bitmap = ((Sprite)item.Asset).GetImage(); var bitmap = ((Sprite)item.Asset).GetImage();
if (bitmap != null) if (bitmap != null)
@ -293,10 +283,12 @@ namespace AssetStudioGUI
if (tga) if (tga)
{ {
var file = new TGA(bitmap); var file = new TGA(bitmap);
file.Save(exportFullName); file.Save(exportFullPath);
} }
else else
bitmap.Save(exportFullName, format); {
bitmap.Save(exportFullPath, format);
}
bitmap.Dispose(); bitmap.Dispose();
return true; return true;
} }
@ -305,36 +297,47 @@ namespace AssetStudioGUI
public static bool ExportRawFile(AssetItem item, string exportPath) public static bool ExportRawFile(AssetItem item, string exportPath)
{ {
var exportFullName = exportPath + item.Text + ".dat"; if (!TryExportFile(exportPath, item, ".dat", out var exportFullPath))
if (ExportFileExists(exportFullName))
return false; return false;
File.WriteAllBytes(exportFullName, item.Asset.GetRawData()); File.WriteAllBytes(exportFullPath, item.Asset.GetRawData());
return true; return true;
} }
private static bool ExportFileExists(string filename) private static bool TryExportFile(string dir, AssetItem item, string extension, out string fullPath)
{ {
if (File.Exists(filename)) var fileName = FixFileName(item.Text);
fullPath = Path.Combine(dir, fileName + extension);
if (!File.Exists(fullPath))
{ {
Directory.CreateDirectory(dir);
return true;
}
fullPath = Path.Combine(dir, fileName + item.UniqueID + extension);
if (!File.Exists(fullPath))
{
Directory.CreateDirectory(dir);
return true; return true;
} }
Directory.CreateDirectory(Path.GetDirectoryName(filename));
return false; return false;
} }
public static bool ExportAnimator(AssetItem item, string exportPath, List<AssetItem> animationList = null) public static bool ExportAnimator(AssetItem item, string exportPath, List<AssetItem> animationList = null)
{ {
var exportFullPath = Path.Combine(exportPath, item.Text, item.Text + ".fbx");
if (File.Exists(exportFullPath))
{
exportFullPath = Path.Combine(exportPath, item.Text + item.UniqueID, item.Text + ".fbx");
}
var m_Animator = (Animator)item.Asset; var m_Animator = (Animator)item.Asset;
var convert = animationList != null ? new ModelConverter(m_Animator, animationList.Select(x => (AnimationClip)x.Asset).ToArray()) : new ModelConverter(m_Animator); var convert = animationList != null ? new ModelConverter(m_Animator, animationList.Select(x => (AnimationClip)x.Asset).ToArray()) : new ModelConverter(m_Animator);
exportPath = $"{exportPath}{item.Text}\\{item.Text}.fbx"; ExportFbx(convert, exportFullPath);
ExportFbx(convert, exportPath);
return true; return true;
} }
public static void ExportGameObject(GameObject gameObject, string exportPath, List<AssetItem> animationList = null) public static void ExportGameObject(GameObject gameObject, string exportPath, List<AssetItem> animationList = null)
{ {
var convert = animationList != null ? new ModelConverter(gameObject, animationList.Select(x => (AnimationClip)x.Asset).ToArray()) : new ModelConverter(gameObject); var convert = animationList != null ? new ModelConverter(gameObject, animationList.Select(x => (AnimationClip)x.Asset).ToArray()) : new ModelConverter(gameObject);
exportPath = exportPath + Studio.FixFileName(gameObject.m_Name) + ".fbx"; exportPath = exportPath + FixFileName(gameObject.m_Name) + ".fbx";
ExportFbx(convert, exportPath); ExportFbx(convert, exportPath);
} }
@ -364,13 +367,12 @@ namespace AssetStudioGUI
public static bool ExportDumpFile(AssetItem item, string exportPath) public static bool ExportDumpFile(AssetItem item, string exportPath)
{ {
var exportFullName = exportPath + item.Text + ".txt"; if (!TryExportFile(exportPath, item, ".txt", out var exportFullPath))
if (ExportFileExists(exportFullName))
return false; return false;
var str = item.Asset.Dump(); var str = item.Asset.Dump();
if (str != null) if (str != null)
{ {
File.WriteAllText(exportFullName, str); File.WriteAllText(exportFullPath, str);
return true; return true;
} }
return false; return false;
@ -408,5 +410,11 @@ namespace AssetStudioGUI
return ExportRawFile(item, exportPath); return ExportRawFile(item, exportPath);
} }
} }
public static string FixFileName(string str)
{
if (str.Length >= 260) return Path.GetRandomFileName();
return Path.GetInvalidFileNameChars().Aggregate(str, (current, c) => current.Replace(c, '_'));
}
} }
} }

View File

@ -101,7 +101,6 @@ namespace AssetStudioGUI
StatusStripUpdate("Building asset list..."); StatusStripUpdate("Building asset list...");
string productName = null; string productName = null;
var assetsNameHash = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
var objectCount = assetsManager.assetsFileList.Sum(x => x.Objects.Count); var objectCount = assetsManager.assetsFileList.Sum(x => x.Objects.Count);
var objectAssetItemDic = new Dictionary<Object, AssetItem>(objectCount); var objectAssetItemDic = new Dictionary<Object, AssetItem>(objectCount);
int i = 0; int i = 0;
@ -177,7 +176,17 @@ namespace AssetStudioGUI
containers = new Dictionary<long, string>(); containers = new Dictionary<long, string>();
foreach (var m_Container in m_AssetBundle.m_Container) foreach (var m_Container in m_AssetBundle.m_Container)
{ {
containers[m_Container.Value.asset.m_PathID] = 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++)
{
var m_PreloadTable = m_AssetBundle.m_PreloadTable[k];
if (m_PreloadTable.m_FileID == 0)
{
containers[m_AssetBundle.m_PreloadTable[k].m_PathID] = m_Container.Key;
}
}
} }
assetItem.Text = m_AssetBundle.m_Name; assetItem.Text = m_AssetBundle.m_Name;
break; break;
@ -189,13 +198,6 @@ namespace AssetStudioGUI
{ {
assetItem.Text = assetItem.TypeString + assetItem.UniqueID; assetItem.Text = assetItem.TypeString + assetItem.UniqueID;
} }
//处理同名文件
if (!assetsNameHash.Add(assetItem.TypeString + assetItem.Text))
{
assetItem.Text += assetItem.UniqueID;
}
//处理非法文件名
assetItem.Text = FixFileName(assetItem.Text);
if (Properties.Settings.Default.displayAll || exportable) if (Properties.Settings.Default.displayAll || exportable)
{ {
tempExportableAssets.Add(assetItem); tempExportableAssets.Add(assetItem);
@ -221,7 +223,6 @@ namespace AssetStudioGUI
containers?.Clear(); containers?.Clear();
} }
visibleAssets = exportableAssets; visibleAssets = exportableAssets;
assetsNameHash.Clear();
StatusStripUpdate("Building tree structure..."); StatusStripUpdate("Building tree structure...");
@ -337,12 +338,6 @@ namespace AssetStudioGUI
return typeMap; return typeMap;
} }
public static string FixFileName(string str)
{
if (str.Length >= 260) return Path.GetRandomFileName();
return Path.GetInvalidFileNameChars().Aggregate(str, (current, c) => current.Replace(c, '_'));
}
public static void ExportAssets(string savePath, List<AssetItem> toExportAssets, ExportType exportType) public static void ExportAssets(string savePath, List<AssetItem> toExportAssets, ExportType exportType)
{ {
ThreadPool.QueueUserWorkItem(state => ThreadPool.QueueUserWorkItem(state =>