diff --git a/AssetStudio/AssetsManager.cs b/AssetStudio/AssetsManager.cs index 4c25ab0..1105a9b 100644 --- a/AssetStudio/AssetsManager.cs +++ b/AssetStudio/AssetsManager.cs @@ -86,7 +86,7 @@ namespace AssetStudio 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; if (!importFilesHash.Contains(sharedFileName)) @@ -189,7 +189,7 @@ namespace AssetStudio var webFile = new WebFile(reader); 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)) { case FileType.AssetsFile: diff --git a/AssetStudio/ImportHelper.cs b/AssetStudio/ImportHelper.cs index 9de002a..5444e62 100644 --- a/AssetStudio/ImportHelper.cs +++ b/AssetStudio/ImportHelper.cs @@ -20,8 +20,8 @@ namespace AssetStudio foreach (var splitFile in splitFiles) { var destFile = Path.GetFileNameWithoutExtension(splitFile); - var destPath = Path.GetDirectoryName(splitFile) + "\\"; - var destFull = destPath + destFile; + var destPath = Path.GetDirectoryName(splitFile); + var destFull = Path.Combine(destPath, destFile); if (!File.Exists(destFull)) { var splitParts = Directory.GetFiles(destPath, destFile + ".split*"); @@ -43,7 +43,7 @@ namespace AssetStudio public static string[] ProcessingSplitFiles(List selectFile) { 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() .ToList(); selectFile.RemoveAll(x => x.Contains(".split")); diff --git a/AssetStudioGUI/AssetStudioGUIForm.cs b/AssetStudioGUI/AssetStudioGUIForm.cs index c5391c8..5d3e170 100644 --- a/AssetStudioGUI/AssetStudioGUIForm.cs +++ b/AssetStudioGUI/AssetStudioGUIForm.cs @@ -332,7 +332,7 @@ namespace AssetStudioGUI Progress.Reset(); foreach (TypeTreeItem item in classesListView.Items) { - var versionPath = savePath + "\\" + item.Group.Header; + var versionPath = Path.Combine(savePath, item.Group.Header); Directory.CreateDirectory(versionPath); var saveFile = $"{versionPath}\\{item.SubItems[1].Text} {item.Text}.txt"; @@ -1422,7 +1422,7 @@ namespace AssetStudioGUI var saveFolderDialog1 = new OpenFolderDialog(); if (saveFolderDialog1.ShowDialog(this) == DialogResult.OK) { - var savePath = saveFolderDialog1.Folder + "\\"; + var savePath = saveFolderDialog1.Folder + Path.DirectorySeparatorChar; ExportSplitObjects(savePath, sceneTreeView.Nodes); } } diff --git a/AssetStudioGUI/Exporter.cs b/AssetStudioGUI/Exporter.cs index 4926b6f..a2e6ad9 100644 --- a/AssetStudioGUI/Exporter.cs +++ b/AssetStudioGUI/Exporter.cs @@ -10,7 +10,7 @@ namespace AssetStudioGUI { 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; if (Properties.Settings.Default.convertTexture) @@ -36,25 +36,25 @@ namespace AssetStudioGUI tga = true; break; } - var exportFullName = exportPathName + item.Text + "." + ext.ToLower(); - if (ExportFileExists(exportFullName)) + if (!TryExportFile(exportPath, item, "." + ext.ToLower(), out var exportFullPath)) return false; if (tga) { var file = new TGA(bitmap); - file.Save(exportFullName); + file.Save(exportFullPath); } else - bitmap.Save(exportFullName, format); + { + bitmap.Save(exportFullPath, format); + } bitmap.Dispose(); return true; } else { - var exportFullName = exportPathName + item.Text + ".tex"; - if (ExportFileExists(exportFullName)) + if (!TryExportFile(exportPath, item, ".tex", out var exportFullPath)) return false; - File.WriteAllBytes(exportFullName, m_Texture2D.image_data.GetData()); + File.WriteAllBytes(exportFullPath, m_Texture2D.image_data.GetData()); return true; } } @@ -68,28 +68,25 @@ namespace AssetStudioGUI var converter = new AudioClipConverter(m_AudioClip); if (Properties.Settings.Default.convertAudio && converter.IsSupport) { - var exportFullName = exportPath + item.Text + ".wav"; - if (ExportFileExists(exportFullName)) + if (!TryExportFile(exportPath, item, ".wav", out var exportFullPath)) return false; var buffer = converter.ConvertToWav(); if (buffer == null) return false; - File.WriteAllBytes(exportFullName, buffer); + File.WriteAllBytes(exportFullPath, buffer); } else { - var exportFullName = exportPath + item.Text + converter.GetExtensionName(); - if (ExportFileExists(exportFullName)) + if (!TryExportFile(exportPath, item, converter.GetExtensionName(), out var exportFullPath)) return false; - File.WriteAllBytes(exportFullName, m_AudioData); + File.WriteAllBytes(exportFullPath, m_AudioData); } return true; } public static bool ExportShader(AssetItem item, string exportPath) { - var exportFullName = exportPath + item.Text + ".shader"; - if (ExportFileExists(exportFullName)) + if (!TryExportFile(exportPath, item, ".shader", out var exportFullPath)) return false; var m_Shader = (Shader)item.Asset; if (m_Shader.compressedBlob != null) //5.5 and up @@ -104,7 +101,7 @@ namespace AssetStudioGUI else { var str = ShaderConverter.Convert(m_Shader); - File.WriteAllText(exportFullName, str); + File.WriteAllText(exportFullPath, str); } return true; } @@ -120,21 +117,19 @@ namespace AssetStudioGUI extension = Path.GetExtension(item.Container); } } - var exportFullName = exportPath + item.Text + extension; - if (ExportFileExists(exportFullName)) + if (!TryExportFile(exportPath, item, extension, out var exportFullPath)) return false; - File.WriteAllBytes(exportFullName, m_TextAsset.m_Script); + File.WriteAllBytes(exportFullPath, m_TextAsset.m_Script); return true; } public static bool ExportMonoBehaviour(AssetItem item, string exportPath) { - var exportFullName = exportPath + item.Text + ".txt"; - if (ExportFileExists(exportFullName)) + if (!TryExportFile(exportPath, item, ".txt", out var exportFullPath)) return false; var m_MonoBehaviour = (MonoBehaviour)item.Asset; var str = m_MonoBehaviour.Dump() ?? Studio.GetScriptString(item.Asset.reader); - File.WriteAllText(exportFullName, str); + File.WriteAllText(exportFullPath, str); return true; } @@ -148,10 +143,9 @@ namespace AssetStudioGUI { extension = ".otf"; } - var exportFullName = exportPath + item.Text + extension; - if (ExportFileExists(exportFullName)) + if (!TryExportFile(exportPath, item, extension, out var exportFullPath)) return false; - File.WriteAllBytes(exportFullName, m_Font.m_FontData); + File.WriteAllBytes(exportFullPath, m_Font.m_FontData); return true; } return false; @@ -162,8 +156,7 @@ namespace AssetStudioGUI var m_Mesh = (Mesh)item.Asset; if (m_Mesh.m_VertexCount <= 0) return false; - var exportFullName = exportPath + item.Text + ".obj"; - if (ExportFileExists(exportFullName)) + if (!TryExportFile(exportPath, item, ".obj", out var exportFullPath)) return false; var sb = new StringBuilder(); sb.AppendLine("g " + m_Mesh.m_Name); @@ -235,7 +228,7 @@ namespace AssetStudioGUI #endregion sb.Replace("NaN", "0"); - File.WriteAllText(exportFullName, sb.ToString()); + File.WriteAllText(exportFullPath, sb.ToString()); return true; } @@ -245,10 +238,9 @@ namespace AssetStudioGUI var m_VideoData = m_VideoClip.m_VideoData.GetData(); if (m_VideoData != null && m_VideoData.Length != 0) { - var exportFullName = exportPath + item.Text + Path.GetExtension(m_VideoClip.m_OriginalPath); - if (ExportFileExists(exportFullName)) + if (!TryExportFile(exportPath, item, Path.GetExtension(m_VideoClip.m_OriginalPath), out var exportFullPath)) return false; - File.WriteAllBytes(exportFullName, m_VideoData); + File.WriteAllBytes(exportFullPath, m_VideoData); return true; } return false; @@ -257,10 +249,9 @@ namespace AssetStudioGUI public static bool ExportMovieTexture(AssetItem item, string exportPath) { var m_MovieTexture = (MovieTexture)item.Asset; - var exportFullName = exportPath + item.Text + ".ogv"; - if (ExportFileExists(exportFullName)) + if (!TryExportFile(exportPath, item, ".ogv", out var exportFullPath)) return false; - File.WriteAllBytes(exportFullName, m_MovieTexture.m_MovieData); + File.WriteAllBytes(exportFullPath, m_MovieTexture.m_MovieData); return true; } @@ -284,8 +275,7 @@ namespace AssetStudioGUI tga = true; break; } - var exportFullName = exportPath + item.Text + "." + type.ToLower(); - if (ExportFileExists(exportFullName)) + if (!TryExportFile(exportPath, item, "." + type.ToLower(), out var exportFullPath)) return false; var bitmap = ((Sprite)item.Asset).GetImage(); if (bitmap != null) @@ -293,10 +283,12 @@ namespace AssetStudioGUI if (tga) { var file = new TGA(bitmap); - file.Save(exportFullName); + file.Save(exportFullPath); } else - bitmap.Save(exportFullName, format); + { + bitmap.Save(exportFullPath, format); + } bitmap.Dispose(); return true; } @@ -305,36 +297,47 @@ namespace AssetStudioGUI public static bool ExportRawFile(AssetItem item, string exportPath) { - var exportFullName = exportPath + item.Text + ".dat"; - if (ExportFileExists(exportFullName)) + if (!TryExportFile(exportPath, item, ".dat", out var exportFullPath)) return false; - File.WriteAllBytes(exportFullName, item.Asset.GetRawData()); + File.WriteAllBytes(exportFullPath, item.Asset.GetRawData()); 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; } - Directory.CreateDirectory(Path.GetDirectoryName(filename)); return false; } public static bool ExportAnimator(AssetItem item, string exportPath, List 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 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, exportPath); + ExportFbx(convert, exportFullPath); return true; } public static void ExportGameObject(GameObject gameObject, string exportPath, List animationList = null) { 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); } @@ -364,13 +367,12 @@ namespace AssetStudioGUI public static bool ExportDumpFile(AssetItem item, string exportPath) { - var exportFullName = exportPath + item.Text + ".txt"; - if (ExportFileExists(exportFullName)) + if (!TryExportFile(exportPath, item, ".txt", out var exportFullPath)) return false; var str = item.Asset.Dump(); if (str != null) { - File.WriteAllText(exportFullName, str); + File.WriteAllText(exportFullPath, str); return true; } return false; @@ -408,5 +410,11 @@ namespace AssetStudioGUI 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, '_')); + } } } diff --git a/AssetStudioGUI/Studio.cs b/AssetStudioGUI/Studio.cs index af3f2a9..6992399 100644 --- a/AssetStudioGUI/Studio.cs +++ b/AssetStudioGUI/Studio.cs @@ -101,7 +101,6 @@ namespace AssetStudioGUI StatusStripUpdate("Building asset list..."); string productName = null; - var assetsNameHash = new HashSet(StringComparer.OrdinalIgnoreCase); var objectCount = assetsManager.assetsFileList.Sum(x => x.Objects.Count); var objectAssetItemDic = new Dictionary(objectCount); int i = 0; @@ -177,7 +176,17 @@ namespace AssetStudioGUI containers = new Dictionary(); 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; break; @@ -189,13 +198,6 @@ namespace AssetStudioGUI { 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) { tempExportableAssets.Add(assetItem); @@ -221,7 +223,6 @@ namespace AssetStudioGUI containers?.Clear(); } visibleAssets = exportableAssets; - assetsNameHash.Clear(); StatusStripUpdate("Building tree structure..."); @@ -337,12 +338,6 @@ namespace AssetStudioGUI 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 toExportAssets, ExportType exportType) { ThreadPool.QueueUserWorkItem(state =>