From 850ba63a10d7f324289d5dd54b9daffd9cf3c64b Mon Sep 17 00:00:00 2001 From: Perfare Date: Fri, 2 Jul 2021 03:26:46 +0800 Subject: [PATCH] support exporting VideoClips with a size above 2gb. close #765 --- AssetStudio/Classes/AudioClip.cs | 10 +++---- AssetStudio/Classes/Mesh.cs | 2 +- AssetStudio/Classes/Texture2D.cs | 6 ++--- AssetStudio/Classes/VideoClip.cs | 12 ++++----- AssetStudio/FileReader.cs | 2 +- AssetStudio/ResourceReader.cs | 46 ++++++++++++++++++++------------ AssetStudioGUI/Exporter.cs | 5 ++-- 7 files changed, 47 insertions(+), 36 deletions(-) diff --git a/AssetStudio/Classes/AudioClip.cs b/AssetStudio/Classes/AudioClip.cs index d4c8429..4dcf268 100644 --- a/AssetStudio/Classes/AudioClip.cs +++ b/AssetStudio/Classes/AudioClip.cs @@ -27,8 +27,8 @@ namespace AssetStudio public AudioCompressionFormat m_CompressionFormat; public string m_Source; - public ulong m_Offset; - public long m_Size; + public long m_Offset; //ulong + public long m_Size; //ulong public ResourceReader m_AudioData; public AudioClip(ObjectReader reader) : base(reader) @@ -74,7 +74,7 @@ namespace AssetStudio //StreamedResource m_Resource m_Source = reader.ReadAlignedString(); - m_Offset = reader.ReadUInt64(); + m_Offset = reader.ReadInt64(); m_Size = reader.ReadInt64(); m_CompressionFormat = (AudioCompressionFormat)reader.ReadInt32(); } @@ -82,11 +82,11 @@ namespace AssetStudio ResourceReader resourceReader; if (!string.IsNullOrEmpty(m_Source)) { - resourceReader = new ResourceReader(m_Source, assetsFile, m_Offset, (int)m_Size); + resourceReader = new ResourceReader(m_Source, assetsFile, m_Offset, m_Size); } else { - resourceReader = new ResourceReader(reader, reader.BaseStream.Position, (int)m_Size); + resourceReader = new ResourceReader(reader, reader.BaseStream.Position, m_Size); } m_AudioData = resourceReader; } diff --git a/AssetStudio/Classes/Mesh.cs b/AssetStudio/Classes/Mesh.cs index 962cca6..0945f43 100644 --- a/AssetStudio/Classes/Mesh.cs +++ b/AssetStudio/Classes/Mesh.cs @@ -681,7 +681,7 @@ namespace AssetStudio { if (m_VertexData.m_VertexCount > 0) { - var resourceReader = new ResourceReader(m_StreamData.path, assetsFile, m_StreamData.offset, (int)m_StreamData.size); + var resourceReader = new ResourceReader(m_StreamData.path, assetsFile, m_StreamData.offset, m_StreamData.size); m_VertexData.m_DataSize = resourceReader.GetData(); } } diff --git a/AssetStudio/Classes/Texture2D.cs b/AssetStudio/Classes/Texture2D.cs index f0b4b13..45ff7ed 100644 --- a/AssetStudio/Classes/Texture2D.cs +++ b/AssetStudio/Classes/Texture2D.cs @@ -4,7 +4,7 @@ namespace AssetStudio { public class StreamingInfo { - public ulong offset; + public long offset; //ulong public uint size; public string path; @@ -14,7 +14,7 @@ namespace AssetStudio if (version[0] >= 2020) //2020.1 and up { - offset = reader.ReadUInt64(); + offset = reader.ReadInt64(); } else { @@ -134,7 +134,7 @@ namespace AssetStudio ResourceReader resourceReader; if (!string.IsNullOrEmpty(m_StreamData?.path)) { - resourceReader = new ResourceReader(m_StreamData.path, assetsFile, m_StreamData.offset, (int)m_StreamData.size); + resourceReader = new ResourceReader(m_StreamData.path, assetsFile, m_StreamData.offset, m_StreamData.size); } else { diff --git a/AssetStudio/Classes/VideoClip.cs b/AssetStudio/Classes/VideoClip.cs index 974fc05..730edfd 100644 --- a/AssetStudio/Classes/VideoClip.cs +++ b/AssetStudio/Classes/VideoClip.cs @@ -5,14 +5,14 @@ namespace AssetStudio public class StreamedResource { public string m_Source; - public ulong m_Offset; - public ulong m_Size; + public long m_Offset; //ulong + public long m_Size; //ulong public StreamedResource(BinaryReader reader) { m_Source = reader.ReadAlignedString(); - m_Offset = reader.ReadUInt64(); - m_Size = reader.ReadUInt64(); + m_Offset = reader.ReadInt64(); + m_Size = reader.ReadInt64(); } } @@ -60,11 +60,11 @@ namespace AssetStudio ResourceReader resourceReader; if (!string.IsNullOrEmpty(m_ExternalResources.m_Source)) { - resourceReader = new ResourceReader(m_ExternalResources.m_Source, assetsFile, m_ExternalResources.m_Offset, (int)m_ExternalResources.m_Size); + resourceReader = new ResourceReader(m_ExternalResources.m_Source, assetsFile, m_ExternalResources.m_Offset, m_ExternalResources.m_Size); } else { - resourceReader = new ResourceReader(reader, reader.BaseStream.Position, (int)m_ExternalResources.m_Size); + resourceReader = new ResourceReader(reader, reader.BaseStream.Position, m_ExternalResources.m_Size); } m_VideoData = resourceReader; } diff --git a/AssetStudio/FileReader.cs b/AssetStudio/FileReader.cs index f801890..b5b7c7b 100644 --- a/AssetStudio/FileReader.cs +++ b/AssetStudio/FileReader.cs @@ -58,7 +58,7 @@ namespace AssetStudio } } - public bool IsSerializedFile() + private bool IsSerializedFile() { var fileSize = BaseStream.Length; if (fileSize < 20) diff --git a/AssetStudio/ResourceReader.cs b/AssetStudio/ResourceReader.cs index 2e02030..fc294cd 100644 --- a/AssetStudio/ResourceReader.cs +++ b/AssetStudio/ResourceReader.cs @@ -8,41 +8,37 @@ namespace AssetStudio private string path; private SerializedFile assetsFile; private long offset; - private int size; + private long size; private BinaryReader reader; - - public ResourceReader(string path, SerializedFile assetsFile, ulong offset, int size) + public ResourceReader(string path, SerializedFile assetsFile, long offset, long size) { needSearch = true; this.path = path; this.assetsFile = assetsFile; - this.offset = (long)offset; + this.offset = offset; this.size = size; } - public ResourceReader(BinaryReader reader, long offset, int size) + public ResourceReader(BinaryReader reader, long offset, long size) { this.reader = reader; this.offset = offset; this.size = size; } - public byte[] GetData() + private BinaryReader GetReader() { if (needSearch) { var resourceFileName = Path.GetFileName(path); - if (assetsFile.assetsManager.resourceFileReaders.TryGetValue(resourceFileName, out reader)) { needSearch = false; - reader.BaseStream.Position = offset; - return reader.ReadBytes(size); + return reader; } - var assetsFileDirectory = Path.GetDirectoryName(assetsFile.fullName); - var resourceFilePath = assetsFileDirectory + Path.DirectorySeparatorChar + resourceFileName; + var resourceFilePath = Path.Combine(assetsFileDirectory, resourceFileName); if (!File.Exists(resourceFilePath)) { var findFiles = Directory.GetFiles(assetsFileDirectory, resourceFileName, SearchOption.AllDirectories); @@ -53,18 +49,34 @@ namespace AssetStudio } if (File.Exists(resourceFilePath)) { - reader = new BinaryReader(File.OpenRead(resourceFilePath)); needSearch = false; + reader = new BinaryReader(File.OpenRead(resourceFilePath)); assetsFile.assetsManager.resourceFileReaders.Add(resourceFileName, reader); - reader.BaseStream.Position = offset; - return reader.ReadBytes(size); + return reader; } - throw new FileNotFoundException($"Can't find the resource file {resourceFileName}"); } + else + { + return reader; + } + } - reader.BaseStream.Position = offset; - return reader.ReadBytes(size); + public byte[] GetData() + { + var binaryReader = GetReader(); + binaryReader.BaseStream.Position = offset; + return binaryReader.ReadBytes((int)size); + } + + public void WriteData(string path) + { + var binaryReader = GetReader(); + binaryReader.BaseStream.Position = offset; + using (var writer = File.OpenWrite(path)) + { + binaryReader.BaseStream.CopyTo(writer, size); + } } } } diff --git a/AssetStudioGUI/Exporter.cs b/AssetStudioGUI/Exporter.cs index 5e97e4f..c028877 100644 --- a/AssetStudioGUI/Exporter.cs +++ b/AssetStudioGUI/Exporter.cs @@ -205,12 +205,11 @@ namespace AssetStudioGUI public static bool ExportVideoClip(AssetItem item, string exportPath) { var m_VideoClip = (VideoClip)item.Asset; - var m_VideoData = m_VideoClip.m_VideoData.GetData(); - if (m_VideoData != null && m_VideoData.Length != 0) + if (m_VideoClip.m_ExternalResources.m_Size > 0) { if (!TryExportFile(exportPath, item, Path.GetExtension(m_VideoClip.m_OriginalPath), out var exportFullPath)) return false; - File.WriteAllBytes(exportFullPath, m_VideoData); + m_VideoClip.m_VideoData.WriteData(exportFullPath); return true; } return false;