20 Commits

Author SHA1 Message Date
VaDiM
d07fc6d6f5 Fix for avg sprites 2025-04-07 16:03:20 +03:00
VaDiM
ee2976aaf1 Update version & dependencies 2025-04-07 13:32:17 +03:00
VaDiM
f144037bc0 Fix for new compression type 2025-04-07 13:23:04 +03:00
VaDiM
0e097bda04 Update README.md 2024-05-01 14:25:55 +03:00
VaDiM
9686eee3b7 Fix for 512x512 avg sprites
temporarily?
2024-04-11 22:30:42 +03:00
VaDiM
b6318e6d9b Fix for empty alpha tex 2024-01-09 11:18:06 +03:00
VaDiM
e0d90d1b1e Update AssetStudioGUI.csproj 2023-12-16 23:17:56 +03:00
VaDiM
dd727758a8 Update ver to v1.1.0 2023-12-16 23:11:27 +03:00
VaDiM
d44ed315e3 Merge branch 'AssetStudioMod' into ArknightsStudio 2023-12-16 22:57:32 +03:00
VaDiM
e30b9e9e89 Fix bug with some avg sprites
- Changed face sprite detection method. We can't rely on the "IsWholeBody" flag
2023-11-08 13:57:57 +03:00
VaDiM
9632e88115 Update version to v1.0.1 2023-11-01 06:49:36 +03:00
VaDiM
bb19dd5019 Add support for avg sprite without separate alpha tex 2023-11-01 06:49:36 +03:00
VaDiM
b6c6ceba1c Update CHANGELOG.md 2023-09-24 15:41:47 +03:00
VaDiM
7c0a6375b1 Update readme files 2023-09-24 15:41:21 +03:00
VaDiM
5c489c5f83 Merge branch 'AssetStudioMod' into ArknightsStudio 2023-09-24 15:40:23 +03:00
VaDiM
e90af43459 Merge branch 'AssetStudioMod' into ArknightsStudio 2023-08-28 02:28:14 +03:00
VaDiM
381a7d89ae [AK][CLI] Add support for portrait sprites 2023-08-25 01:15:46 +03:00
VaDiM
572e3bf0d6 [AK][GUI] Add support for portrait sprites 2023-08-24 05:50:50 +03:00
VaDiM
3d7d51b54f [AK][CLI] Add support for sprites with an external alpha texture
- Added support for Arknights chararts sprites
- Added support for Arknights avg sprites
2023-08-17 01:22:16 +03:00
VaDiM
abbd27fde7 [AK][GUI] Add support for sprites with an external alpha texture
- Added support for Arknights chararts sprites
- Added support for Arknights avg sprites
2023-08-14 20:25:48 +03:00
222 changed files with 8029 additions and 15079 deletions

View File

@@ -1,9 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net472;net8.0;net8.0-windows;net9.0;net9.0-windows</TargetFrameworks>
<TargetFrameworks>net472;net6.0;net6.0-windows;net7.0;net7.0-windows;net8.0;net8.0-windows</TargetFrameworks>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Version>0.19.0.0</Version>
<Version>1.2.0</Version>
<Copyright>Copyright © Perfare 2020-2022; Copyright © hozuki 2020</Copyright>
<DebugType>embedded</DebugType>
</PropertyGroup>

View File

@@ -11,7 +11,7 @@ namespace AssetStudio.PInvoke
{
public static void PreloadDll(string dllName)
{
var localPath = Process.GetCurrentProcess().MainModule?.FileName;
var localPath = Process.GetCurrentProcess().MainModule.FileName;
var localDir = Path.GetDirectoryName(localPath);
// Not using OperatingSystem.Platform.
@@ -35,6 +35,7 @@ namespace AssetStudio.PInvoke
private static class Win32
{
internal static void LoadDll(string dllDir, string dllName)
{
var dllFileName = $"{dllName}.dll";

View File

@@ -22,26 +22,26 @@ namespace SevenZip
}
}
private uint _value = 0xFFFFFFFF;
uint _value = 0xFFFFFFFF;
public void Init() { _value = 0xFFFFFFFF; }
public void UpdateByte(byte b)
{
_value = Table[(byte)_value ^ b] ^ (_value >> 8);
_value = Table[(((byte)(_value)) ^ b)] ^ (_value >> 8);
}
public void Update(byte[] data, uint offset, uint size)
{
for (uint i = 0; i < size; i++)
_value = Table[(byte)_value ^ data[offset + i]] ^ (_value >> 8);
_value = Table[(((byte)(_value)) ^ data[offset + i])] ^ (_value >> 8);
}
public uint GetDigest() { return _value ^ 0xFFFFFFFF; }
public static uint CalculateDigest(byte[] data, uint offset, uint size)
static uint CalculateDigest(byte[] data, uint offset, uint size)
{
var crc = new CRC();
CRC crc = new CRC();
// crc.Init();
crc.Update(data, offset, size);
return crc.GetDigest();
@@ -49,7 +49,7 @@ namespace SevenZip
static bool VerifyDigest(uint digest, byte[] data, uint offset, uint size)
{
return CalculateDigest(data, offset, size) == digest;
return (CalculateDigest(data, offset, size) == digest);
}
}
}

View File

@@ -1,7 +1,6 @@
// LzmaDecoder.cs
using System;
using AssetStudio;
namespace SevenZip.Compression.LZMA
{
@@ -248,8 +247,6 @@ namespace SevenZip.Compression.LZMA
m_OutWindow.PutByte(b);
nowPos64++;
}
Progress.Reset();
while (nowPos64 < outSize64)
{
// UInt64 next = Math.Min(nowPos64 + (1 << 18), outSize64);
@@ -341,8 +338,6 @@ namespace SevenZip.Compression.LZMA
}
m_OutWindow.CopyBlock(rep0, len);
nowPos64 += len;
Progress.Report((int)(nowPos64 * 100f / outSize64), 100);
}
}
}

View File

@@ -1,23 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net472;net8.0;net8.0-windows;net9.0;net9.0-windows</TargetFrameworks>
<Version>0.19.0.0</Version>
<Copyright>Copyright © Perfare 2018-2022; Copyright © aelurum 2021-2025</Copyright>
<TargetFrameworks>net472;net6.0;net6.0-windows;net7.0;net7.0-windows;net8.0;net8.0-windows</TargetFrameworks>
<Version>1.2.0</Version>
<Copyright>Copyright © Perfare 2018-2022; Copyright © aelurum 2025</Copyright>
<DebugType>embedded</DebugType>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="ZstdSharp.Port" Version="0.8.6" />
<PackageReference Include="K4os.Compression.LZ4" Version="1.3.8" />
<PackageReference Include="K4os.Compression.LZ4" Version="1.3.8" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'net472' ">
<PackageReference Include="System.Memory" Version="4.5.5" />
<PackageReference Include="System.IO.Compression" Version="4.3.0" />
<PackageReference Include="System.Text.Json" Version="9.0.8" />
<PackageReference Include="Microsoft.Bcl.Numerics" Version="9.0.8" />
<ProjectReference Include="..\AssetStudio.PInvoke\AssetStudio.PInvoke.csproj" />
</ItemGroup>
</Project>

View File

@@ -1,78 +1,53 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Text;
using System.Text.Json.Serialization;
using System.Text.Json;
using AssetStudio.CustomOptions;
using AssetStudio.CustomOptions.Asmo;
using static AssetStudio.ImportHelper;
namespace AssetStudio
{
public class AssetsManager
{
public bool LoadViaTypeTree = true;
public bool MeshLazyLoad = true;
public ImportOptions Options = new ImportOptions();
public readonly List<Action<OptionsFile>> OptionLoaders = new List<Action<OptionsFile>>();
public readonly List<SerializedFile> AssetsFileList = new List<SerializedFile>();
public string SpecifyUnityVersion;
public List<SerializedFile> assetsFileList = new List<SerializedFile>();
private HashSet<ClassIDType> filteredAssetTypesList = new HashSet<ClassIDType>();
internal Dictionary<string, int> assetsFileIndexCache = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase);
internal ConcurrentDictionary<string, BinaryReader> resourceFileReaders = new ConcurrentDictionary<string, BinaryReader>(StringComparer.OrdinalIgnoreCase);
internal Dictionary<string, BinaryReader> resourceFileReaders = new Dictionary<string, BinaryReader>(StringComparer.OrdinalIgnoreCase);
private readonly List<string> importFiles = new List<string>();
private readonly HashSet<ClassIDType> filteredAssetTypesList = new HashSet<ClassIDType>();
private readonly HashSet<string> importFilesHash = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
private readonly HashSet<string> noexistFiles = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
private readonly HashSet<string> assetsFileListHash = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
public AssetsManager()
{
OptionLoaders.Add(LoadImportOptions);
}
private List<string> importFiles = new List<string>();
private HashSet<string> importFilesHash = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
private HashSet<string> noexistFiles = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
private HashSet<string> assetsFileListHash = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
public void SetAssetFilter(params ClassIDType[] classIDTypes)
{
filteredAssetTypesList.UnionWith(new[]
if (filteredAssetTypesList.Count == 0)
{
ClassIDType.AssetBundle,
ClassIDType.ResourceManager,
ClassIDType.GameObject,
ClassIDType.Transform,
ClassIDType.RectTransform,
});
filteredAssetTypesList.UnionWith(new HashSet<ClassIDType>
{
ClassIDType.AssetBundle,
ClassIDType.ResourceManager,
});
}
if (classIDTypes.Contains(ClassIDType.MonoBehaviour))
{
filteredAssetTypesList.Add(ClassIDType.MonoScript);
}
if (classIDTypes.Contains(ClassIDType.Sprite))
if (classIDTypes.Contains(ClassIDType.Sprite) || classIDTypes.Contains(ClassIDType.AkPortraitSprite))
{
filteredAssetTypesList.Add(ClassIDType.Texture2D);
filteredAssetTypesList.Add(ClassIDType.SpriteAtlas);
filteredAssetTypesList.UnionWith(new HashSet<ClassIDType>
{
ClassIDType.Texture2D,
ClassIDType.SpriteAtlas,
ClassIDType.MonoBehaviour,
ClassIDType.MonoScript
});
}
if (classIDTypes.Contains(ClassIDType.Animator))
{
filteredAssetTypesList.Add(ClassIDType.AnimatorController);
filteredAssetTypesList.Add(ClassIDType.AnimatorOverrideController);
filteredAssetTypesList.Add(ClassIDType.Animation);
filteredAssetTypesList.Add(ClassIDType.AnimationClip);
filteredAssetTypesList.Add(ClassIDType.Avatar);
filteredAssetTypesList.Add(ClassIDType.Material);
filteredAssetTypesList.Add(ClassIDType.MeshFilter);
filteredAssetTypesList.Add(ClassIDType.MeshRenderer);
filteredAssetTypesList.Add(ClassIDType.SkinnedMeshRenderer);
}
if (classIDTypes.Contains(ClassIDType.AnimatorController))
{
filteredAssetTypesList.Add(ClassIDType.Animator);
filteredAssetTypesList.Add(ClassIDType.AnimatorOverrideController);
}
filteredAssetTypesList.UnionWith(classIDTypes);
}
@@ -81,28 +56,32 @@ namespace AssetStudio
SetAssetFilter(classIDTypeList.ToArray());
}
public void LoadFilesAndFolders(params string[] paths)
public void LoadFilesAndFolders(params string[] path)
{
LoadFilesAndFolders(out _, paths.ToList());
List<string> pathList = new List<string>();
pathList.AddRange(path);
LoadFilesAndFolders(out _, pathList);
}
public void LoadFilesAndFolders(out string parentPath, params string[] paths)
public void LoadFilesAndFolders(out string parentPath, params string[] path)
{
LoadFilesAndFolders(out parentPath, paths.ToList());
List<string> pathList = new List<string>();
pathList.AddRange(path);
LoadFilesAndFolders(out parentPath, pathList);
}
public void LoadFilesAndFolders(out string parentPath, List<string> pathList)
{
var fileList = new List<string>();
var filesInPath = false;
List<string> fileList = new List<string>();
bool filesInPath = false;
parentPath = "";
foreach (var path in pathList)
{
var fullPath = Path.GetFullPath(path);
if (Directory.Exists(fullPath))
{
var parent = Directory.GetParent(fullPath)?.FullName;
if (!filesInPath && (parentPath == "" || parentPath?.Length > parent?.Length))
var parent = Directory.GetParent(fullPath).FullName;
if (!filesInPath && (parentPath == "" || parentPath.Length > parent.Length))
{
parentPath = parent;
}
@@ -120,8 +99,6 @@ namespace AssetStudio
{
MergeSplitAssets(parentPath);
}
LoadOptionFiles(fileList);
var toReadFile = ProcessingSplitFiles(fileList);
fileList.Clear();
pathList.Clear();
@@ -141,44 +118,35 @@ namespace AssetStudio
//use a for loop because list size can change
for (var i = 0; i < importFiles.Count; i++)
{
if (LoadFile(importFiles[i]))
{
Progress.Report(i + 1, importFiles.Count);
}
else
{
break;
}
LoadFile(importFiles[i]);
Progress.Report(i + 1, importFiles.Count);
}
importFiles.Clear();
importFilesHash.Clear();
noexistFiles.Clear();
assetsFileListHash.Clear();
if (AssetsFileList.Count == 0)
return;
ReadAssets();
ProcessAssets();
}
private bool LoadFile(string fullName)
private void LoadFile(string fullName)
{
var reader = new FileReader(fullName);
return LoadFile(reader);
LoadFile(reader);
}
private bool LoadFile(FileReader reader, bool fromZip = false)
private void LoadFile(FileReader reader)
{
if (reader == null)
return false;
switch (reader.FileType)
switch (reader?.FileType)
{
case FileType.AssetsFile:
return LoadAssetsFile(reader, fromZip);
LoadAssetsFile(reader);
break;
case FileType.BundleFile:
return LoadBundleFile(reader);
LoadBundleFile(reader);
break;
case FileType.WebFile:
LoadWebFile(reader);
break;
@@ -191,27 +159,20 @@ namespace AssetStudio
case FileType.ZipFile:
LoadZipFile(reader);
break;
case FileType.ResourceFile when !fromZip:
reader.Dispose();
break;
}
return true;
}
private bool LoadAssetsFile(FileReader reader, bool fromZip)
private void LoadAssetsFile(FileReader reader)
{
if (!assetsFileListHash.Contains(reader.FileName))
{
Logger.Info($"Loading \"{reader.FullPath}\"");
Logger.Info($"Loading {reader.FullPath}");
try
{
var assetsFile = new SerializedFile(reader, this);
var dirName = Path.GetDirectoryName(reader.FullPath);
CheckStrippedVersion(assetsFile);
AssetsFileList.Add(assetsFile);
assetsFileList.Add(assetsFile);
assetsFileListHash.Add(assetsFile.fileName);
if (fromZip)
return true;
foreach (var sharedFile in assetsFile.m_Externals)
{
@@ -219,12 +180,12 @@ namespace AssetStudio
if (!importFilesHash.Contains(sharedFileName))
{
var sharedFilePath = Path.Combine(dirName, sharedFileName);
var sharedFilePath = Path.Combine(Path.GetDirectoryName(reader.FullPath), sharedFileName);
if (!noexistFiles.Contains(sharedFilePath))
{
if (!File.Exists(sharedFilePath))
{
var findFiles = Directory.GetFiles(dirName, sharedFileName, SearchOption.AllDirectories);
var findFiles = Directory.GetFiles(Path.GetDirectoryName(reader.FullPath), sharedFileName, SearchOption.AllDirectories);
if (findFiles.Length > 0)
{
sharedFilePath = findFiles[0];
@@ -238,7 +199,6 @@ namespace AssetStudio
else
{
noexistFiles.Add(sharedFilePath);
Logger.Warning($"Dependency wasn't found: {sharedFilePath}");
}
}
}
@@ -248,23 +208,21 @@ namespace AssetStudio
{
Logger.Error(e.Message);
reader.Dispose();
return false;
}
catch (Exception e)
{
Logger.Warning($"Failed to read assets file \"{reader.FullPath}\"\n{e}");
Logger.Warning($"Error while reading assets file {reader.FullPath}\r\n{e}");
reader.Dispose();
}
}
else
{
Logger.Info($"Skipping \"{reader.FullPath}\"");
Logger.Info($"Skipping {reader.FullPath}");
reader.Dispose();
}
return true;
}
private bool LoadAssetsFromMemory(FileReader reader, string originalPath, UnityVersion assetBundleUnityVer = null)
private void LoadAssetsFromMemory(FileReader reader, string originalPath, string unityVersion = null)
{
if (!assetsFileListHash.Contains(reader.FileName))
{
@@ -272,117 +230,71 @@ namespace AssetStudio
{
var assetsFile = new SerializedFile(reader, this);
assetsFile.originalPath = originalPath;
if (assetBundleUnityVer != null && assetsFile.header.m_Version < SerializedFileFormatVersion.Unknown_7)
if (!string.IsNullOrEmpty(unityVersion) && assetsFile.header.m_Version < SerializedFileFormatVersion.Unknown_7)
{
assetsFile.version = assetBundleUnityVer;
assetsFile.SetVersion(unityVersion);
}
CheckStrippedVersion(assetsFile, assetBundleUnityVer);
AssetsFileList.Add(assetsFile);
CheckStrippedVersion(assetsFile);
assetsFileList.Add(assetsFile);
assetsFileListHash.Add(assetsFile.fileName);
}
catch (NotSupportedException e)
{
Logger.Error(e.Message);
reader.Dispose();
return false;
resourceFileReaders.Add(reader.FileName, reader);
}
catch (Exception e)
{
Logger.Warning($"Failed to read assets file \"{reader.FullPath}\" from {Path.GetFileName(originalPath)}\n{e}");
resourceFileReaders.TryAdd(reader.FileName, reader);
Logger.Warning($"Error while reading assets file {reader.FullPath} from {Path.GetFileName(originalPath)}\r\n{e}");
resourceFileReaders.Add(reader.FileName, reader);
}
}
else
{
Logger.Info($"Skipping \"{originalPath}\" ({reader.FileName})");
}
return true;
Logger.Info($"Skipping {originalPath} ({reader.FileName})");
}
private bool LoadBundleFile(FileReader reader, string originalPath = null)
private void LoadBundleFile(FileReader reader, string originalPath = null)
{
Logger.Info($"Loading \"{reader.FullPath}\"");
Logger.Debug($"Bundle offset: {reader.Position}");
var bundleStream = new OffsetStream(reader);
var bundleReader = new FileReader(reader.FullPath, bundleStream);
var isLoaded = false;
Logger.Info("Loading " + reader.FullPath);
try
{
var bundleFile = new BundleFile(bundleReader, Options.BundleOptions);
isLoaded = LoadBundleFiles(bundleReader, bundleFile, originalPath);
if (!isLoaded)
return false;
while (bundleFile.IsDataAfterBundle && isLoaded)
var bundleFile = new BundleFile(reader, SpecifyUnityVersion);
foreach (var file in bundleFile.fileList)
{
isLoaded = false;
bundleStream.Offset = reader.Position;
bundleReader = new FileReader($"{reader.FullPath}_0x{bundleStream.Offset:X}", bundleStream);
if (bundleReader.FileType != FileType.BundleFile)
var dummyPath = Path.Combine(Path.GetDirectoryName(reader.FullPath), file.fileName);
var subReader = new FileReader(dummyPath, file.stream);
if (subReader.FileType == FileType.AssetsFile)
{
Logger.Debug("Unknown data was detected after the end of the bundle.");
break;
LoadAssetsFromMemory(subReader, originalPath ?? reader.FullPath, bundleFile.m_Header.unityRevision);
}
if (bundleReader.Position > 0)
else if (!resourceFileReaders.ContainsKey(file.fileName))
{
bundleStream.Offset += bundleReader.Position;
bundleReader.FullPath = $"{reader.FullPath}_0x{bundleStream.Offset:X}";
bundleReader.FileName = $"{reader.FileName}_0x{bundleStream.Offset:X}";
resourceFileReaders.Add(file.fileName, subReader);
}
Logger.Info($"[MultiBundle] Loading \"{reader.FileName}\" from offset: 0x{bundleStream.Offset:X}");
bundleFile = new BundleFile(bundleReader, Options.BundleOptions, isMultiBundle: true);
isLoaded = LoadBundleFiles(bundleReader, bundleFile, originalPath ?? reader.FullPath);
}
return isLoaded;
}
catch (NotSupportedException e)
{
Logger.Error(e.Message);
return false;
}
catch (Exception e)
{
var str = $"Error while reading bundle file \"{bundleReader.FullPath}\"";
var str = $"Error while reading bundle file {reader.FullPath}";
if (originalPath != null)
{
str += $" from {Path.GetFileName(originalPath)}";
}
Logger.Warning($"{str}\n{e}");
return true;
Logger.Warning($"{str}\r\n{e}");
}
finally
{
if (!isLoaded)
bundleReader.Dispose();
reader.Dispose();
}
}
private bool LoadBundleFiles(FileReader reader, BundleFile bundleFile, string originalPath = null)
{
foreach (var file in bundleFile.fileList)
{
if (file.stream == null)
continue;
file.stream.Position = 0; //go to file offset
var dummyPath = Path.Combine(Path.GetDirectoryName(reader.FullPath), file.fileName);
var subReader = new FileReader(dummyPath, file.stream);
if (subReader.FileType == FileType.AssetsFile)
{
if (!LoadAssetsFromMemory(subReader, originalPath ?? reader.FullPath, bundleFile.m_Header.unityRevision))
return false;
}
else
{
resourceFileReaders.TryAdd(file.fileName, subReader);
}
}
return true;
}
private void LoadWebFile(FileReader reader)
{
Logger.Info($"Loading \"{reader.FullPath}\"");
Logger.Info("Loading " + reader.FullPath);
try
{
var webFile = new WebFile(reader);
@@ -402,14 +314,14 @@ namespace AssetStudio
LoadWebFile(subReader);
break;
case FileType.ResourceFile:
resourceFileReaders.TryAdd(file.fileName, subReader);
resourceFileReaders[file.fileName] = subReader; //TODO
break;
}
}
}
catch (Exception e)
{
Logger.Error($"Error while reading web file \"{reader.FullPath}\"", e);
Logger.Error($"Error while reading web file {reader.FullPath}", e);
}
finally
{
@@ -446,16 +358,15 @@ namespace AssetStudio
}
// merge split files and load the result
for (var i = 0; i < splitFiles.Count; i++)
foreach (string basePath in splitFiles)
{
var basePath = splitFiles[i].Replace("\\", "/");
try
{
Stream splitStream = new MemoryStream();
var j = 0;
int i = 0;
while (true)
{
string path = $"{basePath}.split{j++}";
string path = $"{basePath}.split{i++}";
ZipArchiveEntry entry = archive.GetEntry(path);
if (entry == null)
break;
@@ -466,12 +377,11 @@ namespace AssetStudio
}
splitStream.Seek(0, SeekOrigin.Begin);
FileReader entryReader = new FileReader(basePath, splitStream);
if (!LoadFile(entryReader, fromZip: true))
break;
LoadFile(entryReader);
}
catch (Exception e)
{
Logger.Warning($"Error while reading zip split file \"{basePath}\"\n{e}");
Logger.Warning($"Error while reading zip split file {basePath}\r\n{e}");
}
}
@@ -481,8 +391,6 @@ namespace AssetStudio
Progress.Reset();
foreach (ZipArchiveEntry entry in archive.Entries)
{
if (entry.Length == 0)
continue;
try
{
string dummyPath = Path.Combine(Path.GetDirectoryName(reader.FullPath), reader.FileName, entry.FullName);
@@ -497,19 +405,20 @@ namespace AssetStudio
streamReader.Position = 0;
FileReader entryReader = new FileReader(dummyPath, streamReader);
if (!LoadFile(entryReader, fromZip: true))
break;
LoadFile(entryReader);
if (entryReader.FileType == FileType.ResourceFile)
{
entryReader.Position = 0;
resourceFileReaders.TryAdd(entry.Name, entryReader);
if (!resourceFileReaders.ContainsKey(entry.Name))
{
resourceFileReaders.Add(entry.Name, entryReader);
}
}
Progress.Report(++k, progressCount);
}
catch (Exception e)
{
Logger.Warning($"Error while reading zip entry \"{entry.FullName}\"\n{e}");
Logger.Warning($"Error while reading zip entry {entry.FullName}\r\n{e}");
}
}
}
@@ -524,92 +433,26 @@ namespace AssetStudio
}
}
public void LoadOptionFiles(List<string> pathList)
public void CheckStrippedVersion(SerializedFile assetsFile)
{
if (pathList.Count == 0)
return;
var optionFileIndexes = new List<int>();
for (var i = 0; i < pathList.Count; i++)
if (assetsFile.IsVersionStripped && string.IsNullOrEmpty(SpecifyUnityVersion))
{
var path = pathList[i];
if (!path.EndsWith(OptionsFile.Extension, StringComparison.OrdinalIgnoreCase))
continue;
optionFileIndexes.Add(i);
var optionsFile = LoadOptionsFile(new FileReader(path));
if (optionsFile == null)
continue;
foreach (var optionsLoader in OptionLoaders)
{
optionsLoader(optionsFile);
}
throw new NotSupportedException("The Unity version has been stripped, please set the version in the options");
}
for (var i = 0; i < optionFileIndexes.Count; i++)
if (!string.IsNullOrEmpty(SpecifyUnityVersion))
{
pathList.RemoveAt(optionFileIndexes[i] - i);
}
}
private static OptionsFile LoadOptionsFile(FileReader reader)
{
Logger.Info($"Loading options file \"{reader.FullPath}\"");
try
{
return new OptionsFile(reader);
}
catch (Exception e)
{
Logger.Warning($"Error while loading options file \"{reader.FullPath}\"\n{e}");
return null;
}
finally
{
reader.Dispose();
}
}
private void LoadImportOptions(OptionsFile optionsFile)
{
try
{
var importOptions = ImportOptions.FromOptionsFile(optionsFile);
if (importOptions == null)
return;
Options = importOptions;
Logger.Info("Import options successfully loaded.");
}
catch (Exception e)
{
Logger.Warning($"Error while reading import options\n{e}");
}
}
public void CheckStrippedVersion(SerializedFile assetsFile, UnityVersion bundleUnityVer = null)
{
if (assetsFile.version.IsStripped && Options.CustomUnityVersion == null)
{
var msg = "The asset's Unity version has been stripped, please set the version in the options.";
if (bundleUnityVer != null && !bundleUnityVer.IsStripped)
msg += $"\n\nAssumed Unity version based on asset bundle: {bundleUnityVer}";
throw new NotSupportedException(msg);
}
if (Options.CustomUnityVersion != null)
{
assetsFile.version = Options.CustomUnityVersion;
assetsFile.SetVersion(SpecifyUnityVersion);
}
}
public void Clear()
{
foreach (var assetsFile in AssetsFileList)
foreach (var assetsFile in assetsFileList)
{
assetsFile.Objects.Clear();
assetsFile.reader.Close();
}
AssetsFileList.Clear();
assetsFileList.Clear();
foreach (var resourceFileReader in resourceFileReaders)
{
@@ -624,20 +467,11 @@ namespace AssetStudio
{
Logger.Info("Read assets...");
var jsonOptions = new JsonSerializerOptions
{
Converters = { new JsonConverterHelper.ByteArrayConverter(), new JsonConverterHelper.PPtrConverter(), new JsonConverterHelper.KVPConverter() },
NumberHandling = JsonNumberHandling.AllowNamedFloatingPointLiterals,
PropertyNameCaseInsensitive = true,
IncludeFields = true,
};
var progressCount = AssetsFileList.Sum(x => x.m_Objects.Count);
var i = 0;
var progressCount = assetsFileList.Sum(x => x.m_Objects.Count);
int i = 0;
Progress.Reset();
foreach (var assetsFile in AssetsFileList)
foreach (var assetsFile in assetsFileList)
{
JsonConverterHelper.AssetsFile = assetsFile;
foreach (var objectInfo in assetsFile.m_Objects)
{
var objectReader = new ObjectReader(assetsFile.reader, assetsFile, objectInfo);
@@ -654,9 +488,7 @@ namespace AssetStudio
obj = new Animation(objectReader);
break;
case ClassIDType.AnimationClip:
obj = objectReader.serializedType?.m_Type != null && LoadViaTypeTree
? new AnimationClip(objectReader, TypeTreeHelper.ReadTypeByteArray(objectReader.serializedType.m_Type, objectReader), jsonOptions, objectInfo)
: new AnimationClip(objectReader);
obj = new AnimationClip(objectReader);
break;
case ClassIDType.Animator:
obj = new Animator(objectReader);
@@ -676,9 +508,6 @@ namespace AssetStudio
case ClassIDType.Avatar:
obj = new Avatar(objectReader);
break;
case ClassIDType.BuildSettings:
obj = new BuildSettings(objectReader);
break;
case ClassIDType.Font:
obj = new Font(objectReader);
break;
@@ -686,9 +515,7 @@ namespace AssetStudio
obj = new GameObject(objectReader);
break;
case ClassIDType.Material:
obj = objectReader.serializedType?.m_Type != null && LoadViaTypeTree
? new Material(objectReader, TypeTreeHelper.ReadTypeByteArray(objectReader.serializedType.m_Type, objectReader), jsonOptions)
: new Material(objectReader);
obj = new Material(objectReader);
break;
case ClassIDType.Mesh:
obj = new Mesh(objectReader);
@@ -718,7 +545,7 @@ namespace AssetStudio
obj = new RectTransform(objectReader);
break;
case ClassIDType.Shader:
if (objectReader.version < 2021)
if (objectReader.version[0] < 2021)
obj = new Shader(objectReader);
break;
case ClassIDType.SkinnedMeshRenderer:
@@ -734,14 +561,7 @@ namespace AssetStudio
obj = new TextAsset(objectReader);
break;
case ClassIDType.Texture2D:
obj = objectReader.serializedType?.m_Type != null && LoadViaTypeTree
? new Texture2D(objectReader, TypeTreeHelper.ReadTypeByteArray(objectReader.serializedType.m_Type, objectReader), jsonOptions)
: new Texture2D(objectReader);
break;
case ClassIDType.Texture2DArray:
obj = objectReader.serializedType?.m_Type != null && LoadViaTypeTree
? new Texture2DArray(objectReader, TypeTreeHelper.ReadTypeByteArray(objectReader.serializedType.m_Type, objectReader), jsonOptions)
: new Texture2DArray(objectReader);
obj = new Texture2D(objectReader);
break;
case ClassIDType.Transform:
obj = new Transform(objectReader);
@@ -757,9 +577,7 @@ namespace AssetStudio
break;
}
if (obj != null)
{
assetsFile.AddObject(obj);
}
}
catch (Exception e)
{
@@ -782,7 +600,7 @@ namespace AssetStudio
{
Logger.Info("Process assets...");
foreach (var assetsFile in AssetsFileList)
foreach (var assetsFile in assetsFileList)
{
foreach (var obj in assetsFile.Objects)
{
@@ -812,34 +630,6 @@ namespace AssetStudio
case Animation m_Animation:
m_GameObject.m_Animation = m_Animation;
break;
case MonoBehaviour m_MonoBehaviour:
if (m_MonoBehaviour.m_Script.TryGet(out var m_Script))
{
switch (m_Script.m_ClassName)
{
case "CubismModel":
if (m_GameObject.m_Transform == null)
break;
m_GameObject.CubismModel = new CubismModel(m_GameObject)
{
CubismModelMono = m_MonoBehaviour
};
break;
case "CubismPhysicsController":
if (m_GameObject.CubismModel != null)
m_GameObject.CubismModel.PhysicsController = m_MonoBehaviour;
break;
case "CubismFadeController":
if (m_GameObject.CubismModel != null)
m_GameObject.CubismModel.FadeController = m_MonoBehaviour;
break;
case "CubismExpressionController":
if (m_GameObject.CubismModel != null)
m_GameObject.CubismModel.ExpressionController = m_MonoBehaviour;
break;
}
}
break;
}
}
}
@@ -854,17 +644,16 @@ namespace AssetStudio
{
m_Sprite.m_SpriteAtlas.Set(m_SpriteAtlas);
}
else if (m_Sprite.m_SpriteAtlas.TryGet(out var m_SpriteAtlasOld))
else if (m_Sprite.m_SpriteAtlas.TryGet(out var m_SpriteAtlaOld))
{
if (m_SpriteAtlasOld.m_IsVariant)
if (m_SpriteAtlaOld.m_IsVariant)
{
m_Sprite.m_SpriteAtlas.Set(m_SpriteAtlas);
}
}
else
{
Logger.Debug($"\"{m_Sprite.m_Name}\": The actual SpriteAtlas PathID \"{m_SpriteAtlas.m_PathID}\" does not match the specified one \"{m_Sprite.m_SpriteAtlas.m_PathID}\".");
m_Sprite.m_SpriteAtlas.Set(m_SpriteAtlas);
Logger.Warning($"\"{m_Sprite.m_Name}\": Sprite loading error. SpriteAtlas with PathID: \"{m_Sprite.m_SpriteAtlas.m_PathID}\" was not found.");
}
}
}

View File

@@ -4,11 +4,7 @@ namespace AssetStudio
{
public static class BigArrayPool<T>
{
public static ArrayPool<T> Shared { get; }
static BigArrayPool()
{
Shared = ArrayPool<T>.Create(256 * 1024 * 1024, 5);
}
private static readonly ArrayPool<T> s_shared = ArrayPool<T>.Create(64 * 1024 * 1024, 3);
public static ArrayPool<T> Shared => s_shared;
}
}

View File

@@ -1,4 +1,9 @@
namespace AssetStudio
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AssetStudio
{
public enum BuildTarget
{
@@ -48,18 +53,6 @@
PS5,
EmbeddedLinux,
QNX,
VisionOS,
Switch2,
UnknownPlatform = 9999
}
public enum TuanjieBuildTarget
{
MiniGame = 47,
OpenHarmony,
HMIAndroid,
ArmLinux,
ArmLinuxServer,
VisionOS,
}
}

20
AssetStudio/BuildType.cs Normal file
View File

@@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AssetStudio
{
public class BuildType
{
private string buildType;
public BuildType(string type)
{
buildType = type;
}
public bool IsAlpha => buildType == "a";
public bool IsPatch => buildType == "p";
}
}

View File

@@ -1,43 +0,0 @@
using System;
using System.Runtime.InteropServices;
#if NETFRAMEWORK
using AssetStudio.PInvoke;
#endif
namespace BundleCompression.Oodle
{
public static class OodleLZ
{
private const string LibName = "ooz";
#if NETFRAMEWORK
static OodleLZ()
{
DllLoader.PreloadDll(LibName);
}
#endif
[DllImport(LibName)]
private static extern int Ooz_Decompress(
in byte srcBuffer,
UIntPtr srcLen,
ref byte dstBuffer,
UIntPtr dstLen,
int fuzzSafetyFlag,
int crcCheckFlag,
int logVerbosityFlag,
UIntPtr rawBuffer,
UIntPtr rawBufferSize,
UIntPtr chunkDecodeCallback,
UIntPtr chunkDecodeContext,
UIntPtr scratchBuf,
UIntPtr scratchBufSize,
int threadPhase);
public static int Decompress(ReadOnlySpan<byte> srcSpanBuffer, Span<byte> dstSpanBuffer)
{
return Ooz_Decompress(in srcSpanBuffer[0], (UIntPtr)srcSpanBuffer.Length, ref dstSpanBuffer[0], (UIntPtr)dstSpanBuffer.Length,
0, 0, 0, UIntPtr.Zero, UIntPtr.Zero, UIntPtr.Zero, UIntPtr.Zero, UIntPtr.Zero, UIntPtr.Zero, 0);
}
}
}

View File

@@ -1,65 +0,0 @@
using BundleCompression.Lzma;
using BundleCompression.Oodle;
using System;
using System.IO;
using System.Text.RegularExpressions;
using K4os.Compression.LZ4;
using ZstdSharp;
namespace AssetStudio
{
public static class BundleDecompressionHelper
{
private static readonly Decompressor ZstdDecompressor = new Decompressor();
private static readonly string MsgPattern = @"\. ";
public static MemoryStream DecompressLzmaStream(MemoryStream inStream)
{
return SevenZipLzma.DecompressStream(inStream);
}
public static long DecompressLzmaStream(Stream compressedStream, Stream decompressedStream, long compressedSize, long decompressedSize, ref string errorMsg)
{
var numWrite = -1L;
try
{
numWrite = SevenZipLzma.DecompressStream(compressedStream, decompressedStream, compressedSize, decompressedSize);
}
catch (Exception e)
{
Logger.Debug(e.ToString());
errorMsg = $"({Regex.Split(e.Message, MsgPattern, RegexOptions.CultureInvariant)[0]})";
}
return numWrite;
}
public static int DecompressBlock(CompressionType type, ReadOnlySpan<byte> srcBuffer, Span<byte> dstBuffer, ref string errorMsg)
{
var numWrite = -1;
try
{
switch (type)
{
case CompressionType.Lz4:
case CompressionType.Lz4HC:
numWrite = LZ4Codec.Decode(srcBuffer, dstBuffer);
break;
case CompressionType.Zstd:
numWrite = ZstdDecompressor.Unwrap(srcBuffer, dstBuffer);
break;
case CompressionType.Oodle:
numWrite = OodleLZ.Decompress(srcBuffer, dstBuffer);
break;
default:
throw new NotSupportedException();
}
}
catch (Exception e)
{
Logger.Debug(e.ToString());
errorMsg = $"({Regex.Split(e.Message, MsgPattern, RegexOptions.CultureInvariant)[0]})";
}
return numWrite;
}
}
}

View File

@@ -1,8 +1,7 @@
using System;
using K4os.Compression.LZ4;
using System;
using System.IO;
using System.Linq;
using System.Collections.Generic;
using AssetStudio.CustomOptions;
namespace AssetStudio
{
@@ -19,8 +18,8 @@ namespace AssetStudio
[Flags]
public enum CnEncryptionFlags
{
V1 = 0x200,
V2_V3 = 0x1400,
OldFlag = 0x200,
NewFlag = 0x400
}
[Flags]
@@ -32,27 +31,21 @@ namespace AssetStudio
public enum CompressionType
{
Auto = -1,
None,
Lzma,
Lz4,
Lz4HC,
Lzham,
Zstd, //custom
Oodle, //custom
Lz4Inv,
}
public class BundleFile
{
public readonly bool IsDataAfterBundle;
private readonly CustomBundleOptions _bundleOptions;
public class Header
{
public string signature;
public uint version;
public string unityVersion;
public UnityVersion unityRevision;
public string unityRevision;
public long size;
public uint compressedBlocksInfoSize;
public uint uncompressedBlocksInfoSize;
@@ -78,19 +71,15 @@ namespace AssetStudio
private StorageBlock[] m_BlocksInfo;
private Node[] m_DirectoryInfo;
public List<StreamFile> fileList;
public StreamFile[] fileList;
public BundleFile(FileReader reader, CustomBundleOptions bundleOptions, bool isMultiBundle = false)
public BundleFile(FileReader reader, string specUnityVer = "")
{
_bundleOptions = bundleOptions;
m_Header = new Header();
m_Header.signature = reader.ReadStringToNull();
m_Header.version = reader.ReadUInt32();
m_Header.unityVersion = reader.ReadStringToNull();
var revStr = reader.ReadStringToNull();
if (!UnityVersion.TryParse(revStr, out m_Header.unityRevision))
m_Header.unityRevision = new UnityVersion();
m_Header.unityRevision = reader.ReadStringToNull();
switch (m_Header.signature)
{
case "UnityArchive":
@@ -102,52 +91,49 @@ namespace AssetStudio
goto case "UnityFS";
}
ReadHeaderAndBlocksInfo(reader);
using (reader)
using (var blocksStream = CreateBlocksStream(reader.FullPath))
{
ReadFiles(ReadBlocksAndDirectory(reader));
ReadBlocksAndDirectory(reader, blocksStream);
ReadFiles(blocksStream, reader.FullPath);
}
break;
case "UnityFS":
ReadHeader(reader);
var bundleSize = m_Header.size;
var streamSize = reader.BaseStream.Length;
if (bundleSize > streamSize)
Logger.Warning("Bundle size is incorrect.");
IsDataAfterBundle = streamSize - bundleSize > 200;
var unityVer = m_Header.unityRevision;
var customUnityVer = _bundleOptions.Options.CustomUnityVersion;
if (customUnityVer != null)
bool isUnityCnEnc = false;
string unityVer = string.IsNullOrEmpty(specUnityVer) ? m_Header.unityRevision : specUnityVer;
int[] ver = new string(unityVer.SkipWhile(x => !char.IsDigit(x)).TakeWhile(x => char.IsDigit(x) || x == '.').ToArray()).Split('.').Select(x => int.Parse(x)).ToArray();
if (ver[0] != 0)
{
if (!unityVer.IsStripped && customUnityVer != unityVer)
// https://issuetracker.unity3d.com/issues/files-within-assetbundles-do-not-start-on-aligned-boundaries-breaking-patching-on-nintendo-switch
if (ver[0] < 2020 ||
(ver[0] == 2020 && ver[1] <= 3 && ver[2] < 34) ||
(ver[0] == 2021 && ver[1] <= 3 && ver[2] < 2) ||
(ver[0] == 2022 && ver[1] <= 1 && ver[2] < 1))
{
Logger.Warning($"Detected Unity version is different from the specified one ({customUnityVer.FullVersion.Color(ColorConsole.BrightCyan)}).\n" +
$"Assets may load with errors.\n" +
$"It is recommended to specify the detected Unity version: {unityVer.FullVersion.Color(ColorConsole.BrightCyan)}");
isUnityCnEnc = ((CnEncryptionFlags)m_Header.flags & CnEncryptionFlags.OldFlag) != 0;
}
else
{
isUnityCnEnc = ((CnEncryptionFlags)m_Header.flags & CnEncryptionFlags.NewFlag) != 0;
}
unityVer = customUnityVer;
}
UnityCnCheck(reader, unityVer);
ReadBlocksInfoAndDirectory(reader, unityVer);
if (IsUncompressedBundle && !IsDataAfterBundle && !isMultiBundle)
if (isUnityCnEnc)
{
Logger.Debug($"[Uncompressed bundle] BlockData count: {m_BlocksInfo.Length}");
ReadFiles(reader.BaseStream, reader.Position);
break;
throw new NotSupportedException("Unsupported bundle file. UnityCN encryption was detected.");
}
ReadFiles(ReadBlocks(reader));
if (!IsDataAfterBundle)
reader.Close();
ReadBlocksInfoAndDirectory(reader, ver);
using (var blocksStream = CreateBlocksStream(reader.FullPath))
{
ReadBlocks(reader, blocksStream);
ReadFiles(blocksStream, reader.FullPath);
}
break;
}
}
private void ReadHeaderAndBlocksInfo(FileReader reader)
private void ReadHeaderAndBlocksInfo(EndianBinaryReader reader)
{
if (m_Header.version >= 4)
{
@@ -161,7 +147,7 @@ namespace AssetStudio
m_BlocksInfo = new StorageBlock[1];
for (int i = 0; i < levelCount; i++)
{
var storageBlock = new StorageBlock
var storageBlock = new StorageBlock()
{
compressedSize = reader.ReadUInt32(),
uncompressedSize = reader.ReadUInt32(),
@@ -184,24 +170,23 @@ namespace AssetStudio
private Stream CreateBlocksStream(string path)
{
Stream blocksStream;
var uncompressedSizeSum = m_BlocksInfo.Sum(x => x.uncompressedSize);
if (uncompressedSizeSum < int.MaxValue && !_bundleOptions.DecompressToDisk)
return new MemoryStream((int)uncompressedSizeSum);
if (!Directory.Exists(Path.GetDirectoryName(path)))
if (uncompressedSizeSum >= int.MaxValue)
{
var tempDir = Path.Combine(Directory.GetCurrentDirectory(), "Studio_temp");
Directory.CreateDirectory(tempDir);
var filename = Path.GetFileName(path);
var hash = path.GetHashCode();
path = Path.Combine(tempDir, $"{filename}_{hash:X}");
/*var memoryMappedFile = MemoryMappedFile.CreateNew(null, uncompressedSizeSum);
assetsDataStream = memoryMappedFile.CreateViewStream();*/
blocksStream = new FileStream(path + ".temp", FileMode.Create, FileAccess.ReadWrite, FileShare.None, 4096, FileOptions.DeleteOnClose);
}
return new TempFileStream(path + ".temp", FileMode.Create);
else
{
blocksStream = new MemoryStream((int)uncompressedSizeSum);
}
return blocksStream;
}
private Stream ReadBlocksAndDirectory(FileReader reader)
private void ReadBlocksAndDirectory(EndianBinaryReader reader, Stream blocksStream)
{
var blocksStream = CreateBlocksStream(reader.FullPath);
var isCompressed = m_Header.signature == "UnityWeb";
foreach (var blockInfo in m_BlocksInfo)
{
@@ -210,7 +195,7 @@ namespace AssetStudio
{
using (var memoryStream = new MemoryStream(uncompressedBytes))
{
using (var decompressStream = BundleDecompressionHelper.DecompressLzmaStream(memoryStream))
using (var decompressStream = SevenZipHelper.StreamDecompress(memoryStream))
{
uncompressedBytes = decompressStream.ToArray();
}
@@ -219,11 +204,10 @@ namespace AssetStudio
blocksStream.Write(uncompressedBytes, 0, uncompressedBytes.Length);
}
blocksStream.Position = 0;
var blocksReader = new EndianBinaryReader(blocksStream);
var nodesCount = blocksReader.ReadInt32();
m_DirectoryInfo = new Node[nodesCount];
for (var i = 0; i < nodesCount; i++)
for (int i = 0; i < nodesCount; i++)
{
m_DirectoryInfo[i] = new Node
{
@@ -232,31 +216,37 @@ namespace AssetStudio
size = blocksReader.ReadUInt32()
};
}
return blocksStream;
}
private void ReadFiles(Stream inputStream, long blocksOffset = 0)
public void ReadFiles(Stream blocksStream, string path)
{
fileList = new List<StreamFile>(m_DirectoryInfo.Length);
foreach (var node in m_DirectoryInfo)
fileList = new StreamFile[m_DirectoryInfo.Length];
for (int i = 0; i < m_DirectoryInfo.Length; i++)
{
var node = m_DirectoryInfo[i];
var file = new StreamFile();
fileList.Add(file);
fileList[i] = file;
file.path = node.path;
file.fileName = Path.GetFileName(node.path);
try
if (node.size >= int.MaxValue)
{
file.stream = new OffsetStream(inputStream, node.offset + blocksOffset, node.size);
/*var memoryMappedFile = MemoryMappedFile.CreateNew(null, entryinfo_size);
file.stream = memoryMappedFile.CreateViewStream();*/
var extractPath = path + "_unpacked" + Path.DirectorySeparatorChar;
Directory.CreateDirectory(extractPath);
file.stream = new FileStream(extractPath + file.fileName, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite);
}
catch (IOException e)
else
{
Logger.Warning($"Failed to access {file.fileName} file.\n{e}");
file.stream = new MemoryStream((int)node.size);
}
blocksStream.Position = node.offset;
blocksStream.CopyTo(file.stream, node.size);
file.stream.Position = 0;
}
}
private void ReadHeader(FileReader reader)
private void ReadHeader(EndianBinaryReader reader)
{
m_Header.size = reader.ReadInt64();
m_Header.compressedBlocksInfoSize = reader.ReadUInt32();
@@ -268,7 +258,7 @@ namespace AssetStudio
}
}
private void ReadBlocksInfoAndDirectory(FileReader reader, UnityVersion unityVer, bool silent = false)
private void ReadBlocksInfoAndDirectory(EndianBinaryReader reader, int[] unityVer)
{
byte[] blocksInfoBytes;
@@ -276,7 +266,7 @@ namespace AssetStudio
{
reader.AlignStream(16);
}
else if (unityVer >= (2019, 4) && m_Header.flags != ArchiveFlags.BlocksAndDirectoryInfoCombined)
else if (unityVer[0] >= 2019 && unityVer[1] >= 4)
{
//check if we need to align the reader
//- align to 16 bytes and check if all are 0
@@ -289,96 +279,58 @@ namespace AssetStudio
}
}
var compressedSize = (int)m_Header.compressedBlocksInfoSize;
var uncompressedSize = (int)m_Header.uncompressedBlocksInfoSize;
if (uncompressedSize < 0 || compressedSize < 0 || compressedSize > reader.BaseStream.Length)
{
throw new IOException("Incorrect blockInfo length.\nBlockInfo sizes might be encrypted.\n");
}
if ((m_Header.flags & ArchiveFlags.BlocksInfoAtTheEnd) != 0)
{
var position = reader.Position;
reader.Position = m_Header.size - compressedSize;
blocksInfoBytes = reader.ReadBytes(compressedSize);
reader.Position = reader.BaseStream.Length - m_Header.compressedBlocksInfoSize;
blocksInfoBytes = reader.ReadBytes((int)m_Header.compressedBlocksInfoSize);
reader.Position = position;
}
else //0x40 BlocksAndDirectoryInfoCombined
{
blocksInfoBytes = reader.ReadBytes(compressedSize);
blocksInfoBytes = reader.ReadBytes((int)m_Header.compressedBlocksInfoSize);
}
var customBlockInfoCompression = _bundleOptions.CustomBlockInfoCompression;
MemoryStream blocksInfoUncompresseddStream;
var uncompressedSize = m_Header.uncompressedBlocksInfoSize;
var compressionType = (CompressionType)(m_Header.flags & ArchiveFlags.CompressionTypeMask);
if (customBlockInfoCompression == CompressionType.Auto)
{
if (!silent && compressionType > CompressionType.Lzham && Enum.IsDefined(typeof(CompressionType), compressionType))
{
Logger.Warning($"Non-standard blockInfo compression type: {(int)compressionType}. Trying to decompress as {compressionType} archive..");
}
}
else if (compressionType != CompressionType.None)
{
compressionType = customBlockInfoCompression;
if (!silent)
{
Logger.Info($"Custom blockInfo compression type: {customBlockInfoCompression}");
}
}
Logger.Debug($"BlockInfo compression: {compressionType}");
int numWrite;
var errorMsg = string.Empty;
MemoryStream blocksInfoUncompressedStream;
switch (compressionType)
{
case CompressionType.None:
{
blocksInfoUncompressedStream = new MemoryStream(blocksInfoBytes);
numWrite = compressedSize;
break;
}
case CompressionType.Lzma:
{
blocksInfoUncompressedStream = new MemoryStream(uncompressedSize);
using (var blocksInfoCompressedStream = new MemoryStream(blocksInfoBytes))
{
numWrite = (int)BundleDecompressionHelper.DecompressLzmaStream(blocksInfoCompressedStream, blocksInfoUncompressedStream, compressedSize, uncompressedSize, ref errorMsg);
blocksInfoUncompresseddStream = new MemoryStream(blocksInfoBytes);
break;
}
case CompressionType.Lzma:
{
blocksInfoUncompresseddStream = new MemoryStream((int)(uncompressedSize));
using (var blocksInfoCompressedStream = new MemoryStream(blocksInfoBytes))
{
SevenZipHelper.StreamDecompress(blocksInfoCompressedStream, blocksInfoUncompresseddStream, m_Header.compressedBlocksInfoSize, m_Header.uncompressedBlocksInfoSize);
}
blocksInfoUncompresseddStream.Position = 0;
break;
}
blocksInfoUncompressedStream.Position = 0;
break;
}
case CompressionType.Lz4:
case CompressionType.Lz4HC:
case CompressionType.Zstd:
case CompressionType.Oodle:
{
var uncompressedBytes = new byte[uncompressedSize];
numWrite = BundleDecompressionHelper.DecompressBlock(compressionType, blocksInfoBytes, uncompressedBytes, ref errorMsg);
blocksInfoUncompressedStream = new MemoryStream(uncompressedBytes);
break;
}
case CompressionType.Lzham:
throw new IOException($"Unsupported blockInfo compression type: {compressionType}.\n");
{
var uncompressedBytes = new byte[uncompressedSize];
var numWrite = LZ4Codec.Decode(blocksInfoBytes, uncompressedBytes);
if (numWrite != uncompressedSize)
{
throw new IOException($"Lz4 decompression error, write {numWrite} bytes but expected {uncompressedSize} bytes");
}
blocksInfoUncompresseddStream = new MemoryStream(uncompressedBytes);
break;
}
default:
throw new IOException($"Unknown blockInfo compression type: {compressionType}.\nYou may try to specify the compression type manually.\n");
throw new IOException($"Unsupported compression type {compressionType}");
}
if (numWrite != uncompressedSize)
{
var msg = $"{compressionType} blockInfo decompression error. {errorMsg}\nWrite {numWrite} bytes but expected {uncompressedSize} bytes.";
var exMsg = compressionType > CompressionType.Lz4HC || customBlockInfoCompression != CompressionType.Auto
? "Wrong compression type or blockInfo data might be encrypted."
: "BlockInfo data might be encrypted.";
throw new IOException($"{msg}\n{exMsg}\n");
}
using (var blocksInfoReader = new EndianBinaryReader(blocksInfoUncompressedStream))
using (var blocksInfoReader = new EndianBinaryReader(blocksInfoUncompresseddStream))
{
var uncompressedDataHash = blocksInfoReader.ReadBytes(16);
var blocksInfoCount = blocksInfoReader.ReadInt32();
m_BlocksInfo = new StorageBlock[blocksInfoCount];
for (var i = 0; i < blocksInfoCount; i++)
for (int i = 0; i < blocksInfoCount; i++)
{
m_BlocksInfo[i] = new StorageBlock
{
@@ -390,7 +342,7 @@ namespace AssetStudio
var nodesCount = blocksInfoReader.ReadInt32();
m_DirectoryInfo = new Node[nodesCount];
for (var i = 0; i < nodesCount; i++)
for (int i = 0; i < nodesCount; i++)
{
m_DirectoryInfo[i] = new Node
{
@@ -407,147 +359,57 @@ namespace AssetStudio
}
}
private Stream ReadBlocks(FileReader reader)
private void ReadBlocks(EndianBinaryReader reader, Stream blocksStream)
{
var customBlockCompression = _bundleOptions.CustomBlockCompression;
var blocksStream = CreateBlocksStream(reader.FullPath);
var blocksCompression = m_BlocksInfo.Max(x => (CompressionType)(x.flags & StorageBlockFlags.CompressionTypeMask));
var blockSize = (int)m_BlocksInfo.Max(x => x.uncompressedSize);
Logger.Debug($"BlockData compression: {blocksCompression}\n" +
$"BlockData count: {m_BlocksInfo.Length}\n" +
$"BlockSize: {blockSize}");
if (customBlockCompression == CompressionType.Auto)
foreach (var blockInfo in m_BlocksInfo)
{
if (blocksCompression > CompressionType.Lzham && Enum.IsDefined(typeof(CompressionType), blocksCompression))
var compressionType = (CompressionType)(blockInfo.flags & StorageBlockFlags.CompressionTypeMask);
switch (compressionType)
{
Logger.Warning($"Non-standard block compression type: {(int)blocksCompression}. Trying to decompress as {blocksCompression} archive..");
}
}
else
{
Logger.Info($"Custom block compression type: {customBlockCompression}");
blocksCompression = customBlockCompression;
}
byte[] sharedCompressedBuff = null;
byte[] sharedUncompressedBuff = null;
if (blocksCompression != CompressionType.Lzma && blocksCompression != CompressionType.Lzham)
{
sharedCompressedBuff = BigArrayPool<byte>.Shared.Rent(blockSize);
sharedUncompressedBuff = BigArrayPool<byte>.Shared.Rent(blockSize);
}
try
{
foreach (var blockInfo in m_BlocksInfo)
{
var compressionType = (CompressionType)(blockInfo.flags & StorageBlockFlags.CompressionTypeMask);
if (customBlockCompression != CompressionType.Auto && compressionType > 0)
{
compressionType = customBlockCompression;
}
long numWrite;
var errorMsg = string.Empty;
switch (compressionType)
{
case CompressionType.None:
case CompressionType.None:
{
reader.BaseStream.CopyTo(blocksStream, blockInfo.compressedSize);
numWrite = blockInfo.compressedSize;
break;
case CompressionType.Lzma:
Logger.Info("Decompressing LZMA stream...");
numWrite = BundleDecompressionHelper.DecompressLzmaStream(reader.BaseStream, blocksStream, blockInfo.compressedSize, blockInfo.uncompressedSize, ref errorMsg);
}
case CompressionType.Lzma:
{
SevenZipHelper.StreamDecompress(reader.BaseStream, blocksStream, blockInfo.compressedSize, blockInfo.uncompressedSize);
break;
case CompressionType.Lz4:
case CompressionType.Lz4HC:
case CompressionType.Zstd:
case CompressionType.Oodle:
}
case CompressionType.Lz4:
case CompressionType.Lz4HC:
case CompressionType.Lz4Inv:
{
var compressedSize = (int)blockInfo.compressedSize;
var compressedBytes = BigArrayPool<byte>.Shared.Rent(compressedSize);
_ = reader.Read(compressedBytes, 0, compressedSize);
var uncompressedSize = (int)blockInfo.uncompressedSize;
sharedCompressedBuff.AsSpan().Clear();
sharedUncompressedBuff.AsSpan().Clear();
_ = reader.Read(sharedCompressedBuff, 0, compressedSize);
var compressedSpan = new ReadOnlySpan<byte>(sharedCompressedBuff, 0, compressedSize);
var uncompressedSpan = new Span<byte>(sharedUncompressedBuff, 0, uncompressedSize);
numWrite = BundleDecompressionHelper.DecompressBlock(compressionType, compressedSpan, uncompressedSpan, ref errorMsg);
if (numWrite == uncompressedSize)
var uncompressedBytes = BigArrayPool<byte>.Shared.Rent(uncompressedSize);
try
{
blocksStream.Write(sharedUncompressedBuff, 0, uncompressedSize);
continue;
var compressedSpan = compressedBytes.AsSpan(0, compressedSize);
var uncompressedSpan = uncompressedBytes.AsSpan(0, uncompressedSize);
var numWrite = compressionType == CompressionType.Lz4Inv
? LZ4Inv.Instance.Decompress(compressedSpan, uncompressedSpan)
: LZ4Codec.Decode(compressedSpan, uncompressedSpan);
if (numWrite != uncompressedSize)
{
throw new IOException($"Lz4 decompression error, write {numWrite} bytes but expected {uncompressedSize} bytes");
}
blocksStream.Write(uncompressedBytes, 0, uncompressedSize);
}
finally
{
BigArrayPool<byte>.Shared.Return(compressedBytes);
BigArrayPool<byte>.Shared.Return(uncompressedBytes);
}
break;
case CompressionType.Lzham:
throw new IOException($"Unsupported block compression type: {compressionType}.\n");
default:
throw new IOException($"Unknown block compression type: {compressionType}.\nYou may try to specify the compression type manually.\n");
}
if (numWrite != blockInfo.uncompressedSize)
{
var msg = $"{compressionType} block decompression error. {errorMsg}\nWrite {numWrite} bytes but expected {blockInfo.uncompressedSize} bytes.";
var exMsg = compressionType > CompressionType.Lz4HC || customBlockCompression != CompressionType.Auto
? "Wrong compression type or block data might be encrypted."
: "Block data might be encrypted.";
throw new IOException($"{msg}\n{exMsg}\n");
}
}
default:
throw new IOException($"Unsupported compression type {compressionType}");
}
}
finally
{
if (sharedCompressedBuff != null)
BigArrayPool<byte>.Shared.Return(sharedCompressedBuff, clearArray: true);
if (sharedUncompressedBuff != null)
BigArrayPool<byte>.Shared.Return(sharedUncompressedBuff, clearArray: true);
}
return blocksStream;
blocksStream.Position = 0;
}
private void UnityCnCheck(FileReader reader, UnityVersion unityVer)
{
if ((m_Header.flags & ArchiveFlags.BlocksInfoAtTheEnd) != 0)
return;
var hasUnityCnFlag = false;
if (!unityVer.IsStripped)
{
// https://issuetracker.unity3d.com/issues/files-within-assetbundles-do-not-start-on-aligned-boundaries-breaking-patching-on-nintendo-switch
if (unityVer < 2020
|| unityVer.IsInRange(2020, (2020, 3, 34))
|| unityVer.IsInRange(2021, (2021, 3, 2))
|| unityVer.IsInRange(2022, (2022, 1, 1)))
{
hasUnityCnFlag = ((CnEncryptionFlags)m_Header.flags & CnEncryptionFlags.V1) != 0;
}
else
{
hasUnityCnFlag = ((CnEncryptionFlags)m_Header.flags & CnEncryptionFlags.V2_V3) != 0;
}
}
if (!hasUnityCnFlag)
return;
var pos = reader.Position;
reader.Position += 70;
try
{
ReadBlocksInfoAndDirectory(reader, unityVer, silent: true);
}
catch (Exception)
{
reader.Position = pos;
return;
}
throw new NotSupportedException("Unsupported bundle file. UnityCN encryption was detected.");
}
private bool IsUncompressedBundle => m_BlocksInfo.All(x => (CompressionType)(x.flags & StorageBlockFlags.CompressionTypeMask) == CompressionType.None);
}
}

View File

@@ -3,6 +3,7 @@ namespace AssetStudio
{
public enum ClassIDType
{
AkPortraitSprite = -2,
UnknownType = -1,
Object = 0,
GameObject = 1,
@@ -145,7 +146,6 @@ namespace AssetStudio
ProceduralMaterial = 185,
ProceduralTexture = 186,
Texture2DArray = 187,
Texture2DArrayImage = -187, //fake type
CubemapArray = 188,
OffMeshLink = 191,
OcclusionArea = 192,
@@ -297,7 +297,6 @@ namespace AssetStudio
//void = 100011,
TilemapCollider2D = 19719996,
AssetImporterLog = 41386430,
GraphicsStateCollection = 55640938,
VFXRenderer = 73398921,
SerializableManagedRefTestClass = 76251197,
Grid = 156049354,
@@ -310,13 +309,9 @@ namespace AssetStudio
AssemblyDefinitionReferenceImporter = 294290339,
SiblingDerived = 334799969,
TestObjectWithSerializedMapStringNonAlignedStruct = 342846651,
AudioResource = 355983997,
SubDerived = 367388927,
AssetImportInProgressProxy = 369655926,
PluginBuildInfo = 382020655,
MemorySettings = 387306366,
BuildMetaDataImporter = 403037116,
BuildInstructionImporter = 403037117,
EditorProjectAccess = 426301858,
PrefabImporter = 468431735,
TestObjectWithSerializedArray = 478637458,
@@ -328,22 +323,16 @@ namespace AssetStudio
AudioBuildInfo = 641289076,
CachedSpriteAtlasRuntimeData = 644342135,
RendererFake = 646504946,
MultiplayerManager = 655991488,
AssemblyDefinitionReferenceAsset = 662584278,
BuiltAssetBundleInfoSet = 668709126,
SpriteAtlas = 687078895,
RayTracingShaderImporter = 747330370,
BuildArchiveImporter = 780535461,
PreviewImporter = 815301076,
RayTracingShader = 825902497,
LightingSettings = 850595691,
PlatformModuleSetup = 877146078,
VersionControlSettings = 890905787,
CustomCollider2D = 893571522,
AimConstraint = 895512359,
VFXManager = 937362698,
RoslynAnalyzerConfigAsset = 947337230,
RuleSetFileAsset = 954905827,
VisualEffectSubgraph = 994735392,
VisualEffectSubgraphOperator = 994735403,
VisualEffectSubgraphBlock = 994735404,
@@ -356,40 +345,25 @@ namespace AssetStudio
LookAtConstraint = 1183024399,
SpriteAtlasImporter = 1210832254,
MultiArtifactTestImporter = 1223240404,
AudioContainerElement = 1233149941,
GameObjectRecorder = 1268269756,
AudioRandomContainer = 1307931743,
LightingDataAssetParent = 1325145578,
PresetManager = 1386491679,
TestObjectWithSpecialLayoutTwo = 1392443030,
StreamingManager = 1403656975,
LowerResBlitTexture = 1480428607,
VideoBuildInfo = 1521398425,
C4DImporter = 1541671625,
StreamingController = 1542919678,
RenderPassAttachment = 1571458007,
TestObjectVectorPairStringBool = 1628831178,
ShaderContainer = 1557264870,
RoslynAdditionalFileAsset = 1597193336,
RoslynAdditionalFileImporter = 1642787288,
MultiplayerRolesData = 1652712579,
SceneRoots = 1660057539,
BrokenPrefabAsset = 1731078267,
AndroidAssetPackImporter = 1736697216,
VulkanDeviceFilterLists = 1740304944,
GridLayout = 1742807556,
AssemblyDefinitionImporter = 1766753193,
ParentConstraint = 1773428102,
FakeComponent = 1803986026,
RuleSetFileImporter = 1777034230,
PositionConstraint = 1818360608,
RotationConstraint = 1818360609,
ScaleConstraint = 1818360610,
Tilemap = 1839735485,
PackageManifest = 1896753125,
PackageManifestImporter = 1896753126,
RoslynAnalyzerConfigImporter = 1903396204,
UIRenderer = 1931382933,
TerrainLayer = 1953259897,
SpriteShapeRenderer = 1971053207,
NativeObjectType = 1977754360,
@@ -401,7 +375,6 @@ namespace AssetStudio
VisualEffectObject = 2059678085,
VisualEffect = 2083052967,
LocalizationAsset = 2083778819,
ScriptedImporter = 2089858483,
ShaderIncludeImporter = 2103361453,
ScriptedImporter = 2089858483
}
}

View File

@@ -1,19 +1,22 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AssetStudio
{
public sealed class Animation : Behaviour
{
public List<PPtr<AnimationClip>> m_Animations;
public PPtr<AnimationClip>[] m_Animations;
public Animation(ObjectReader reader) : base(reader)
{
var m_Animation = new PPtr<AnimationClip>(reader);
int numAnimations = reader.ReadInt32();
m_Animations = new List<PPtr<AnimationClip>>();
for (var i = 0; i < numAnimations; i++)
m_Animations = new PPtr<AnimationClip>[numAnimations];
for (int i = 0; i < numAnimations; i++)
{
m_Animations.Add(new PPtr<AnimationClip>(reader));
m_Animations[i] = new PPtr<AnimationClip>(reader);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,9 @@
namespace AssetStudio
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AssetStudio
{
public sealed class Animator : Behaviour
{
@@ -12,57 +17,47 @@
m_Controller = new PPtr<RuntimeAnimatorController>(reader);
var m_CullingMode = reader.ReadInt32();
if (version >= (4, 5)) //4.5 and up
if (version[0] > 4 || (version[0] == 4 && version[1] >= 5)) //4.5 and up
{
var m_UpdateMode = reader.ReadInt32();
}
if (version.IsTuanjie && (version > (2022, 3, 48) || version == (2022, 3, 48) && version.Build >= 7)) //2022.3.48t7(1.4.4) and up
{
var m_UpdateFrequencyMode = reader.ReadInt32();
var m_UpdateFrequency = reader.ReadSingle();
}
var m_ApplyRootMotion = reader.ReadBoolean();
if (version == 4 && version.Minor >= 5) //4.5 and up - 5.0 down
if (version[0] == 4 && version[1] >= 5) //4.5 and up - 5.0 down
{
reader.AlignStream();
}
if (version >= 5) //5.0 and up
if (version[0] >= 5) //5.0 and up
{
var m_LinearVelocityBlending = reader.ReadBoolean();
if (version >= (2021, 2)) //2021.2 and up
if (version[0] > 2021 || (version[0] == 2021 && version[1] >= 2)) //2021.2 and up
{
var m_StabilizeFeet = reader.ReadBoolean();
}
if (version >= (2023, 1)) //2023.1 and up
{
var m_AnimatePhysics = reader.ReadBoolean();
}
reader.AlignStream();
}
if (version < (4, 5)) //4.5 down
if (version[0] < 4 || (version[0] == 4 && version[1] < 5)) //4.5 down
{
var m_AnimatePhysics = reader.ReadBoolean();
}
if (version >= (4, 3)) //4.3 and up
if (version[0] > 4 || (version[0] == 4 && version[1] >= 3)) //4.3 and up
{
m_HasTransformHierarchy = reader.ReadBoolean();
}
if (version >= (4, 5)) //4.5 and up
if (version[0] > 4 || (version[0] == 4 && version[1] >= 5)) //4.5 and up
{
var m_AllowConstantClipSamplingOptimization = reader.ReadBoolean();
}
if (version.IsInRange(5, 2018)) //5.0 and up - 2018 down
if (version[0] >= 5 && version[0] < 2018) //5.0 and up - 2018 down
{
reader.AlignStream();
}
if (version >= 2018) //2018 and up
if (version[0] >= 2018) //2018 and up
{
var m_KeepAnimatorControllerStateOnDisable = reader.ReadBoolean();
reader.AlignStream();

View File

@@ -1,4 +1,7 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AssetStudio
{
@@ -14,7 +17,7 @@ namespace AssetStudio
word0 = reader.ReadUInt32();
word1 = reader.ReadUInt32();
if (version >= (5, 2)) //5.2 and up
if (version[0] > 5 || (version[0] == 5 && version[1] >= 2)) //5.2 and up
{
word2 = reader.ReadUInt32();
}
@@ -35,15 +38,15 @@ namespace AssetStudio
public class SkeletonMask
{
public List<SkeletonMaskElement> m_Data;
public SkeletonMaskElement[] m_Data;
public SkeletonMask(ObjectReader reader)
{
int numElements = reader.ReadInt32();
m_Data = new List<SkeletonMaskElement>();
for (var i = 0; i < numElements; i++)
m_Data = new SkeletonMaskElement[numElements];
for (int i = 0; i < numElements; i++)
{
m_Data.Add(new SkeletonMaskElement(reader));
m_Data[i] = new SkeletonMaskElement(reader);
}
}
}
@@ -70,12 +73,12 @@ namespace AssetStudio
m_SkeletonMask = new SkeletonMask(reader);
m_Binding = reader.ReadUInt32();
m_LayerBlendingMode = reader.ReadInt32();
if (version >= (4, 2)) //4.2 and up
if (version[0] > 4 || (version[0] == 4 && version[1] >= 2)) //4.2 and up
{
m_DefaultWeight = reader.ReadSingle();
}
m_IKPass = reader.ReadBoolean();
if (version >= (4, 2)) //4.2 and up
if (version[0] > 4 || (version[0] == 4 && version[1] >= 2)) //4.2 and up
{
m_SyncedLayerAffectsTiming = reader.ReadBoolean();
}
@@ -121,15 +124,14 @@ namespace AssetStudio
var version = reader.version;
int numConditions = reader.ReadInt32();
var conditionConstantList = new List<ConditionConstant>();
for (var i = 0; i < numConditions; i++)
m_ConditionConstantArray = new ConditionConstant[numConditions];
for (int i = 0; i < numConditions; i++)
{
conditionConstantList.Add(new ConditionConstant(reader));
m_ConditionConstantArray[i] = new ConditionConstant(reader);
}
m_ConditionConstantArray = conditionConstantList.ToArray();
m_DestinationState = reader.ReadUInt32();
if (version >= 5) //5.0 and up
if (version[0] >= 5) //5.0 and up
{
m_FullPathID = reader.ReadUInt32();
}
@@ -138,7 +140,7 @@ namespace AssetStudio
m_UserID = reader.ReadUInt32();
m_TransitionDuration = reader.ReadSingle();
m_TransitionOffset = reader.ReadSingle();
if (version >= 5) //5.0 and up
if (version[0] >= 5) //5.0 and up
{
m_ExitTime = reader.ReadSingle();
m_HasExitTime = reader.ReadBoolean();
@@ -152,7 +154,7 @@ namespace AssetStudio
m_Atomic = reader.ReadBoolean();
}
if (version >= (4, 5)) //4.5 and up
if (version[0] > 4 || (version[0] == 4 && version[1] >= 5)) //4.5 and up
{
m_CanTransitionToSelf = reader.ReadBoolean();
}
@@ -199,12 +201,11 @@ namespace AssetStudio
m_ChildPairAvgMagInvArray = reader.ReadSingleArray();
int numNeighbours = reader.ReadInt32();
var childNeighborLists = new List<MotionNeighborList>();
for (var i = 0; i < numNeighbours; i++)
m_ChildNeighborListArray = new MotionNeighborList[numNeighbours];
for (int i = 0; i < numNeighbours; i++)
{
childNeighborLists.Add(new MotionNeighborList(reader));
m_ChildNeighborListArray[i] = new MotionNeighborList(reader);
}
m_ChildNeighborListArray = childNeighborLists.ToArray();
}
}
@@ -251,41 +252,43 @@ namespace AssetStudio
{
var version = reader.version;
if (version >= (4, 1)) //4.1 and up
if (version[0] > 4 || (version[0] == 4 && version[1] >= 1)) //4.1 and up
{
m_BlendType = reader.ReadUInt32();
}
m_BlendEventID = reader.ReadUInt32();
if (version >= (4, 1)) //4.1 and up
if (version[0] > 4 || (version[0] == 4 && version[1] >= 1)) //4.1 and up
{
m_BlendEventYID = reader.ReadUInt32();
}
m_ChildIndices = reader.ReadUInt32Array();
if (version < (4, 1)) //4.1 down
if (version[0] < 4 || (version[0] == 4 && version[1] < 1)) //4.1 down
{
m_ChildThresholdArray = reader.ReadSingleArray();
}
if (version >= (4, 1)) //4.1 and up
if (version[0] > 4 || (version[0] == 4 && version[1] >= 1)) //4.1 and up
{
m_Blend1dData = new Blend1dDataConstant(reader);
m_Blend2dData = new Blend2dDataConstant(reader);
}
if (version >= 5) //5.0 and up
if (version[0] >= 5) //5.0 and up
{
m_BlendDirectData = new BlendDirectDataConstant(reader);
}
m_ClipID = reader.ReadUInt32();
if (version == 4 && version.Minor >= 5) //4.5 - 5.0
if (version[0] == 4 && version[1] >= 5) //4.5 - 5.0
{
m_ClipIndex = reader.ReadUInt32();
}
m_Duration = reader.ReadSingle();
if (version >= (4, 1, 3)) //4.1.3 and up
if (version[0] > 4
|| (version[0] == 4 && version[1] > 1)
|| (version[0] == 4 && version[1] == 1 && version[2] >= 3)) //4.1.3 and up
{
m_CycleOffset = reader.ReadSingle();
m_Mirror = reader.ReadBoolean();
@@ -304,14 +307,13 @@ namespace AssetStudio
var version = reader.version;
int numNodes = reader.ReadInt32();
var nodeList = new List<BlendTreeNodeConstant>();
for (var i = 0; i < numNodes; i++)
m_NodeArray = new BlendTreeNodeConstant[numNodes];
for (int i = 0; i < numNodes; i++)
{
nodeList.Add(new BlendTreeNodeConstant(reader));
m_NodeArray[i] = new BlendTreeNodeConstant(reader);
}
m_NodeArray = nodeList.ToArray();
if (version < (4, 5)) //4.5 down
if (version[0] < 4 || (version[0] == 4 && version[1] < 5)) //4.5 down
{
m_BlendEventArrayConstant = new ValueArrayConstant(reader);
}
@@ -343,71 +345,68 @@ namespace AssetStudio
{
var version = reader.version;
int numTransitions = reader.ReadInt32();
var transitionConstantList = new List<TransitionConstant>();
for (var i = 0; i < numTransitions; i++)
int numTransistions = reader.ReadInt32();
m_TransitionConstantArray = new TransitionConstant[numTransistions];
for (int i = 0; i < numTransistions; i++)
{
transitionConstantList.Add(new TransitionConstant(reader));
m_TransitionConstantArray[i] = new TransitionConstant(reader);
}
m_TransitionConstantArray = transitionConstantList.ToArray();
m_BlendTreeConstantIndexArray = reader.ReadInt32Array();
if (version < (5, 2)) //5.2 down
if (version[0] < 5 || (version[0] == 5 && version[1] < 2)) //5.2 down
{
int numInfos = reader.ReadInt32();
var leafInfoList = new List<LeafInfoConstant>();
for (var i = 0; i < numInfos; i++)
m_LeafInfoArray = new LeafInfoConstant[numInfos];
for (int i = 0; i < numInfos; i++)
{
leafInfoList.Add(new LeafInfoConstant(reader));
m_LeafInfoArray[i] = new LeafInfoConstant(reader);
}
m_LeafInfoArray = leafInfoList.ToArray();
}
int numBlends = reader.ReadInt32();
var blendTreeConstantList = new List<BlendTreeConstant>();
for (var i = 0; i < numBlends; i++)
m_BlendTreeConstantArray = new BlendTreeConstant[numBlends];
for (int i = 0; i < numBlends; i++)
{
blendTreeConstantList.Add(new BlendTreeConstant(reader));
m_BlendTreeConstantArray[i] = new BlendTreeConstant(reader);
}
m_BlendTreeConstantArray = blendTreeConstantList.ToArray();
m_NameID = reader.ReadUInt32();
if (version >= (4, 3)) //4.3 and up
if (version[0] > 4 || (version[0] == 4 && version[1] >= 3)) //4.3 and up
{
m_PathID = reader.ReadUInt32();
}
if (version >= 5) //5.0 and up
if (version[0] >= 5) //5.0 and up
{
m_FullPathID = reader.ReadUInt32();
}
m_TagID = reader.ReadUInt32();
if (version >= (5, 1)) //5.1 and up
if (version[0] > 5 || (version[0] == 5 && version[1] >= 1)) //5.1 and up
{
m_SpeedParamID = reader.ReadUInt32();
m_MirrorParamID = reader.ReadUInt32();
m_CycleOffsetParamID = reader.ReadUInt32();
}
if (version >= (2017, 2)) //2017.2 and up
if (version[0] > 2017 || (version[0] == 2017 && version[1] >= 2)) //2017.2 and up
{
var m_TimeParamID = reader.ReadUInt32();
}
m_Speed = reader.ReadSingle();
if (version >= (4, 1)) //4.1 and up
if (version[0] > 4 || (version[0] == 4 && version[1] >= 1)) //4.1 and up
{
m_CycleOffset = reader.ReadSingle();
}
m_IKOnFeet = reader.ReadBoolean();
if (version >= 5) //5.0 and up
if (version[0] >= 5) //5.0 and up
{
m_WriteDefaultValues = reader.ReadBoolean();
}
m_Loop = reader.ReadBoolean();
if (version >= (4, 1)) //4.1 and up
if (version[0] > 4 || (version[0] == 4 && version[1] >= 1)) //4.1 and up
{
m_Mirror = reader.ReadBoolean();
}
@@ -426,12 +425,11 @@ namespace AssetStudio
m_Destination = reader.ReadUInt32();
int numConditions = reader.ReadInt32();
var conditionConstantList = new List<ConditionConstant>();
for (var i = 0; i < numConditions; i++)
m_ConditionConstantArray = new ConditionConstant[numConditions];
for (int i = 0; i < numConditions; i++)
{
conditionConstantList.Add(new ConditionConstant(reader));
m_ConditionConstantArray[i] = new ConditionConstant(reader);
}
m_ConditionConstantArray = conditionConstantList.ToArray();
}
}
@@ -444,12 +442,11 @@ namespace AssetStudio
public SelectorStateConstant(ObjectReader reader)
{
int numTransitions = reader.ReadInt32();
var transitionConstantList = new List<SelectorTransitionConstant>();
for (var i = 0; i < numTransitions; i++)
m_TransitionConstantArray = new SelectorTransitionConstant[numTransitions];
for (int i = 0; i < numTransitions; i++)
{
transitionConstantList.Add(new SelectorTransitionConstant(reader));
m_TransitionConstantArray[i] = new SelectorTransitionConstant(reader);
}
m_TransitionConstantArray = transitionConstantList.ToArray();
m_FullPathID = reader.ReadUInt32();
m_isEntry = reader.ReadBoolean();
@@ -470,30 +467,27 @@ namespace AssetStudio
var version = reader.version;
int numStates = reader.ReadInt32();
var stateConstantList = new List<StateConstant>();
for (var i = 0; i < numStates; i++)
m_StateConstantArray = new StateConstant[numStates];
for (int i = 0; i < numStates; i++)
{
stateConstantList.Add(new StateConstant(reader));
m_StateConstantArray[i] = new StateConstant(reader);
}
m_StateConstantArray = stateConstantList.ToArray();
int numAnyStates = reader.ReadInt32();
var anyStateTransitionConstantList = new List<TransitionConstant>();
for (var i = 0; i < numAnyStates; i++)
m_AnyStateTransitionConstantArray = new TransitionConstant[numAnyStates];
for (int i = 0; i < numAnyStates; i++)
{
anyStateTransitionConstantList.Add(new TransitionConstant(reader));
m_AnyStateTransitionConstantArray[i] = new TransitionConstant(reader);
}
m_AnyStateTransitionConstantArray = anyStateTransitionConstantList.ToArray();
if (version >= 5) //5.0 and up
if (version[0] >= 5) //5.0 and up
{
int numSelectors = reader.ReadInt32();
var selectorStateConstantList = new List<SelectorStateConstant>();
for (var i = 0; i < numSelectors; i++)
m_SelectorStateConstantArray = new SelectorStateConstant[numSelectors];
for (int i = 0; i < numSelectors; i++)
{
selectorStateConstantList.Add(new SelectorStateConstant(reader));
m_SelectorStateConstantArray[i] = new SelectorStateConstant(reader);
}
m_SelectorStateConstantArray = selectorStateConstantList.ToArray();
}
m_DefaultState = reader.ReadUInt32();
@@ -515,7 +509,7 @@ namespace AssetStudio
{
var version = reader.version;
if (version < (5, 5)) //5.5 down
if (version[0] < 5 || (version[0] == 5 && version[1] < 5)) //5.5 down
{
m_BoolValues = reader.ReadBooleanArray();
reader.AlignStream();
@@ -523,35 +517,29 @@ namespace AssetStudio
m_FloatValues = reader.ReadSingleArray();
}
if (version < (4, 3)) //4.3 down
if (version[0] < 4 || (version[0] == 4 && version[1] < 3)) //4.3 down
{
m_VectorValues = reader.ReadVector4Array();
}
else
{
int numPosValues = reader.ReadInt32();
var positionValuesList = new List<Vector3>();
for (var i = 0; i < numPosValues; i++)
m_PositionValues = new Vector3[numPosValues];
for (int i = 0; i < numPosValues; i++)
{
positionValuesList.Add(version >= (5, 4) //5.4 and up
? reader.ReadVector3()
: (Vector3)reader.ReadVector4());
m_PositionValues[i] = version[0] > 5 || (version[0] == 5 && version[1] >= 4) ? reader.ReadVector3() : (Vector3)reader.ReadVector4(); //5.4 and up
}
m_PositionValues = positionValuesList.ToArray();
m_QuaternionValues = reader.ReadVector4Array();
int numScaleValues = reader.ReadInt32();
var scaleValuesList = new List<Vector3>();
for (var i = 0; i < numScaleValues; i++)
m_ScaleValues = new Vector3[numScaleValues];
for (int i = 0; i < numScaleValues; i++)
{
scaleValuesList.Add(version >= (5, 4) //5.4 and up
? reader.ReadVector3()
: (Vector3)reader.ReadVector4());
m_ScaleValues[i] = version[0] > 5 || (version[0] == 5 && version[1] >= 4) ? reader.ReadVector3() : (Vector3)reader.ReadVector4(); //5.4 and up
}
m_ScaleValues = scaleValuesList.ToArray();
if (version >= (5, 5)) //5.5 and up
if (version[0] > 5 || (version[0] == 5 && version[1] >= 5)) //5.5 and up
{
m_FloatValues = reader.ReadSingleArray();
m_IntValues = reader.ReadInt32Array();
@@ -572,20 +560,18 @@ namespace AssetStudio
public ControllerConstant(ObjectReader reader)
{
int numLayers = reader.ReadInt32();
var layerList = new List<LayerConstant>();
for (var i = 0; i < numLayers; i++)
m_LayerArray = new LayerConstant[numLayers];
for (int i = 0; i < numLayers; i++)
{
layerList.Add(new LayerConstant(reader));
m_LayerArray[i] = new LayerConstant(reader);
}
m_LayerArray = layerList.ToArray();
int numStates = reader.ReadInt32();
var stateMachineList = new List<StateMachineConstant>();
for (var i = 0; i < numStates; i++)
m_StateMachineArray = new StateMachineConstant[numStates];
for (int i = 0; i < numStates; i++)
{
stateMachineList.Add(new StateMachineConstant(reader));
m_StateMachineArray[i] = new StateMachineConstant(reader);
}
m_StateMachineArray = stateMachineList.ToArray();
m_Values = new ValueArrayConstant(reader);
m_DefaultValues = new ValueArray(reader);
@@ -594,8 +580,7 @@ namespace AssetStudio
public sealed class AnimatorController : RuntimeAnimatorController
{
public List<PPtr<AnimationClip>> m_AnimationClips;
public List<KeyValuePair<uint, string>> m_TOS;
public PPtr<AnimationClip>[] m_AnimationClips;
public AnimatorController(ObjectReader reader) : base(reader)
{
@@ -603,17 +588,17 @@ namespace AssetStudio
var m_Controller = new ControllerConstant(reader);
int tosSize = reader.ReadInt32();
m_TOS = new List<KeyValuePair<uint, string>>();
for (var i = 0; i < tosSize; i++)
var m_TOS = new KeyValuePair<uint, string>[tosSize];
for (int i = 0; i < tosSize; i++)
{
m_TOS.Add(new KeyValuePair<uint, string>(reader.ReadUInt32(), reader.ReadAlignedString()));
m_TOS[i] = new KeyValuePair<uint, string>(reader.ReadUInt32(), reader.ReadAlignedString());
}
int numClips = reader.ReadInt32();
m_AnimationClips = new List<PPtr<AnimationClip>>();
for (var i = 0; i < numClips; i++)
m_AnimationClips = new PPtr<AnimationClip>[numClips];
for (int i = 0; i < numClips; i++)
{
m_AnimationClips.Add(new PPtr<AnimationClip>(reader));
m_AnimationClips[i] = new PPtr<AnimationClip>(reader);
}
}
}

View File

@@ -1,4 +1,7 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AssetStudio
{
@@ -17,17 +20,17 @@ namespace AssetStudio
public sealed class AnimatorOverrideController : RuntimeAnimatorController
{
public PPtr<RuntimeAnimatorController> m_Controller;
public List<AnimationClipOverride> m_Clips;
public AnimationClipOverride[] m_Clips;
public AnimatorOverrideController(ObjectReader reader) : base(reader)
{
m_Controller = new PPtr<RuntimeAnimatorController>(reader);
int numOverrides = reader.ReadInt32();
m_Clips = new List<AnimationClipOverride>();
for (var i = 0; i < numOverrides; i++)
m_Clips = new AnimationClipOverride[numOverrides];
for (int i = 0; i < numOverrides; i++)
{
m_Clips.Add(new AnimationClipOverride(reader));
m_Clips[i] = new AnimationClipOverride(reader);
}
}
}

View File

@@ -18,8 +18,8 @@ namespace AssetStudio
public sealed class AssetBundle : NamedObject
{
public List<PPtr<Object>> m_PreloadTable;
public List<KeyValuePair<string, AssetInfo>> m_Container;
public PPtr<Object>[] m_PreloadTable;
public KeyValuePair<string, AssetInfo>[] m_Container;
public string m_AssetBundleName;
public string[] m_Dependencies;
public bool m_IsStreamedSceneAssetBundle;
@@ -27,41 +27,37 @@ namespace AssetStudio
public AssetBundle(ObjectReader reader) : base(reader)
{
var m_PreloadTableSize = reader.ReadInt32();
m_PreloadTable = new List<PPtr<Object>>();
m_PreloadTable = new PPtr<Object>[m_PreloadTableSize];
for (var i = 0; i < m_PreloadTableSize; i++)
{
m_PreloadTable.Add(new PPtr<Object>(reader));
m_PreloadTable[i] = new PPtr<Object>(reader);
}
var m_ContainerSize = reader.ReadInt32();
m_Container = new List<KeyValuePair<string, AssetInfo>>();
m_Container = new KeyValuePair<string, AssetInfo>[m_ContainerSize];
for (var i = 0; i < m_ContainerSize; i++)
{
m_Container.Add(new KeyValuePair<string, AssetInfo>(reader.ReadAlignedString(), new AssetInfo(reader)));
m_Container[i] = new KeyValuePair<string, AssetInfo>(reader.ReadAlignedString(), new AssetInfo(reader));
}
var m_MainAsset = new AssetInfo(reader);
if (version == (5, 4)) //5.4.x
{
var m_ClassVersionMapSize = reader.ReadInt32();
for (var i = 0; i < m_ClassVersionMapSize; i++)
{
var first = reader.ReadInt32();
var second = reader.ReadInt32();
}
}
if (version >= (4, 2)) //4.2 and up
if (version[0] > 4 || (version[0] == 4 && version[1] >= 2)) //4.2 and up
{
var m_RuntimeCompatibility = reader.ReadUInt32();
}
if (version >= 5) //5.0 and up
if (version[0] >= 5) //5.0 and up
{
m_AssetBundleName = reader.ReadAlignedString();
m_Dependencies = reader.ReadStringArray();
var m_DependenciesSize = reader.ReadInt32();
m_Dependencies = new string[m_DependenciesSize];
for (var i = 0; i < m_DependenciesSize; i++)
{
m_Dependencies[i] = reader.ReadAlignedString();
}
m_IsStreamedSceneAssetBundle = reader.ReadBoolean();
}

View File

@@ -1,4 +1,10 @@
namespace AssetStudio
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
namespace AssetStudio
{
public sealed class AudioClip : NamedObject
{
@@ -27,23 +33,15 @@
public AudioClip(ObjectReader reader) : base(reader)
{
if (version < 5)
if (version[0] < 5)
{
m_Format = reader.ReadInt32();
if (version >= (2, 6)) //2.6 to 5
{
m_Type = (FMODSoundType)reader.ReadInt32();
m_3D = reader.ReadBoolean();
m_UseHardware = reader.ReadBoolean();
reader.AlignStream();
}
else
{
m_Length = reader.ReadSingle();
m_Frequency = reader.ReadInt32();
m_Channels = m_Format != 0x05 ? m_Format >> 1 : 0;
}
if (version >= (3, 2)) //3.2.0 to 5
m_Type = (FMODSoundType)reader.ReadInt32();
m_3D = reader.ReadBoolean();
m_UseHardware = reader.ReadBoolean();
reader.AlignStream();
if (version[0] >= 4 || (version[0] == 3 && version[1] >= 2)) //3.2.0 to 5
{
int m_Stream = reader.ReadInt32();
m_Size = reader.ReadInt32();
@@ -97,7 +95,7 @@
public enum FMODSoundType
{
UNKNOWN = 0,
AAC = 1,
ACC = 1,
AIFF = 2,
ASF = 3,
AT3 = 4,

View File

@@ -23,7 +23,7 @@ namespace AssetStudio
public Limit(ObjectReader reader)
{
var version = reader.version;
if (version >= (5, 4))//5.4 and up
if (version[0] > 5 || (version[0] == 5 && version[1] >= 4))//5.4 and up
{
m_Min = reader.ReadVector3();
m_Max = reader.ReadVector3();
@@ -50,7 +50,7 @@ namespace AssetStudio
var version = reader.version;
m_PreQ = reader.ReadVector4();
m_PostQ = reader.ReadVector4();
if (version >= (5, 4)) //5.4 and up
if (version[0] > 5 || (version[0] == 5 && version[1] >= 4)) //5.4 and up
{
m_Sgn = reader.ReadVector3();
}
@@ -66,7 +66,7 @@ namespace AssetStudio
public class Skeleton
{
public List<Node> m_Node;
public Node[] m_Node;
public uint[] m_ID;
public Axes[] m_AxesArray;
@@ -74,35 +74,34 @@ namespace AssetStudio
public Skeleton(ObjectReader reader)
{
int numNodes = reader.ReadInt32();
m_Node = new List<Node>();
for (var i = 0; i < numNodes; i++)
m_Node = new Node[numNodes];
for (int i = 0; i < numNodes; i++)
{
m_Node.Add(new Node(reader));
m_Node[i] = new Node(reader);
}
m_ID = reader.ReadUInt32Array();
int numAxes = reader.ReadInt32();
var axesList = new List<Axes>();
for (var i = 0; i < numAxes; i++)
m_AxesArray = new Axes[numAxes];
for (int i = 0; i < numAxes; i++)
{
axesList.Add(new Axes(reader));
m_AxesArray[i] = new Axes(reader);
}
m_AxesArray = axesList.ToArray();
}
}
public class SkeletonPose
{
public List<xform> m_X;
public xform[] m_X;
public SkeletonPose(ObjectReader reader)
{
int numXforms = reader.ReadInt32();
m_X = new List<xform>();
for (var i = 0; i < numXforms; i++)
m_X = new xform[numXforms];
for (int i = 0; i < numXforms; i++)
{
m_X.Add(new xform(reader));
m_X[i] = new xform(reader);
}
}
}
@@ -164,7 +163,7 @@ namespace AssetStudio
public SkeletonPose m_SkeletonPose;
public Hand m_LeftHand;
public Hand m_RightHand;
public List<Handle> m_Handles;
public Handle[] m_Handles;
public Collider[] m_ColliderArray;
public int[] m_HumanBoneIndex;
public float[] m_HumanBoneMass;
@@ -190,29 +189,28 @@ namespace AssetStudio
m_LeftHand = new Hand(reader);
m_RightHand = new Hand(reader);
if (version < (2018, 2)) //2018.2 down
if (version[0] < 2018 || (version[0] == 2018 && version[1] < 2)) //2018.2 down
{
int numHandles = reader.ReadInt32();
m_Handles = new List<Handle>();
for (var i = 0; i < numHandles; i++)
m_Handles = new Handle[numHandles];
for (int i = 0; i < numHandles; i++)
{
m_Handles.Add(new Handle(reader));
m_Handles[i] = new Handle(reader);
}
int numColliders = reader.ReadInt32();
var colliderList = new List<Collider>();
for (var i = 0; i < numColliders; i++)
m_ColliderArray = new Collider[numColliders];
for (int i = 0; i < numColliders; i++)
{
colliderList.Add(new Collider(reader));
m_ColliderArray[i] = new Collider(reader);
}
m_ColliderArray = colliderList.ToArray();
}
m_HumanBoneIndex = reader.ReadInt32Array();
m_HumanBoneMass = reader.ReadSingleArray();
if (version < (2018, 2)) //2018.2 down
if (version[0] < 2018 || (version[0] == 2018 && version[1] < 2)) //2018.2 down
{
m_ColliderIndex = reader.ReadInt32Array();
}
@@ -227,7 +225,7 @@ namespace AssetStudio
m_FeetSpacing = reader.ReadSingle();
m_HasLeftHand = reader.ReadBoolean();
m_HasRightHand = reader.ReadBoolean();
if (version >= (5, 2)) //5.2 and up
if (version[0] > 5 || (version[0] == 5 && version[1] >= 2)) //5.2 and up
{
m_HasTDoF = reader.ReadBoolean();
}
@@ -256,7 +254,7 @@ namespace AssetStudio
m_AvatarSkeleton = new Skeleton(reader);
m_AvatarSkeletonPose = new SkeletonPose(reader);
if (version >= (4, 3)) //4.3 and up
if (version[0] > 4 || (version[0] == 4 && version[1] >= 3)) //4.3 and up
{
m_DefaultPose = new SkeletonPose(reader);
@@ -267,7 +265,7 @@ namespace AssetStudio
m_HumanSkeletonIndexArray = reader.ReadInt32Array();
if (version >= (4, 3)) //4.3 and up
if (version[0] > 4 || (version[0] == 4 && version[1] >= 3)) //4.3 and up
{
m_HumanSkeletonReverseIndexArray = reader.ReadInt32Array();
}
@@ -275,7 +273,7 @@ namespace AssetStudio
m_RootMotionBoneIndex = reader.ReadInt32();
m_RootMotionBoneX = new xform(reader);
if (version >= (4, 3)) //4.3 and up
if (version[0] > 4 || (version[0] == 4 && version[1] >= 3)) //4.3 and up
{
m_RootMotionSkeleton = new Skeleton(reader);
m_RootMotionSkeletonPose = new SkeletonPose(reader);
@@ -289,7 +287,7 @@ namespace AssetStudio
{
public uint m_AvatarSize;
public AvatarConstant m_Avatar;
public List<KeyValuePair<uint, string>> m_TOS;
public KeyValuePair<uint, string>[] m_TOS;
public Avatar(ObjectReader reader) : base(reader)
{
@@ -297,10 +295,10 @@ namespace AssetStudio
m_Avatar = new AvatarConstant(reader);
int numTOS = reader.ReadInt32();
m_TOS = new List<KeyValuePair<uint, string>>();
for (var i = 0; i < numTOS; i++)
m_TOS = new KeyValuePair<uint, string>[numTOS];
for (int i = 0; i < numTOS; i++)
{
m_TOS.Add(new KeyValuePair<uint, string>(reader.ReadUInt32(), reader.ReadAlignedString()));
m_TOS[i] = new KeyValuePair<uint, string>(reader.ReadUInt32(), reader.ReadAlignedString());
}
//HumanDescription m_HumanDescription 2019 and up

View File

@@ -1,11 +1,14 @@
namespace AssetStudio
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AssetStudio
{
public abstract class Behaviour : Component
{
public byte m_Enabled;
public Behaviour() { }
protected Behaviour(ObjectReader reader) : base(reader)
{
m_Enabled = reader.ReadByte();

View File

@@ -1,20 +1,24 @@
namespace AssetStudio
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AssetStudio
{
public sealed class BuildSettings : Object
{
public string[] levels;
public string[] scenes;
public string m_Version;
public BuildSettings(ObjectReader reader) : base(reader)
{
if (reader.version < (5, 1)) //5.1 down
{
levels = reader.ReadStringArray();
}
else
{
scenes = reader.ReadStringArray();
}
var levels = reader.ReadStringArray();
var hasRenderTexture = reader.ReadBoolean();
var hasPROVersion = reader.ReadBoolean();
var hasPublishingRights = reader.ReadBoolean();
var hasShadows = reader.ReadBoolean();
m_Version = reader.ReadAlignedString();
}
}
}

View File

@@ -1,11 +1,14 @@
namespace AssetStudio
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AssetStudio
{
public abstract class Component : EditorExtension
{
public PPtr<GameObject> m_GameObject;
public Component() { }
protected Component(ObjectReader reader) : base(reader)
{
m_GameObject = new PPtr<GameObject>(reader);

View File

@@ -1,9 +1,12 @@
namespace AssetStudio
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AssetStudio
{
public abstract class EditorExtension : Object
{
protected EditorExtension() { }
protected EditorExtension(ObjectReader reader) : base(reader)
{
if (platform == BuildTarget.NoTarget)

View File

@@ -1,4 +1,9 @@
namespace AssetStudio
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AssetStudio
{
public sealed class Font : NamedObject
{
@@ -6,7 +11,7 @@
public Font(ObjectReader reader) : base(reader)
{
if (version >= (5, 5))//5.5 and up
if ((version[0] == 5 && version[1] >= 5) || version[0] > 5)//5.5 and up
{
var m_LineSpacing = reader.ReadSingle();
var m_DefaultMaterial = new PPtr<Material>(reader);
@@ -18,12 +23,12 @@
var m_CharacterPadding = reader.ReadInt32();
var m_ConvertCase = reader.ReadInt32();
int m_CharacterRects_size = reader.ReadInt32();
for (var i = 0; i < m_CharacterRects_size; i++)
for (int i = 0; i < m_CharacterRects_size; i++)
{
reader.Position += 44;//CharacterInfo data 41
}
int m_KerningValues_size = reader.ReadInt32();
for (var i = 0; i < m_KerningValues_size; i++)
for (int i = 0; i < m_KerningValues_size; i++)
{
reader.Position += 8;
}
@@ -38,7 +43,7 @@
{
int m_AsciiStartOffset = reader.ReadInt32();
if (version <= 3)
if (version[0] <= 3)
{
int m_FontCountX = reader.ReadInt32();
int m_FontCountY = reader.ReadInt32();
@@ -47,10 +52,10 @@
float m_Kerning = reader.ReadSingle();
float m_LineSpacing = reader.ReadSingle();
if (version <= 3)
if (version[0] <= 3)
{
int m_PerCharacterKerning_size = reader.ReadInt32();
for (var i = 0; i < m_PerCharacterKerning_size; i++)
for (int i = 0; i < m_PerCharacterKerning_size; i++)
{
int first = reader.ReadInt32();
float second = reader.ReadSingle();
@@ -66,7 +71,7 @@
var m_DefaultMaterial = new PPtr<Material>(reader);
int m_CharacterRects_size = reader.ReadInt32();
for (var i = 0; i < m_CharacterRects_size; i++)
for (int i = 0; i < m_CharacterRects_size; i++)
{
int index = reader.ReadInt32();
//Rectf uv
@@ -81,7 +86,7 @@
float vertheight = reader.ReadSingle();
float width = reader.ReadSingle();
if (version >= 4)
if (version[0] >= 4)
{
var flipped = reader.ReadBoolean();
reader.AlignStream();
@@ -91,14 +96,14 @@
var m_Texture = new PPtr<Texture>(reader);
int m_KerningValues_size = reader.ReadInt32();
for (var i = 0; i < m_KerningValues_size; i++)
for (int i = 0; i < m_KerningValues_size; i++)
{
int pairfirst = reader.ReadInt16();
int pairsecond = reader.ReadInt16();
float second = reader.ReadSingle();
}
if (version <= 3)
if (version[0] <= 3)
{
var m_GridFont = reader.ReadBoolean();
reader.AlignStream();

View File

@@ -1,35 +0,0 @@
using System.Text.Json.Serialization;
namespace AssetStudio
{
public class GLTextureSettings
{
public int m_FilterMode;
public int m_Aniso;
public float m_MipBias;
public int m_WrapMode;
[JsonInclude]
private int m_WrapU { set => m_WrapMode = value; }
public GLTextureSettings() { }
public GLTextureSettings(ObjectReader reader)
{
var version = reader.version;
m_FilterMode = reader.ReadInt32();
m_Aniso = reader.ReadInt32();
m_MipBias = reader.ReadSingle();
if (version >= 2017)//2017.x and up
{
m_WrapMode = reader.ReadInt32(); //m_WrapU
var m_WrapV = reader.ReadInt32();
var m_WrapW = reader.ReadInt32();
}
else
{
m_WrapMode = reader.ReadInt32();
}
}
}
}

View File

@@ -1,11 +1,13 @@
using System.Collections.Generic;
using System.Text.Json.Serialization;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AssetStudio
{
public sealed class GameObject : EditorExtension
{
public List<PPtr<Component>> m_Components;
public PPtr<Component>[] m_Components;
public string m_Name;
public Transform m_Transform;
@@ -14,28 +16,21 @@ namespace AssetStudio
public SkinnedMeshRenderer m_SkinnedMeshRenderer;
public Animator m_Animator;
public Animation m_Animation;
[JsonIgnore]
public CubismModel CubismModel;
public GameObject(ObjectReader reader) : base(reader)
{
var m_ComponentSize = reader.ReadInt32();
m_Components = new List<PPtr<Component>>();
for (var i = 0; i < m_ComponentSize; i++)
int m_Component_size = reader.ReadInt32();
m_Components = new PPtr<Component>[m_Component_size];
for (int i = 0; i < m_Component_size; i++)
{
if (version < (5, 5)) //5.5 down
if ((version[0] == 5 && version[1] < 5) || version[0] < 5) //5.5 down
{
var first = reader.ReadInt32();
int first = reader.ReadInt32();
}
m_Components.Add(new PPtr<Component>(reader));
m_Components[i] = new PPtr<Component>(reader);
}
var m_Layer = reader.ReadInt32();
if (version.IsTuanjie && (version > (2022, 3, 2) || (version == (2022, 3, 2) && version.Build >= 11))) //2022.3.2t11(1.1.3) and up
{
var m_HasEditorInfo = reader.ReadBoolean();
reader.AlignStream();
}
m_Name = reader.ReadAlignedString();
}
}

View File

@@ -1,711 +0,0 @@
namespace AssetStudio
{
public enum GraphicsFormat
{
/// <summary>
/// The format is not specified.
/// </summary>
None,
/// <summary>
/// A one-component, 8-bit unsigned normalized format that has a single 8-bit R component stored with sRGB nonlinear encoding.
/// </summary>
R8_SRGB,
/// <summary>
/// A two-component, 16-bit unsigned normalized format that has an 8-bit R component stored with sRGB nonlinear encoding in byte 0, and an 8-bit G component stored with sRGB nonlinear encoding in byte 1.
/// </summary>
R8G8_SRGB,
/// <summary>
/// A three-component, 24-bit unsigned normalized format that has an 8-bit R component stored with sRGB nonlinear encoding in byte 0, an 8-bit G component stored with sRGB nonlinear encoding in byte 1, and an 8-bit B component stored with sRGB nonlinear encoding in byte 2.
/// </summary>
R8G8B8_SRGB,
/// <summary>
/// A four-component, 32-bit unsigned normalized format that has an 8-bit R component stored with sRGB nonlinear encoding in byte 0, an 8-bit G component stored with sRGB nonlinear encoding in byte 1, an 8-bit B component stored with sRGB nonlinear encoding in byte 2, and an 8-bit A component in byte 3.
/// </summary>
R8G8B8A8_SRGB,
/// <summary>
/// A one-component, 8-bit unsigned normalized format that has a single 8-bit R component.
/// </summary>
R8_UNorm,
/// <summary>
/// A two-component, 16-bit unsigned normalized format that has an 8-bit R component stored with sRGB nonlinear encoding in byte 0, and an 8-bit G component stored with sRGB nonlinear encoding in byte 1.
/// </summary>
R8G8_UNorm,
/// <summary>
/// A three-component, 24-bit unsigned normalized format that has an 8-bit R component in byte 0, an 8-bit G component in byte 1, and an 8-bit B component in byte 2.
/// </summary>
R8G8B8_UNorm,
/// <summary>
/// A four-component, 32-bit unsigned normalized format that has an 8-bit R component in byte 0, an 8-bit G component in byte 1, an 8-bit B component in byte 2, and an 8-bit A component in byte 3.
/// </summary>
R8G8B8A8_UNorm,
/// <summary>
/// A one-component, 8-bit signed normalized format that has a single 8-bit R component.
/// </summary>
R8_SNorm,
/// <summary>
/// A two-component, 16-bit signed normalized format that has an 8-bit R component stored with sRGB nonlinear encoding in byte 0, and an 8-bit G component stored with sRGB nonlinear encoding in byte 1.
/// </summary>
R8G8_SNorm,
/// <summary>
/// A three-component, 24-bit signed normalized format that has an 8-bit R component in byte 0, an 8-bit G component in byte 1, and an 8-bit B component in byte 2.
/// </summary>
R8G8B8_SNorm,
/// <summary>
/// A four-component, 32-bit signed normalized format that has an 8-bit R component in byte 0, an 8-bit G component in byte 1, an 8-bit B component in byte 2, and an 8-bit A component in byte 3.
/// </summary>
R8G8B8A8_SNorm,
/// <summary>
/// A one-component, 8-bit unsigned integer format that has a single 8-bit R component.
/// </summary>
R8_UInt,
/// <summary>
/// A two-component, 16-bit unsigned integer format that has an 8-bit R component in byte 0, and an 8-bit G component in byte 1.
/// </summary>
R8G8_UInt,
/// <summary>
/// A three-component, 24-bit unsigned integer format that has an 8-bit R component in byte 0, an 8-bit G component in byte 1, and an 8-bit B component in byte 2.
/// </summary>
R8G8B8_UInt,
/// <summary>
/// A four-component, 32-bit unsigned integer format that has an 8-bit R component in byte 0, an 8-bit G component in byte 1, an 8-bit B component in byte 2, and an 8-bit A component in byte 3.
/// </summary>
R8G8B8A8_UInt,
/// <summary>
/// A one-component, 8-bit signed integer format that has a single 8-bit R component.
/// </summary>
R8_SInt,
/// <summary>
/// A two-component, 16-bit signed integer format that has an 8-bit R component in byte 0, and an 8-bit G component in byte 1.
/// </summary>
R8G8_SInt,
/// <summary>
/// A three-component, 24-bit signed integer format that has an 8-bit R component in byte 0, an 8-bit G component in byte 1, and an 8-bit B component in byte 2.
/// </summary>
R8G8B8_SInt,
/// <summary>
/// A four-component, 32-bit signed integer format that has an 8-bit R component in byte 0, an 8-bit G component in byte 1, an 8-bit B component in byte 2, and an 8-bit A component in byte 3.
/// </summary>
R8G8B8A8_SInt,
/// <summary>
/// A one-component, 16-bit unsigned normalized format that has a single 16-bit R component.
/// </summary>
R16_UNorm,
/// <summary>
/// A two-component, 32-bit unsigned normalized format that has a 16-bit R component in bytes 0..1, and a 16-bit G component in bytes 2..3.
/// </summary>
R16G16_UNorm,
/// <summary>
/// A three-component, 48-bit unsigned normalized format that has a 16-bit R component in bytes 0..1, a 16-bit G component in bytes 2..3, and a 16-bit B component in bytes 4..5.
/// </summary>
R16G16B16_UNorm,
/// <summary>
/// A four-component, 64-bit unsigned normalized format that has a 16-bit R component in bytes 0..1, a 16-bit G component in bytes 2..3, a 16-bit B component in bytes 4..5, and a 16-bit A component in bytes 6..7.
/// </summary>
R16G16B16A16_UNorm,
/// <summary>
/// A one-component, 16-bit signed normalized format that has a single 16-bit R component.
/// </summary>
R16_SNorm,
/// <summary>
/// A two-component, 32-bit signed normalized format that has a 16-bit R component in bytes 0..1, and a 16-bit G component in bytes 2..3.
/// </summary>
R16G16_SNorm,
/// <summary>
/// A three-component, 48-bit signed normalized format that has a 16-bit R component in bytes 0..1, a 16-bit G component in bytes 2..3, and a 16-bit B component in bytes 4..5.
/// </summary>
R16G16B16_SNorm,
/// <summary>
/// A four-component, 64-bit signed normalized format that has a 16-bit R component in bytes 0..1, a 16-bit G component in bytes 2..3, a 16-bit B component in bytes 4..5, and a 16-bit A component in bytes 6..7.
/// </summary>
R16G16B16A16_SNorm,
/// <summary>
/// A one-component, 16-bit unsigned integer format that has a single 16-bit R component.
/// </summary>
R16_UInt,
/// <summary>
/// A two-component, 32-bit unsigned integer format that has a 16-bit R component in bytes 0..1, and a 16-bit G component in bytes 2..3.
/// </summary>
R16G16_UInt,
/// <summary>
/// A three-component, 48-bit unsigned integer format that has a 16-bit R component in bytes 0..1, a 16-bit G component in bytes 2..3, and a 16-bit B component in bytes 4..5.
/// </summary>
R16G16B16_UInt,
/// <summary>
/// A four-component, 64-bit unsigned integer format that has a 16-bit R component in bytes 0..1, a 16-bit G component in bytes 2..3, a 16-bit B component in bytes 4..5, and a 16-bit A component in bytes 6..7.
/// </summary>
R16G16B16A16_UInt,
/// <summary>
/// A one-component, 16-bit signed integer format that has a single 16-bit R component.
/// </summary>
R16_SInt,
/// <summary>
/// A two-component, 32-bit signed integer format that has a 16-bit R component in bytes 0..1, and a 16-bit G component in bytes 2..3.
/// </summary>
R16G16_SInt,
/// <summary>
/// A three-component, 48-bit signed integer format that has a 16-bit R component in bytes 0..1, a 16-bit G component in bytes 2..3, and a 16-bit B component in bytes 4..5.
/// </summary>
R16G16B16_SInt,
/// <summary>
/// A four-component, 64-bit signed integer format that has a 16-bit R component in bytes 0..1, a 16-bit G component in bytes 2..3, a 16-bit B component in bytes 4..5, and a 16-bit A component in bytes 6..7.
/// </summary>
R16G16B16A16_SInt,
/// <summary>
/// A one-component, 32-bit unsigned integer format that has a single 32-bit R component.
/// </summary>
R32_UInt,
/// <summary>
/// A two-component, 64-bit unsigned integer format that has a 32-bit R component in bytes 0..3, and a 32-bit G component in bytes 4..7.
/// </summary>
R32G32_UInt,
/// <summary>
/// A three-component, 96-bit unsigned integer format that has a 32-bit R component in bytes 0..3, a 32-bit G component in bytes 4..7, and a 32-bit B component in bytes 8..11.
/// </summary>
R32G32B32_UInt,
/// <summary>
/// A four-component, 128-bit unsigned integer format that has a 32-bit R component in bytes 0..3, a 32-bit G component in bytes 4..7, a 32-bit B component in bytes 8..11, and a 32-bit A component in bytes 12..15.
/// </summary>
R32G32B32A32_UInt,
/// <summary>
/// A one-component, 32-bit signed integer format that has a single 32-bit R component.
/// </summary>
R32_SInt,
/// <summary>
/// A two-component, 64-bit signed integer format that has a 32-bit R component in bytes 0..3, and a 32-bit G component in bytes 4..7.
/// </summary>
R32G32_SInt,
/// <summary>
/// A three-component, 96-bit signed integer format that has a 32-bit R component in bytes 0..3, a 32-bit G component in bytes 4..7, and a 32-bit B component in bytes 8..11.
/// </summary>
R32G32B32_SInt,
/// <summary>
/// A four-component, 128-bit signed integer format that has a 32-bit R component in bytes 0..3, a 32-bit G component in bytes 4..7, a 32-bit B component in bytes 8..11, and a 32-bit A component in bytes 12..15.
/// </summary>
R32G32B32A32_SInt,
/// <summary>
/// A one-component, 16-bit signed floating-point format that has a single 16-bit R component.
/// </summary>
R16_SFloat,
/// <summary>
/// A two-component, 32-bit signed floating-point format that has a 16-bit R component in bytes 0..1, and a 16-bit G component in bytes 2..3.
/// </summary>
R16G16_SFloat,
/// <summary>
/// A three-component, 48-bit signed floating-point format that has a 16-bit R component in bytes 0..1, a 16-bit G component in bytes 2..3, and a 16-bit B component in bytes 4..5.
/// </summary>
R16G16B16_SFloat,
/// <summary>
/// A four-component, 64-bit signed floating-point format that has a 16-bit R component in bytes 0..1, a 16-bit G component in bytes 2..3, a 16-bit B component in bytes 4..5, and a 16-bit A component in bytes 6..7.
/// </summary>
R16G16B16A16_SFloat,
/// <summary>
/// A one-component, 32-bit signed floating-point format that has a single 32-bit R component.
/// </summary>
R32_SFloat,
/// <summary>
/// A two-component, 64-bit signed floating-point format that has a 32-bit R component in bytes 0..3, and a 32-bit G component in bytes 4..7.
/// </summary>
R32G32_SFloat,
/// <summary>
/// A three-component, 96-bit signed floating-point format that has a 32-bit R component in bytes 0..3, a 32-bit G component in bytes 4..7, and a 32-bit B component in bytes 8..11.
/// </summary>
R32G32B32_SFloat,
/// <summary>
/// A four-component, 128-bit signed floating-point format that has a 32-bit R component in bytes 0..3, a 32-bit G component in bytes 4..7, a 32-bit B component in bytes 8..11, and a 32-bit A component in bytes 12..15.
/// </summary>
R32G32B32A32_SFloat,
/// <summary>
/// A three-component, 24-bit unsigned normalized format that has an 8-bit B component stored with sRGB nonlinear encoding in byte 0, an 8-bit G component stored with sRGB nonlinear encoding in byte 1, and an 8-bit R component stored with sRGB nonlinear encoding in byte 2.
/// </summary>
B8G8R8_SRGB = 56,
/// <summary>
/// A four-component, 32-bit unsigned normalized format that has an 8-bit B component stored with sRGB nonlinear encoding in byte 0, an 8-bit G component stored with sRGB nonlinear encoding in byte 1, an 8-bit R component stored with sRGB nonlinear encoding in byte 2, and an 8-bit A component in byte 3.
/// </summary>
B8G8R8A8_SRGB,
/// <summary>
/// A three-component, 24-bit unsigned normalized format that has an 8-bit B component in byte 0, an 8-bit G component in byte 1, and an 8-bit R component in byte 2.
/// </summary>
B8G8R8_UNorm,
/// <summary>
/// A four-component, 32-bit unsigned normalized format that has an 8-bit B component in byte 0, an 8-bit G component in byte 1, an 8-bit R component in byte 2, and an 8-bit A component in byte 3.
/// </summary>
B8G8R8A8_UNorm,
/// <summary>
/// A three-component, 24-bit signed normalized format that has an 8-bit B component in byte 0, an 8-bit G component in byte 1, and an 8-bit R component in byte 2.
/// </summary>
B8G8R8_SNorm,
/// <summary>
/// A four-component, 32-bit signed normalized format that has an 8-bit B component in byte 0, an 8-bit G component in byte 1, an 8-bit R component in byte 2, and an 8-bit A component in byte 3.
/// </summary>
B8G8R8A8_SNorm,
/// <summary>
/// A three-component, 24-bit unsigned integer format that has an 8-bit B component in byte 0, an 8-bit G component in byte 1, and an 8-bit R component in byte 2
/// </summary>
B8G8R8_UInt,
/// <summary>
/// A four-component, 32-bit unsigned integer format that has an 8-bit B component in byte 0, an 8-bit G component in byte 1, an 8-bit R component in byte 2, and an 8-bit A component in byte 3.
/// </summary>
B8G8R8A8_UInt,
/// <summary>
/// A three-component, 24-bit signed integer format that has an 8-bit B component in byte 0, an 8-bit G component in byte 1, and an 8-bit R component in byte 2.
/// </summary>
B8G8R8_SInt,
/// <summary>
/// A four-component, 32-bit signed integer format that has an 8-bit B component in byte 0, an 8-bit G component in byte 1, an 8-bit R component in byte 2, and an 8-bit A component in byte 3.
/// </summary>
B8G8R8A8_SInt,
/// <summary>
/// A four-component, 16-bit packed unsigned normalized format that has a 4-bit R component in bits 12..15, a 4-bit G component in bits 8..11, a 4-bit B component in bits 4..7, and a 4-bit A component in bits 0..3.
/// </summary>
R4G4B4A4_UNormPack16,
/// <summary>
/// A four-component, 16-bit packed unsigned normalized format that has a 4-bit B component in bits 12..15, a 4-bit G component in bits 8..11, a 4-bit R component in bits 4..7, and a 4-bit A component in bits 0..3.
/// </summary>
B4G4R4A4_UNormPack16,
/// <summary>
/// A three-component, 16-bit packed unsigned normalized format that has a 5-bit R component in bits 11..15, a 6-bit G component in bits 5..10, and a 5-bit B component in bits 0..4.
/// </summary>
R5G6B5_UNormPack16,
/// <summary>
/// A three-component, 16-bit packed unsigned normalized format that has a 5-bit B component in bits 11..15, a 6-bit G component in bits 5..10, and a 5-bit R component in bits 0..4.
/// </summary>
B5G6R5_UNormPack16,
/// <summary>
/// A four-component, 16-bit packed unsigned normalized format that has a 5-bit R component in bits 11..15, a 5-bit G component in bits 6..10, a 5-bit B component in bits 1..5, and a 1-bit A component in bit 0.
/// </summary>
R5G5B5A1_UNormPack16,
/// <summary>
/// A four-component, 16-bit packed unsigned normalized format that has a 5-bit B component in bits 11..15, a 5-bit G component in bits 6..10, a 5-bit R component in bits 1..5, and a 1-bit A component in bit 0.
/// </summary>
B5G5R5A1_UNormPack16,
/// <summary>
/// A four-component, 16-bit packed unsigned normalized format that has a 1-bit A component in bit 15, a 5-bit R component in bits 10..14, a 5-bit G component in bits 5..9, and a 5-bit B component in bits 0..4.
/// </summary>
A1R5G5B5_UNormPack16,
/// <summary>
/// A three-component, 32-bit packed unsigned floating-point format that has a 5-bit shared exponent in bits 27..31, a 9-bit B component mantissa in bits 18..26, a 9-bit G component mantissa in bits 9..17, and a 9-bit R component mantissa in bits 0..8.
/// </summary>
E5B9G9R9_UFloatPack32,
/// <summary>
/// A three-component, 32-bit packed unsigned floating-point format that has a 10-bit B component in bits 22..31, an 11-bit G component in bits 11..21, an 11-bit R component in bits 0..10.
/// </summary>
B10G11R11_UFloatPack32,
/// <summary>
/// A four-component, 32-bit packed unsigned normalized format that has a 2-bit A component in bits 30..31, a 10-bit B component in bits 20..29, a 10-bit G component in bits 10..19, and a 10-bit R component in bits 0..9.
/// </summary>
A2B10G10R10_UNormPack32,
/// <summary>
/// A four-component, 32-bit packed unsigned integer format that has a 2-bit A component in bits 30..31, a 10-bit B component in bits 20..29, a 10-bit G component in bits 10..19, and a 10-bit R component in bits 0..9.
/// </summary>
A2B10G10R10_UIntPack32,
/// <summary>
/// A four-component, 32-bit packed signed integer format that has a 2-bit A component in bits 30..31, a 10-bit B component in bits 20..29, a 10-bit G component in bits 10..19, and a 10-bit R component in bits 0..9.
/// </summary>
A2B10G10R10_SIntPack32,
/// <summary>
/// A four-component, 32-bit packed unsigned normalized format that has a 2-bit A component in bits 30..31, a 10-bit R component in bits 20..29, a 10-bit G component in bits 10..19, and a 10-bit B component in bits 0..9.
/// </summary>
A2R10G10B10_UNormPack32,
/// <summary>
/// A four-component, 32-bit packed unsigned integer format that has a 2-bit A component in bits 30..31, a 10-bit R component in bits 20..29, a 10-bit G component in bits 10..19, and a 10-bit B component in bits 0..9.
/// </summary>
A2R10G10B10_UIntPack32,
/// <summary>
/// A four-component, 32-bit packed signed integer format that has a 2-bit A component in bits 30..31, a 10-bit R component in bits 20..29, a 10-bit G component in bits 10..19, and a 10-bit B component in bits 0..9.
/// </summary>
A2R10G10B10_SIntPack32,
/// <summary>
/// A four-component, 32-bit packed unsigned normalized format that has a 2-bit A component in bits 30..31, a 10-bit R component in bits 20..29, a 10-bit G component in bits 10..19, and a 10-bit B component in bits 0..9. The components are gamma encoded and their values range from -0.5271 to 1.66894. The alpha component is clamped to either 0.0 or 1.0 on sampling, rendering, and writing operations.
/// </summary>
A2R10G10B10_XRSRGBPack32,
/// <summary>
/// A four-component, 32-bit packed unsigned normalized format that has a 2-bit A component in bits 30..31, a 10-bit R component in bits 20..29, a 10-bit G component in bits 10..19, and a 10-bit B component in bits 0..9. The components are linearly encoded and their values range from -0.752941 to 1.25098 (pre-expansion). The alpha component is clamped to either 0.0 or 1.0 on sampling, rendering, and writing operations.
/// </summary>
A2R10G10B10_XRUNormPack32,
/// <summary>
/// A four-component, 32-bit packed unsigned normalized format that has a 10-bit R component in bits 20..29, a 10-bit G component in bits 10..19, and a 10-bit B component in bits 0..9. The components are gamma encoded and their values range from -0.5271 to 1.66894. The alpha component is clamped to either 0.0 or 1.0 on sampling, rendering, and writing operations.
/// </summary>
R10G10B10_XRSRGBPack32,
/// <summary>
/// A four-component, 32-bit packed unsigned normalized format that has a 10-bit R component in bits 20..29, a 10-bit G component in bits 10..19, and a 10-bit B component in bits 0..9. The components are linearly encoded and their values range from -0.752941 to 1.25098 (pre-expansion).
/// </summary>
R10G10B10_XRUNormPack32,
/// <summary>
/// A four-component, 64-bit packed unsigned normalized format that has a 10-bit A component in bits 30..39, a 10-bit R component in bits 20..29, a 10-bit G component in bits 10..19, and a 10-bit B component in bits 0..9. The components are gamma encoded and their values range from -0.5271 to 1.66894. The alpha component is clamped to either 0.0 or 1.0 on sampling, rendering, and writing operations.
/// </summary>
A10R10G10B10_XRSRGBPack32,
/// <summary>
/// A four-component, 64-bit packed unsigned normalized format that has a 10-bit A component in bits 30..39, a 10-bit R component in bits 20..29, a 10-bit G component in bits 10..19, and a 10-bit B component in bits 0..9. The components are linearly encoded and their values range from -0.752941 to 1.25098 (pre-expansion). The alpha component is clamped to either 0.0 or 1.0 on sampling, rendering, and writing operations.
/// </summary>
A10R10G10B10_XRUNormPack32,
/// <summary>
/// A one-component, 16-bit unsigned normalized format that has a single 16-bit depth component.
/// </summary>
D16_UNorm = 90,
/// <summary>
/// A two-component, 32-bit format that has 24 unsigned normalized bits in the depth component and, optionally: 8 bits that are unused.
/// </summary>
D24_UNorm,
/// <summary>
/// A two-component, 32-bit packed format that has 8 unsigned integer bits in the stencil component, and 24 unsigned normalized bits in the depth component.
/// </summary>
D24_UNorm_S8_UInt,
/// <summary>
/// A one-component, 32-bit signed floating-point format that has 32-bits in the depth component.
/// </summary>
D32_SFloat,
/// <summary>
/// A two-component format that has 32 signed float bits in the depth component and 8 unsigned integer bits in the stencil component. There are optionally: 24-bits that are unused.
/// </summary>
D32_SFloat_S8_UInt,
/// <summary>
/// A one-component, 8-bit unsigned integer format that has 8-bits in the stencil component.
/// </summary>
S8_UInt,
/// <summary>
/// A three-component, block-compressed format (also known as BC1). Each 64-bit compressed texel block encodes a 4×4 rectangle of unsigned normalized RGB texel data with sRGB nonlinear encoding. This format has a 1 bit alpha channel.
/// </summary>
RGBA_DXT1_SRGB,
/// <summary>
/// A three-component, block-compressed format (also known as BC1). Each 64-bit compressed texel block encodes a 4×4 rectangle of unsigned normalized RGB texel data. This format has a 1 bit alpha channel.
/// </summary>
RGBA_DXT1_UNorm,
/// <summary>
/// A four-component, block-compressed format (also known as BC2) where each 128-bit compressed texel block encodes a 4×4 rectangle of unsigned normalized RGBA texel data with the first 64 bits encoding alpha values followed by 64 bits encoding RGB values with sRGB nonlinear encoding.
/// </summary>
RGBA_DXT3_SRGB,
/// <summary>
/// A four-component, block-compressed format (also known as BC2) where each 128-bit compressed texel block encodes a 4×4 rectangle of unsigned normalized RGBA texel data with the first 64 bits encoding alpha values followed by 64 bits encoding RGB values.
/// </summary>
RGBA_DXT3_UNorm,
/// <summary>
/// A four-component, block-compressed format (also known as BC3) where each 128-bit compressed texel block encodes a 4×4 rectangle of unsigned normalized RGBA texel data with the first 64 bits encoding alpha values followed by 64 bits encoding RGB values with sRGB nonlinear encoding.
/// </summary>
RGBA_DXT5_SRGB,
/// <summary>
/// A four-component, block-compressed format (also known as BC3) where each 128-bit compressed texel block encodes a 4×4 rectangle of unsigned normalized RGBA texel data with the first 64 bits encoding alpha values followed by 64 bits encoding RGB values.
/// </summary>
RGBA_DXT5_UNorm,
/// <summary>
/// A one-component, block-compressed format where each 64-bit compressed texel block encodes a 4×4 rectangle of unsigned normalized red texel data.
/// </summary>
R_BC4_UNorm,
/// <summary>
/// A one-component, block-compressed format where each 64-bit compressed texel block encodes a 4×4 rectangle of signed normalized red texel data.
/// </summary>
R_BC4_SNorm,
/// <summary>
/// A two-component, block-compressed format where each 128-bit compressed texel block encodes a 4×4 rectangle of unsigned normalized RG texel data with the first 64 bits encoding red values followed by 64 bits encoding green values.
/// </summary>
RG_BC5_UNorm,
/// <summary>
/// A two-component, block-compressed format where each 128-bit compressed texel block encodes a 4×4 rectangle of signed normalized RG texel data with the first 64 bits encoding red values followed by 64 bits encoding green values.
/// </summary>
RG_BC5_SNorm,
/// <summary>
/// A three-component, block-compressed format where each 128-bit compressed texel block encodes a 4×4 rectangle of unsigned floating-point RGB texel data.
/// </summary>
RGB_BC6H_UFloat,
/// <summary>
/// A three-component, block-compressed format where each 128-bit compressed texel block encodes a 4×4 rectangle of signed floating-point RGB texel data.
/// </summary>
RGB_BC6H_SFloat,
/// <summary>
/// A four-component, block-compressed format where each 128-bit compressed texel block encodes a 4×4 rectangle of unsigned normalized RGBA texel data with sRGB nonlinear encoding applied to the RGB components.
/// </summary>
RGBA_BC7_SRGB,
/// <summary>
/// A four-component, block-compressed format where each 128-bit compressed texel block encodes a 4×4 rectangle of unsigned normalized RGBA texel data.
/// </summary>
RGBA_BC7_UNorm,
/// <summary>
/// A three-component, PVRTC compressed format where each 64-bit compressed texel block encodes a 8×4 rectangle of unsigned normalized RGB texel data with sRGB nonlinear encoding. This format has no alpha and is considered opaque.
/// </summary>
RGB_PVRTC_2Bpp_SRGB,
/// <summary>
/// A three-component, PVRTC compressed format where each 64-bit compressed texel block encodes a 8×4 rectangle of unsigned normalized RGB texel data. This format has no alpha and is considered opaque.
/// </summary>
RGB_PVRTC_2Bpp_UNorm,
/// <summary>
/// A three-component, PVRTC compressed format where each 64-bit compressed texel block encodes a 4×4 rectangle of unsigned normalized RGB texel data with sRGB nonlinear encoding. This format has no alpha and is considered opaque.
/// </summary>
RGB_PVRTC_4Bpp_SRGB,
/// <summary>
/// A three-component, PVRTC compressed format where each 64-bit compressed texel block encodes a 4×4 rectangle of unsigned normalized RGB texel data. This format has no alpha and is considered opaque.
/// </summary>
RGB_PVRTC_4Bpp_UNorm,
/// <summary>
/// A four-component, PVRTC compressed format where each 64-bit compressed texel block encodes a 8×4 rectangle of unsigned normalized RGBA texel data with the first 32 bits encoding alpha values followed by 32 bits encoding RGB values with sRGB nonlinear encoding applied.
/// </summary>
RGBA_PVRTC_2Bpp_SRGB,
/// <summary>
/// A four-component, PVRTC compressed format where each 64-bit compressed texel block encodes a 8×4 rectangle of unsigned normalized RGBA texel data with the first 32 bits encoding alpha values followed by 32 bits encoding RGB values.
/// </summary>
RGBA_PVRTC_2Bpp_UNorm,
/// <summary>
/// A four-component, PVRTC compressed format where each 64-bit compressed texel block encodes a 4×4 rectangle of unsigned normalized RGBA texel data with the first 32 bits encoding alpha values followed by 32 bits encoding RGB values with sRGB nonlinear encoding applied.
/// </summary>
RGBA_PVRTC_4Bpp_SRGB,
/// <summary>
/// A four-component, PVRTC compressed format where each 64-bit compressed texel block encodes a 4×4 rectangle of unsigned normalized RGBA texel data with the first 32 bits encoding alpha values followed by 32 bits encoding RGB values.
/// </summary>
RGBA_PVRTC_4Bpp_UNorm,
/// <summary>
/// A three-component, ETC compressed format where each 64-bit compressed texel block encodes a 4×4 rectangle of unsigned normalized RGB texel data. This format has no alpha and is considered opaque.
/// </summary>
RGB_ETC_UNorm,
/// <summary>
/// A three-component, ETC2 compressed format where each 64-bit compressed texel block encodes a 4×4 rectangle of unsigned normalized RGB texel data with sRGB nonlinear encoding. This format has no alpha and is considered opaque.
/// </summary>
RGB_ETC2_SRGB,
/// <summary>
/// A three-component, ETC2 compressed format where each 64-bit compressed texel block encodes a 4×4 rectangle of unsigned normalized RGB texel data. This format has no alpha and is considered opaque.
/// </summary>
RGB_ETC2_UNorm,
/// <summary>
/// A four-component, ETC2 compressed format where each 64-bit compressed texel block encodes a 4×4 rectangle of unsigned normalized RGB texel data with sRGB nonlinear encoding, and provides 1 bit of alpha.
/// </summary>
RGB_A1_ETC2_SRGB,
/// <summary>
/// A four-component, ETC2 compressed format where each 64-bit compressed texel block encodes a 4×4 rectangle of unsigned normalized RGB texel data, and provides 1 bit of alpha.
/// </summary>
RGB_A1_ETC2_UNorm,
/// <summary>
/// A four-component, ETC2 compressed format where each 128-bit compressed texel block encodes a 4×4 rectangle of unsigned normalized RGBA texel data with the first 64 bits encoding alpha values followed by 64 bits encoding RGB values with sRGB nonlinear encoding applied.
/// </summary>
RGBA_ETC2_SRGB,
/// <summary>
/// A four-component, ETC2 compressed format where each 128-bit compressed texel block encodes a 4×4 rectangle of unsigned normalized RGBA texel data with the first 64 bits encoding alpha values followed by 64 bits encoding RGB values.
/// </summary>
RGBA_ETC2_UNorm,
/// <summary>
/// A one-component, ETC2 compressed format where each 64-bit compressed texel block encodes a 4×4 rectangle of unsigned normalized red texel data.
/// </summary>
R_EAC_UNorm,
/// <summary>
/// A one-component, ETC2 compressed format where each 64-bit compressed texel block encodes a 4×4 rectangle of signed normalized red texel data.
/// </summary>
R_EAC_SNorm,
/// <summary>
/// A two-component, ETC2 compressed format where each 128-bit compressed texel block encodes a 4×4 rectangle of unsigned normalized RG texel data with the first 64 bits encoding red values followed by 64 bits encoding green values.
/// </summary>
RG_EAC_UNorm,
/// <summary>
/// A two-component, ETC2 compressed format where each 128-bit compressed texel block encodes a 4×4 rectangle of signed normalized RG texel data with the first 64 bits encoding red values followed by 64 bits encoding green values.
/// </summary>
RG_EAC_SNorm,
/// <summary>
/// A four-component, ASTC compressed format where each 128-bit compressed texel block encodes a 4×4 rectangle of unsigned normalized RGBA texel data with sRGB nonlinear encoding applied to the RGB components.
/// </summary>
RGBA_ASTC4X4_SRGB,
/// <summary>
/// A four-component, ASTC compressed format where each 128-bit compressed texel block encodes a 4×4 rectangle of unsigned normalized RGBA texel data.
/// </summary>
RGBA_ASTC4X4_UNorm,
/// <summary>
/// A four-component, ASTC compressed format where each 128-bit compressed texel block encodes a 5×5 rectangle of unsigned normalized RGBA texel data with sRGB nonlinear encoding applied to the RGB components.
/// </summary>
RGBA_ASTC5X5_SRGB,
/// <summary>
/// A four-component, ASTC compressed format where each 128-bit compressed texel block encodes a 5×5 rectangle of unsigned normalized RGBA texel data.
/// </summary>
RGBA_ASTC5X5_UNorm,
/// <summary>
/// A four-component, ASTC compressed format where each 128-bit compressed texel block encodes a 6×6 rectangle of unsigned normalized RGBA texel data with sRGB nonlinear encoding applied to the RGB components.
/// </summary>
RGBA_ASTC6X6_SRGB,
/// <summary>
/// A four-component, ASTC compressed format where each 128-bit compressed texel block encodes a 6×6 rectangle of unsigned normalized RGBA texel data.
/// </summary>
RGBA_ASTC6X6_UNorm,
/// <summary>
/// A four-component, ASTC compressed format where each 128-bit compressed texel block encodes an 8×8 rectangle of unsigned normalized RGBA texel data with sRGB nonlinear encoding applied to the RGB components.
/// </summary>
RGBA_ASTC8X8_SRGB,
/// <summary>
/// A four-component, ASTC compressed format where each 128-bit compressed texel block encodes an 8×8 rectangle of unsigned normalized RGBA texel data.
/// </summary>
RGBA_ASTC8X8_UNorm,
/// <summary>
/// A four-component, ASTC compressed format where each 128-bit compressed texel block encodes a 10×10 rectangle of unsigned normalized RGBA texel data with sRGB nonlinear encoding applied to the RGB components.
/// </summary>
RGBA_ASTC10X10_SRGB,
/// <summary>
/// A four-component, ASTC compressed format where each 128-bit compressed texel block encodes a 10×10 rectangle of unsigned normalized RGBA texel data.
/// </summary>
RGBA_ASTC10X10_UNorm,
/// <summary>
/// A four-component, ASTC compressed format where each 128-bit compressed texel block encodes a 12×12 rectangle of unsigned normalized RGBA texel data with sRGB nonlinear encoding applied to the RGB components.
/// </summary>
RGBA_ASTC12X12_SRGB,
/// <summary>
/// A four-component, ASTC compressed format where each 128-bit compressed texel block encodes a 12×12 rectangle of unsigned normalized RGBA texel data.
/// </summary>
RGBA_ASTC12X12_UNorm,
/// <summary>
/// YUV 4:2:2 Video resource format.
/// </summary>
YUV2,
/// <summary>
/// GraphicsFormat.YUV2.
/// </summary>
VideoAuto = 144,
/// <summary>
/// A four-component, ASTC compressed format where each 128-bit compressed texel block encodes a 4×4 rectangle of float RGBA texel data.
/// </summary>
RGBA_ASTC4X4_UFloat,
/// <summary>
/// A four-component, ASTC compressed format where each 128-bit compressed texel block encodes a 5×5 rectangle of float RGBA texel data.
/// </summary>
RGBA_ASTC5X5_UFloat,
/// <summary>
/// A four-component, ASTC compressed format where each 128-bit compressed texel block encodes a 6×6 rectangle of float RGBA texel data.
/// </summary>
RGBA_ASTC6X6_UFloat,
/// <summary>
/// A four-component, ASTC compressed format where each 128-bit compressed texel block encodes an 8×8 rectangle of float RGBA texel data.
/// </summary>
RGBA_ASTC8X8_UFloat,
/// <summary>
/// A four-component, ASTC compressed format where each 128-bit compressed texel block encodes a 10×10 rectangle of float RGBA texel data.
/// </summary>
RGBA_ASTC10X10_UFloat,
/// <summary>
/// A four-component, ASTC compressed format where each 128-bit compressed texel block encodes a 12×12 rectangle of float RGBA texel data.
/// </summary>
RGBA_ASTC12X12_UFloat,
/// <summary>
/// A two-component, 24-bit format that has 16 unsigned normalized bits in the depth component and 8 unsigned integer bits in the stencil component. Most platforms do not support this format.
/// </summary>
D16_UNorm_S8_UInt,
}
public static class GraphicsFormatExtension
{
public static TextureFormat ToTextureFormat(this GraphicsFormat graphicsFormat)
{
switch (graphicsFormat)
{
case GraphicsFormat.R8_SRGB:
case GraphicsFormat.R8_UInt:
case GraphicsFormat.R8_UNorm:
return TextureFormat.R8;
case GraphicsFormat.R8G8_SRGB:
case GraphicsFormat.R8G8_UInt:
case GraphicsFormat.R8G8_UNorm:
return TextureFormat.RG16;
case GraphicsFormat.R8G8B8_SRGB:
case GraphicsFormat.R8G8B8_UInt:
case GraphicsFormat.R8G8B8_UNorm:
return TextureFormat.RGB24;
case GraphicsFormat.R8G8B8A8_SRGB:
case GraphicsFormat.R8G8B8A8_UInt:
case GraphicsFormat.R8G8B8A8_UNorm:
return TextureFormat.RGBA32;
case GraphicsFormat.R16_UInt:
case GraphicsFormat.R16_UNorm:
return TextureFormat.R16;
case GraphicsFormat.R16G16_UInt:
case GraphicsFormat.R16G16_UNorm:
return TextureFormat.RG32;
case GraphicsFormat.R16G16B16_UInt:
case GraphicsFormat.R16G16B16_UNorm:
return TextureFormat.RGB48;
case GraphicsFormat.R16G16B16A16_UInt:
case GraphicsFormat.R16G16B16A16_UNorm:
return TextureFormat.RGBA64;
case GraphicsFormat.R16_SFloat:
return TextureFormat.RHalf;
case GraphicsFormat.R16G16_SFloat:
return TextureFormat.RGHalf;
case GraphicsFormat.R16G16B16_SFloat: //?
case GraphicsFormat.R16G16B16A16_SFloat:
return TextureFormat.RGBAHalf;
case GraphicsFormat.R32_SFloat:
return TextureFormat.RFloat;
case GraphicsFormat.R32G32_SFloat:
return TextureFormat.RGFloat;
case GraphicsFormat.R32G32B32_SFloat: //?
case GraphicsFormat.R32G32B32A32_SFloat:
return TextureFormat.RGBAFloat;
case GraphicsFormat.B8G8R8A8_SRGB:
case GraphicsFormat.B8G8R8A8_UInt:
case GraphicsFormat.B8G8R8A8_UNorm:
return TextureFormat.BGRA32;
case GraphicsFormat.E5B9G9R9_UFloatPack32:
return TextureFormat.RGB9e5Float;
case GraphicsFormat.RGBA_DXT1_SRGB:
case GraphicsFormat.RGBA_DXT1_UNorm:
return TextureFormat.DXT1;
case GraphicsFormat.RGBA_DXT3_SRGB:
case GraphicsFormat.RGBA_DXT3_UNorm:
return TextureFormat.DXT3;
case GraphicsFormat.RGBA_DXT5_SRGB:
case GraphicsFormat.RGBA_DXT5_UNorm:
return TextureFormat.DXT5;
case GraphicsFormat.R_BC4_UNorm:
return TextureFormat.BC4;
case GraphicsFormat.RG_BC5_UNorm:
return TextureFormat.BC5;
case GraphicsFormat.RGB_BC6H_SFloat:
case GraphicsFormat.RGB_BC6H_UFloat:
return TextureFormat.BC6H;
case GraphicsFormat.RGBA_BC7_SRGB:
case GraphicsFormat.RGBA_BC7_UNorm:
return TextureFormat.BC7;
case GraphicsFormat.RGB_PVRTC_2Bpp_SRGB:
case GraphicsFormat.RGB_PVRTC_2Bpp_UNorm:
case GraphicsFormat.RGBA_PVRTC_2Bpp_SRGB:
case GraphicsFormat.RGBA_PVRTC_2Bpp_UNorm:
return TextureFormat.PVRTC_RGBA2;
case GraphicsFormat.RGB_PVRTC_4Bpp_SRGB:
case GraphicsFormat.RGB_PVRTC_4Bpp_UNorm:
case GraphicsFormat.RGBA_PVRTC_4Bpp_SRGB:
case GraphicsFormat.RGBA_PVRTC_4Bpp_UNorm:
return TextureFormat.PVRTC_RGBA4;
case GraphicsFormat.RGB_ETC_UNorm:
return TextureFormat.ETC_RGB4;
case GraphicsFormat.RGB_ETC2_SRGB:
case GraphicsFormat.RGB_ETC2_UNorm:
return TextureFormat.ETC2_RGB;
case GraphicsFormat.RGB_A1_ETC2_SRGB:
case GraphicsFormat.RGB_A1_ETC2_UNorm:
return TextureFormat.ETC2_RGBA1;
case GraphicsFormat.RGBA_ETC2_SRGB:
case GraphicsFormat.RGBA_ETC2_UNorm:
return TextureFormat.ETC2_RGBA8;
case GraphicsFormat.R_EAC_UNorm:
return TextureFormat.EAC_R;
case GraphicsFormat.R_EAC_SNorm:
return TextureFormat.EAC_R_SIGNED;
case GraphicsFormat.RG_EAC_UNorm:
return TextureFormat.EAC_RG;
case GraphicsFormat.RG_EAC_SNorm:
return TextureFormat.EAC_RG_SIGNED;
case GraphicsFormat.RGBA_ASTC4X4_SRGB:
case GraphicsFormat.RGBA_ASTC4X4_UNorm:
return TextureFormat.ASTC_RGBA_4x4;
case GraphicsFormat.RGBA_ASTC5X5_SRGB:
case GraphicsFormat.RGBA_ASTC5X5_UNorm:
return TextureFormat.ASTC_RGBA_5x5;
case GraphicsFormat.RGBA_ASTC6X6_SRGB:
case GraphicsFormat.RGBA_ASTC6X6_UNorm:
return TextureFormat.ASTC_RGBA_6x6;
case GraphicsFormat.RGBA_ASTC8X8_SRGB:
case GraphicsFormat.RGBA_ASTC8X8_UNorm:
return TextureFormat.ASTC_RGBA_8x8;
case GraphicsFormat.RGBA_ASTC10X10_SRGB:
case GraphicsFormat.RGBA_ASTC10X10_UNorm:
return TextureFormat.ASTC_RGBA_10x10;
case GraphicsFormat.RGBA_ASTC12X12_SRGB:
case GraphicsFormat.RGBA_ASTC12X12_UNorm:
return TextureFormat.ASTC_RGBA_12x12;
case GraphicsFormat.YUV2:
case GraphicsFormat.VideoAuto:
return TextureFormat.YUY2;
default:
return 0;
}
}
}
}

View File

@@ -1,5 +1,4 @@
using System.Collections.Generic;
using System.Text.Json;
namespace AssetStudio
{
@@ -9,8 +8,6 @@ namespace AssetStudio
public Vector2 m_Scale;
public Vector2 m_Offset;
public UnityTexEnv() { }
public UnityTexEnv(ObjectReader reader)
{
m_Texture = new PPtr<Texture>(reader);
@@ -21,46 +18,44 @@ namespace AssetStudio
public class UnityPropertySheet
{
public List<KeyValuePair<string, UnityTexEnv>> m_TexEnvs;
public List<KeyValuePair<string, int>> m_Ints;
public List<KeyValuePair<string, float>> m_Floats;
public List<KeyValuePair<string, Color>> m_Colors;
public UnityPropertySheet() { }
public KeyValuePair<string, UnityTexEnv>[] m_TexEnvs;
public KeyValuePair<string, int>[] m_Ints;
public KeyValuePair<string, float>[] m_Floats;
public KeyValuePair<string, Color>[] m_Colors;
public UnityPropertySheet(ObjectReader reader)
{
var version = reader.version;
int m_TexEnvsSize = reader.ReadInt32();
m_TexEnvs = new List<KeyValuePair<string, UnityTexEnv>>();
for (var i = 0; i < m_TexEnvsSize; i++)
m_TexEnvs = new KeyValuePair<string, UnityTexEnv>[m_TexEnvsSize];
for (int i = 0; i < m_TexEnvsSize; i++)
{
m_TexEnvs.Add(new KeyValuePair<string, UnityTexEnv>(reader.ReadAlignedString(), new UnityTexEnv(reader)));
m_TexEnvs[i] = new KeyValuePair<string, UnityTexEnv>(reader.ReadAlignedString(), new UnityTexEnv(reader));
}
if (version >= 2021) //2021.1 and up
if (version[0] >= 2021) //2021.1 and up
{
int m_IntsSize = reader.ReadInt32();
m_Ints = new List<KeyValuePair<string, int>>();
for (var i = 0; i < m_IntsSize; i++)
m_Ints = new KeyValuePair<string, int>[m_IntsSize];
for (int i = 0; i < m_IntsSize; i++)
{
m_Ints.Add(new KeyValuePair<string, int>(reader.ReadAlignedString(), reader.ReadInt32()));
m_Ints[i] = new KeyValuePair<string, int>(reader.ReadAlignedString(), reader.ReadInt32());
}
}
int m_FloatsSize = reader.ReadInt32();
m_Floats = new List<KeyValuePair<string, float>>();
for (var i = 0; i < m_FloatsSize; i++)
m_Floats = new KeyValuePair<string, float>[m_FloatsSize];
for (int i = 0; i < m_FloatsSize; i++)
{
m_Floats.Add(new KeyValuePair<string, float>(reader.ReadAlignedString(), reader.ReadSingle()));
m_Floats[i] = new KeyValuePair<string, float>(reader.ReadAlignedString(), reader.ReadSingle());
}
int m_ColorsSize = reader.ReadInt32();
m_Colors = new List<KeyValuePair<string, Color>>();
for (var i = 0; i < m_ColorsSize; i++)
m_Colors = new KeyValuePair<string, Color>[m_ColorsSize];
for (int i = 0; i < m_ColorsSize; i++)
{
m_Colors.Add(new KeyValuePair<string, Color>(reader.ReadAlignedString(), reader.ReadColor4()));
m_Colors[i] = new KeyValuePair<string, Color>(reader.ReadAlignedString(), reader.ReadColor4());
}
}
}
@@ -70,62 +65,53 @@ namespace AssetStudio
public PPtr<Shader> m_Shader;
public UnityPropertySheet m_SavedProperties;
public Material() { }
public Material(ObjectReader reader, byte[] type, JsonSerializerOptions jsonOptions) : base(reader)
{
var parsedMaterial = JsonSerializer.Deserialize<Material>(type, jsonOptions);
m_Shader = parsedMaterial.m_Shader;
m_SavedProperties = parsedMaterial.m_SavedProperties;
}
public Material(ObjectReader reader) : base(reader)
{
m_Shader = new PPtr<Shader>(reader);
if (version == 4 && version.Minor >= 1) //4.1 - 4.7.2
if (version[0] == 4 && version[1] >= 1) //4.x
{
var m_ShaderKeywords = reader.ReadStringArray();
}
if (version >= (2021, 2, 18)) //2021.2.18 and up
if (version[0] > 2021 || (version[0] == 2021 && version[1] >= 3)) //2021.3 and up
{
var m_ValidKeywords = reader.ReadStringArray();
var m_InvalidKeywords = reader.ReadStringArray();
}
else if (version >= 5) //5.0 - 2021.2.17
else if (version[0] >= 5) //5.0 ~ 2021.2
{
var m_ShaderKeywords = reader.ReadAlignedString();
}
if (version >= 5) //5.0 and up
if (version[0] >= 5) //5.0 and up
{
var m_LightmapFlags = reader.ReadUInt32();
}
if (version >= (5, 6)) //5.6 and up
if (version[0] > 5 || (version[0] == 5 && version[1] >= 6)) //5.6 and up
{
var m_EnableInstancingVariants = reader.ReadBoolean();
//var m_DoubleSidedGI = a_Stream.ReadBoolean(); //2017 and up
reader.AlignStream();
}
if (version >= (4, 3)) //4.3 and up
if (version[0] > 4 || (version[0] == 4 && version[1] >= 3)) //4.3 and up
{
var m_CustomRenderQueue = reader.ReadInt32();
}
if (version >= (5, 1)) //5.1 and up
if (version[0] > 5 || (version[0] == 5 && version[1] >= 1)) //5.1 and up
{
var stringTagMapSize = reader.ReadInt32();
for (var i = 0; i < stringTagMapSize; i++)
for (int i = 0; i < stringTagMapSize; i++)
{
var first = reader.ReadAlignedString();
var second = reader.ReadAlignedString();
}
}
if (version >= (5, 6)) //5.6 and up
if (version[0] > 5 || (version[0] == 5 && version[1] >= 6)) //5.6 and up
{
var disabledShaderPasses = reader.ReadStringArray();
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,9 @@
namespace AssetStudio
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AssetStudio
{
public sealed class MeshFilter : Component
{

View File

@@ -1,4 +1,9 @@
namespace AssetStudio
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AssetStudio
{
public sealed class MeshRenderer : Renderer
{

View File

@@ -1,12 +1,15 @@
namespace AssetStudio
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AssetStudio
{
public class MonoBehaviour : Behaviour
public sealed class MonoBehaviour : Behaviour
{
public PPtr<MonoScript> m_Script;
public string m_Name;
public MonoBehaviour() { }
public MonoBehaviour(ObjectReader reader) : base(reader)
{
m_Script = new PPtr<MonoScript>(reader);

View File

@@ -1,4 +1,9 @@
namespace AssetStudio
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AssetStudio
{
public sealed class MonoScript : NamedObject
{
@@ -8,31 +13,29 @@
public MonoScript(ObjectReader reader) : base(reader)
{
if (version >= (3, 4)) //3.4 and up
if (version[0] > 3 || (version[0] == 3 && version[1] >= 4)) //3.4 and up
{
var m_ExecutionOrder = reader.ReadInt32();
if (version < 5) //5.0 down
{
var m_PropertiesHash = reader.ReadUInt32();
}
else
{
var m_PropertiesHash = reader.ReadBytes(16);
}
}
if (version < 3) //3.0 down
if (version[0] < 5) //5.0 down
{
var m_PropertiesHash = reader.ReadUInt32();
}
else
{
var m_PropertiesHash = reader.ReadBytes(16);
}
if (version[0] < 3) //3.0 down
{
var m_PathName = reader.ReadAlignedString();
}
m_ClassName = reader.ReadAlignedString();
if (version >= 3) //3.0 and up
if (version[0] >= 3) //3.0 and up
{
m_Namespace = reader.ReadAlignedString();
}
m_AssemblyName = reader.ReadAlignedString();
if (version < (2018, 2)) //2018.2 down
if (version[0] < 2018 || (version[0] == 2018 && version[1] < 2)) //2018.2 down
{
var m_IsEditorScript = reader.ReadBoolean();
}

View File

@@ -1,4 +1,9 @@
namespace AssetStudio
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AssetStudio
{
public sealed class MovieTexture : Texture
{
@@ -7,13 +12,10 @@
public MovieTexture(ObjectReader reader) : base(reader)
{
if (reader.version < (2019, 3)) //2019.3 down
{
var m_Loop = reader.ReadBoolean();
reader.AlignStream();
m_AudioClip = new PPtr<AudioClip>(reader);
m_MovieData = reader.ReadUInt8Array();
}
var m_Loop = reader.ReadBoolean();
reader.AlignStream();
m_AudioClip = new PPtr<AudioClip>(reader);
m_MovieData = reader.ReadUInt8Array();
}
}
}

View File

@@ -1,11 +1,14 @@
namespace AssetStudio
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AssetStudio
{
public class NamedObject : EditorExtension
{
public string m_Name;
protected NamedObject() { }
protected NamedObject(ObjectReader reader) : base(reader)
{
m_Name = reader.ReadAlignedString();

View File

@@ -1,47 +1,18 @@
using System.Collections.Specialized;
using System.Text.Encodings.Web;
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Text.Json.Serialization;
namespace AssetStudio
{
public class Object
{
[JsonIgnore]
public SerializedFile assetsFile;
[JsonIgnore]
public ObjectReader reader;
public long m_PathID;
[JsonIgnore]
public UnityVersion version;
[JsonIgnore]
public int[] version;
protected BuildType buildType;
public BuildTarget platform;
[JsonConverter(typeof(JsonStringEnumConverter))]
public ClassIDType type;
[JsonIgnore]
public SerializedType serializedType;
public int classID;
public uint byteSize;
[JsonIgnore]
public string Name;
private static readonly JsonSerializerOptions jsonOptions;
static Object()
{
jsonOptions = new JsonSerializerOptions
{
Converters = { new JsonConverterHelper.FloatConverter() },
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
NumberHandling = JsonNumberHandling.AllowNamedFloatingPointLiterals,
ReferenceHandler = ReferenceHandler.IgnoreCycles,
PropertyNameCaseInsensitive = true,
IncludeFields = true,
WriteIndented = true,
};
}
public Object() { }
public Object(ObjectReader reader)
{
@@ -51,9 +22,9 @@ namespace AssetStudio
type = reader.type;
m_PathID = reader.m_PathID;
version = reader.version;
buildType = reader.buildType;
platform = reader.platform;
serializedType = reader.serializedType;
classID = reader.classID;
byteSize = reader.byteSize;
if (platform == BuildTarget.NoTarget)
@@ -62,67 +33,39 @@ namespace AssetStudio
}
}
public string DumpObject()
public string Dump()
{
string str = null;
try
if (serializedType?.m_Type != null)
{
if (this is Mesh m_Mesh)
{
m_Mesh.ProcessData();
}
str = JsonSerializer.Deserialize<JsonObject>(JsonSerializer.SerializeToUtf8Bytes(this, GetType(), jsonOptions))
.ToJsonString(jsonOptions).Replace(" ", " ");
return TypeTreeHelper.ReadTypeString(serializedType.m_Type, reader);
}
catch
{
//ignore
}
return str;
return null;
}
public string Dump(TypeTree m_Type = null)
public string Dump(TypeTree m_Type)
{
m_Type = m_Type ?? serializedType?.m_Type;
if (m_Type == null)
return null;
return TypeTreeHelper.ReadTypeString(m_Type, reader);
if (m_Type != null)
{
return TypeTreeHelper.ReadTypeString(m_Type, reader);
}
return null;
}
public OrderedDictionary ToType(TypeTree m_Type = null)
public OrderedDictionary ToType()
{
m_Type = m_Type ?? serializedType?.m_Type;
if (m_Type == null)
return null;
return TypeTreeHelper.ReadType(m_Type, reader);
if (serializedType?.m_Type != null)
{
return TypeTreeHelper.ReadType(serializedType.m_Type, reader);
}
return null;
}
public JsonDocument ToJsonDoc(TypeTree m_Type = null)
public OrderedDictionary ToType(TypeTree m_Type)
{
var typeDict = ToType(m_Type);
try
if (m_Type != null)
{
if (typeDict != null)
{
return JsonSerializer.SerializeToDocument(typeDict, jsonOptions);
}
if (this is Mesh m_Mesh)
{
m_Mesh.ProcessData();
}
return JsonSerializer.SerializeToDocument(this, GetType(), jsonOptions);
return TypeTreeHelper.ReadType(m_Type, reader);
}
catch
{
//ignore
}
return null;
}

View File

@@ -1,5 +1,4 @@
using System;
using System.Text.Json.Serialization;
namespace AssetStudio
{
@@ -7,55 +6,46 @@ namespace AssetStudio
{
public int m_FileID;
public long m_PathID;
public string Name => _assetsFile != null && TryGet(out var result) ? result.Name : string.Empty;
private int _index = -2; //-2 - Prepare, -1 - Missing
private SerializedFile _assetsFile;
[JsonIgnore]
public SerializedFile AssetsFile
{
get => _assetsFile;
set => _assetsFile = value;
}
private SerializedFile assetsFile;
private int index = -2; //-2 - Prepare, -1 - Missing
public PPtr(ObjectReader reader)
{
m_FileID = reader.ReadInt32();
m_PathID = reader.m_Version < SerializedFileFormatVersion.Unknown_14 ? reader.ReadInt32() : reader.ReadInt64();
_assetsFile = reader.assetsFile;
assetsFile = reader.assetsFile;
}
public PPtr() { }
private bool TryGetAssetsFile(out SerializedFile result)
{
result = null;
if (m_FileID == 0)
{
result = _assetsFile;
result = assetsFile;
return true;
}
if (m_FileID > 0 && m_FileID - 1 < _assetsFile.m_Externals.Count)
if (m_FileID > 0 && m_FileID - 1 < assetsFile.m_Externals.Count)
{
var assetsManager = _assetsFile.assetsManager;
var assetsFileList = assetsManager.AssetsFileList;
var assetsManager = assetsFile.assetsManager;
var assetsFileList = assetsManager.assetsFileList;
var assetsFileIndexCache = assetsManager.assetsFileIndexCache;
if (_index == -2)
if (index == -2)
{
var m_External = _assetsFile.m_Externals[m_FileID - 1];
var m_External = assetsFile.m_Externals[m_FileID - 1];
var name = m_External.fileName;
if (!assetsFileIndexCache.TryGetValue(name, out _index))
if (!assetsFileIndexCache.TryGetValue(name, out index))
{
_index = assetsFileList.FindIndex(x => x.fileName.Equals(name, StringComparison.OrdinalIgnoreCase));
assetsFileIndexCache.Add(name, _index);
index = assetsFileList.FindIndex(x => x.fileName.Equals(name, StringComparison.OrdinalIgnoreCase));
assetsFileIndexCache.Add(name, index);
}
}
if (_index >= 0)
if (index >= 0)
{
result = assetsFileList[_index];
result = assetsFileList[index];
return true;
}
}
@@ -63,10 +53,9 @@ namespace AssetStudio
return false;
}
public bool TryGet(out T result, SerializedFile assetsFile = null)
public bool TryGet(out T result)
{
_assetsFile = _assetsFile ?? assetsFile;
if (!IsNull && TryGetAssetsFile(out var sourceFile))
if (TryGetAssetsFile(out var sourceFile))
{
if (sourceFile.ObjectsDic.TryGetValue(m_PathID, out var obj))
{
@@ -82,10 +71,9 @@ namespace AssetStudio
return false;
}
public bool TryGet<T2>(out T2 result, SerializedFile assetsFile = null) where T2 : Object
public bool TryGet<T2>(out T2 result) where T2 : Object
{
_assetsFile = _assetsFile ?? assetsFile;
if (!IsNull && TryGetAssetsFile(out var sourceFile))
if (TryGetAssetsFile(out var sourceFile))
{
if (sourceFile.ObjectsDic.TryGetValue(m_PathID, out var obj))
{
@@ -104,20 +92,20 @@ namespace AssetStudio
public void Set(T m_Object)
{
var name = m_Object.assetsFile.fileName;
if (string.Equals(_assetsFile.fileName, name, StringComparison.OrdinalIgnoreCase))
if (string.Equals(assetsFile.fileName, name, StringComparison.OrdinalIgnoreCase))
{
m_FileID = 0;
}
else
{
m_FileID = _assetsFile.m_Externals.FindIndex(x => string.Equals(x.fileName, name, StringComparison.OrdinalIgnoreCase));
m_FileID = assetsFile.m_Externals.FindIndex(x => string.Equals(x.fileName, name, StringComparison.OrdinalIgnoreCase));
if (m_FileID == -1)
{
_assetsFile.m_Externals.Add(new FileIdentifier
assetsFile.m_Externals.Add(new FileIdentifier
{
fileName = m_Object.assetsFile.fileName
});
m_FileID = _assetsFile.m_Externals.Count;
m_FileID = assetsFile.m_Externals.Count;
}
else
{
@@ -125,14 +113,14 @@ namespace AssetStudio
}
}
var assetsManager = _assetsFile.assetsManager;
var assetsFileList = assetsManager.AssetsFileList;
var assetsManager = assetsFile.assetsManager;
var assetsFileList = assetsManager.assetsFileList;
var assetsFileIndexCache = assetsManager.assetsFileIndexCache;
if (!assetsFileIndexCache.TryGetValue(name, out _index))
if (!assetsFileIndexCache.TryGetValue(name, out index))
{
_index = assetsFileList.FindIndex(x => x.fileName.Equals(name, StringComparison.OrdinalIgnoreCase));
assetsFileIndexCache.Add(name, _index);
index = assetsFileList.FindIndex(x => x.fileName.Equals(name, StringComparison.OrdinalIgnoreCase));
assetsFileIndexCache.Add(name, index);
}
m_PathID = m_Object.m_PathID;

View File

@@ -1,4 +1,9 @@
namespace AssetStudio
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AssetStudio
{
public sealed class PlayerSettings : Object
{
@@ -7,40 +12,37 @@
public PlayerSettings(ObjectReader reader) : base(reader)
{
if (version >= (3, 0))
if (version[0] > 5 || (version[0] == 5 && version[1] >= 4)) //5.4.0 nad up
{
if (version >= (5, 4)) //5.4.0 and up
{
var productGUID = reader.ReadBytes(16);
}
var productGUID = reader.ReadBytes(16);
}
var AndroidProfiler = reader.ReadBoolean();
//bool AndroidFilterTouchesWhenObscured 2017.2 and up
//bool AndroidEnableSustainedPerformanceMode 2018 and up
reader.AlignStream();
int defaultScreenOrientation = reader.ReadInt32();
int targetDevice = reader.ReadInt32();
if (version < (5, 3)) //5.3 down
var AndroidProfiler = reader.ReadBoolean();
//bool AndroidFilterTouchesWhenObscured 2017.2 and up
//bool AndroidEnableSustainedPerformanceMode 2018 and up
reader.AlignStream();
int defaultScreenOrientation = reader.ReadInt32();
int targetDevice = reader.ReadInt32();
if (version[0] < 5 || (version[0] == 5 && version[1] < 3)) //5.3 down
{
if (version[0] < 5) //5.0 down
{
if (version < 5) //5.0 down
int targetPlatform = reader.ReadInt32(); //4.0 and up targetGlesGraphics
if (version[0] > 4 || (version[0] == 4 && version[1] >= 6)) //4.6 and up
{
int targetPlatform = reader.ReadInt32(); //4.0 and up targetGlesGraphics
if (version >= (4, 6)) //4.6 and up
{
var targetIOSGraphics = reader.ReadInt32();
}
var targetIOSGraphics = reader.ReadInt32();
}
int targetResolution = reader.ReadInt32();
}
else
{
var useOnDemandResources = reader.ReadBoolean();
reader.AlignStream();
}
if (version >= (3, 5)) //3.5 and up
{
var accelerometerFrequency = reader.ReadInt32();
}
int targetResolution = reader.ReadInt32();
}
else
{
var useOnDemandResources = reader.ReadBoolean();
reader.AlignStream();
}
if (version[0] > 3 || (version[0] == 3 && version[1] >= 5)) //3.5 and up
{
var accelerometerFrequency = reader.ReadInt32();
}
companyName = reader.ReadAlignedString();
productName = reader.ReadAlignedString();

View File

@@ -1,18 +1,16 @@
using System.Collections.Generic;
namespace AssetStudio
namespace AssetStudio
{
public sealed class PreloadData : NamedObject
{
public List<PPtr<Object>> m_Assets;
public PPtr<Object>[] m_Assets;
public PreloadData(ObjectReader reader) : base(reader)
{
var m_PreloadTableSize = reader.ReadInt32();
m_Assets = new List<PPtr<Object>>();
m_Assets = new PPtr<Object>[m_PreloadTableSize];
for (var i = 0; i < m_PreloadTableSize; i++)
{
m_Assets.Add(new PPtr<Object>(reader));
m_Assets[i] = new PPtr<Object>(reader);
}
/*

View File

@@ -1,4 +1,9 @@
namespace AssetStudio
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AssetStudio
{
public sealed class RectTransform : Transform
{

View File

@@ -1,4 +1,7 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AssetStudio
{
@@ -16,13 +19,13 @@ namespace AssetStudio
public abstract class Renderer : Component
{
public List<PPtr<Material>> m_Materials;
public PPtr<Material>[] m_Materials;
public StaticBatchInfo m_StaticBatchInfo;
public uint[] m_SubsetIndices;
protected Renderer(ObjectReader reader) : base(reader)
{
if (version < 5) //5.0 down
if (version[0] < 5) //5.0 down
{
var m_Enabled = reader.ReadBoolean();
var m_CastShadows = reader.ReadBoolean();
@@ -31,53 +34,30 @@ namespace AssetStudio
}
else //5.0 and up
{
if (version >= (5, 4)) //5.4 and up
if (version[0] > 5 || (version[0] == 5 && version[1] >= 4)) //5.4 and up
{
var m_Enabled = reader.ReadBoolean();
var m_CastShadows = reader.ReadByte();
var m_ReceiveShadows = reader.ReadByte();
if (version >= (2017, 2)) //2017.2 and up
if (version[0] > 2017 || (version[0] == 2017 && version[1] >= 2)) //2017.2 and up
{
var m_DynamicOccludee = reader.ReadByte();
}
if (version >= 2021) //2021.1 and up
if (version[0] >= 2021) //2021.1 and up
{
var m_StaticShadowCaster = reader.ReadByte();
}
var m_MotionVectors = reader.ReadByte();
var m_LightProbeUsage = reader.ReadByte();
var m_ReflectionProbeUsage = reader.ReadByte();
if (version >= (2019, 3)) //2019.3 and up
if (version[0] > 2019 || (version[0] == 2019 && version[1] >= 3)) //2019.3 and up
{
var m_RayTracingMode = reader.ReadByte();
}
if (version >= 2020) //2020.1 and up
if (version[0] >= 2020) //2020.1 and up
{
var m_RayTraceProcedural = reader.ReadByte();
}
if (version.IsTuanjie) //2022.3.2t3(1.0.0) and up
{
var m_virtualGeometry = reader.ReadByte();
var m_virtualGeometryShadow = reader.ReadByte();
if (version > (2022, 3, 48) || (version == (2022, 3, 48) && version.Build >= 3)) //2022.3.48t3(1.4.0) and up
{
reader.AlignStream();
var m_ShadingRate = reader.ReadByte();
if (version >= (2022, 3, 61)) //2022.3.61t1(1.6.0) and up
{
var m_ForceDisableGRD = reader.ReadByte();
}
}
}
if (version >= (2023, 2)) //2023.2 and up
{
var m_RayTracingAccelStructBuildFlagsOverride = reader.ReadByte();
var m_RayTracingAccelStructBuildFlags = reader.ReadByte();
}
if (version >= (2023, 3)) //2023.3 and up
{
var m_SmallMeshCulling = reader.ReadByte();
}
reader.AlignStream();
}
else
@@ -89,12 +69,12 @@ namespace AssetStudio
reader.AlignStream();
}
if (version >= 2018) //2018 and up
if (version[0] >= 2018) //2018 and up
{
var m_RenderingLayerMask = reader.ReadUInt32();
}
if (version >= (2018, 3)) //2018.3 and up
if (version[0] > 2018 || (version[0] == 2018 && version[1] >= 3)) //2018.3 and up
{
var m_RendererPriority = reader.ReadInt32();
}
@@ -103,30 +83,30 @@ namespace AssetStudio
var m_LightmapIndexDynamic = reader.ReadUInt16();
}
if (version >= 3) //3.0 and up
if (version[0] >= 3) //3.0 and up
{
var m_LightmapTilingOffset = reader.ReadVector4();
}
if (version >= 5) //5.0 and up
if (version[0] >= 5) //5.0 and up
{
var m_LightmapTilingOffsetDynamic = reader.ReadVector4();
}
var m_MaterialsSize = reader.ReadInt32();
m_Materials = new List<PPtr<Material>>();
for (var i = 0; i < m_MaterialsSize; i++)
m_Materials = new PPtr<Material>[m_MaterialsSize];
for (int i = 0; i < m_MaterialsSize; i++)
{
m_Materials.Add(new PPtr<Material>(reader));
m_Materials[i] = new PPtr<Material>(reader);
}
if (version < 3) //3.0 down
if (version[0] < 3) //3.0 down
{
var m_LightmapTilingOffset = reader.ReadVector4();
}
else //3.0 and up
{
if (version >= (5, 5)) //5.5 and up
if (version[0] > 5 || (version[0] == 5 && version[1] >= 5)) //5.5 and up
{
m_StaticBatchInfo = new StaticBatchInfo(reader);
}
@@ -138,17 +118,17 @@ namespace AssetStudio
var m_StaticBatchRoot = new PPtr<Transform>(reader);
}
if (version >= (5, 4)) //5.4 and up
if (version[0] > 5 || (version[0] == 5 && version[1] >= 4)) //5.4 and up
{
var m_ProbeAnchor = new PPtr<Transform>(reader);
var m_LightProbeVolumeOverride = new PPtr<GameObject>(reader);
}
else if (version >= (3, 5)) //3.5 - 5.3
else if (version[0] > 3 || (version[0] == 3 && version[1] >= 5)) //3.5 - 5.3
{
var m_UseLightProbes = reader.ReadBoolean();
reader.AlignStream();
if (version >= 5) //5.0 and up
if (version[0] >= 5)//5.0 and up
{
var m_ReflectionProbeUsage = reader.ReadInt32();
}
@@ -156,22 +136,18 @@ namespace AssetStudio
var m_LightProbeAnchor = new PPtr<Transform>(reader); //5.0 and up m_ProbeAnchor
}
if (version >= (4, 3)) //4.3 and up
if (version[0] > 4 || (version[0] == 4 && version[1] >= 3)) //4.3 and up
{
if (version == (4, 3)) //4.3
if (version[0] == 4 && version[1] == 3) //4.3
{
var m_SortingLayer = reader.ReadInt16();
}
else
{
var m_SortingLayerID = reader.ReadInt32();
}
if (version > (5, 6) || (version == (5, 6) && version.Build >= 3)) //5.6.0f3 and up
{
var m_SortingLayer = reader.ReadInt16();
var m_SortingLayerID = reader.ReadUInt32();
}
//SInt16 m_SortingLayer 5.6 and up
var m_SortingOrder = reader.ReadInt16();
reader.AlignStream();
}

View File

@@ -4,15 +4,15 @@ namespace AssetStudio
{
public class ResourceManager : Object
{
public List<KeyValuePair<string, PPtr<Object>>> m_Container;
public KeyValuePair<string, PPtr<Object>>[] m_Container;
public ResourceManager(ObjectReader reader) : base(reader)
{
var m_ContainerSize = reader.ReadInt32();
m_Container = new List<KeyValuePair<string, PPtr<Object>>>();
for (var i = 0; i < m_ContainerSize; i++)
m_Container = new KeyValuePair<string, PPtr<Object>>[m_ContainerSize];
for (int i = 0; i < m_ContainerSize; i++)
{
m_Container.Add(new KeyValuePair<string, PPtr<Object>>(reader.ReadAlignedString(), new PPtr<Object>(reader)));
m_Container[i] = new KeyValuePair<string, PPtr<Object>>(reader.ReadAlignedString(), new PPtr<Object>(reader));
}
}
}

View File

@@ -1,4 +1,9 @@
namespace AssetStudio
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AssetStudio
{
public abstract class RuntimeAnimatorController : NamedObject
{

View File

@@ -17,8 +17,8 @@ namespace AssetStudio
public class StructParameter
{
public List<MatrixParameter> m_MatrixParams;
public List<VectorParameter> m_VectorParams;
public MatrixParameter[] m_MatrixParams;
public VectorParameter[] m_VectorParams;
public StructParameter(BinaryReader reader)
{
@@ -28,17 +28,17 @@ namespace AssetStudio
var m_StructSize = reader.ReadInt32();
int numVectorParams = reader.ReadInt32();
m_VectorParams = new List<VectorParameter>();
for (var i = 0; i < numVectorParams; i++)
m_VectorParams = new VectorParameter[numVectorParams];
for (int i = 0; i < numVectorParams; i++)
{
m_VectorParams.Add(new VectorParameter(reader));
m_VectorParams[i] = new VectorParameter(reader);
}
int numMatrixParams = reader.ReadInt32();
m_MatrixParams = new List<MatrixParameter>();
for (var i = 0; i < numMatrixParams; i++)
m_MatrixParams = new MatrixParameter[numMatrixParams];
for (int i = 0; i < numMatrixParams; i++)
{
m_MatrixParams.Add(new MatrixParameter(reader));
m_MatrixParams[i] = new MatrixParameter(reader);
}
}
}
@@ -112,15 +112,15 @@ namespace AssetStudio
public class SerializedProperties
{
public List<SerializedProperty> m_Props;
public SerializedProperty[] m_Props;
public SerializedProperties(BinaryReader reader)
{
int numProps = reader.ReadInt32();
m_Props = new List<SerializedProperty>();
for (var i = 0; i < numProps; i++)
m_Props = new SerializedProperty[numProps];
for (int i = 0; i < numProps; i++)
{
m_Props.Add(new SerializedProperty(reader));
m_Props[i] = new SerializedProperty(reader);
}
}
}
@@ -237,20 +237,20 @@ namespace AssetStudio
m_Name = reader.ReadAlignedString();
rtBlend = new SerializedShaderRTBlendState[8];
for (var i = 0; i < 8; i++)
for (int i = 0; i < 8; i++)
{
rtBlend[i] = new SerializedShaderRTBlendState(reader);
}
rtSeparateBlend = reader.ReadBoolean();
reader.AlignStream();
if (version >= (2017, 2)) //2017.2 and up
if (version[0] > 2017 || (version[0] == 2017 && version[1] >= 2)) //2017.2 and up
{
zClip = new SerializedShaderFloatValue(reader);
}
zTest = new SerializedShaderFloatValue(reader);
zWrite = new SerializedShaderFloatValue(reader);
culling = new SerializedShaderFloatValue(reader);
if (version >= 2020) //2020.1 and up
if (version[0] >= 2020) //2020.1 and up
{
conservative = new SerializedShaderFloatValue(reader);
}
@@ -290,16 +290,16 @@ namespace AssetStudio
public class ParserBindChannels
{
public List<ShaderBindChannel> m_Channels;
public ShaderBindChannel[] m_Channels;
public uint m_SourceMap;
public ParserBindChannels(BinaryReader reader)
{
int numChannels = reader.ReadInt32();
m_Channels = new List<ShaderBindChannel>();
for (var i = 0; i < numChannels; i++)
m_Channels = new ShaderBindChannel[numChannels];
for (int i = 0; i < numChannels; i++)
{
m_Channels.Add(new ShaderBindChannel(reader));
m_Channels[i] = new ShaderBindChannel(reader);
}
reader.AlignStream();
@@ -359,7 +359,7 @@ namespace AssetStudio
m_NameIndex = reader.ReadInt32();
m_Index = reader.ReadInt32();
m_SamplerIndex = reader.ReadInt32();
if (version >= (2017, 3)) //2017.3 and up
if (version[0] > 2017 || (version[0] == 2017 && version[1] >= 3)) //2017.3 and up
{
var m_MultiSampled = reader.ReadBoolean();
}
@@ -380,7 +380,7 @@ namespace AssetStudio
m_NameIndex = reader.ReadInt32();
m_Index = reader.ReadInt32();
if (version >= 2020) //2020.1 and up
if (version[0] >= 2020) //2020.1 and up
{
m_ArraySize = reader.ReadInt32();
}
@@ -390,9 +390,9 @@ namespace AssetStudio
public class ConstantBuffer
{
public int m_NameIndex;
public List<MatrixParameter> m_MatrixParams;
public List<VectorParameter> m_VectorParams;
public List<StructParameter> m_StructParams;
public MatrixParameter[] m_MatrixParams;
public VectorParameter[] m_VectorParams;
public StructParameter[] m_StructParams;
public int m_Size;
public bool m_IsPartialCB;
@@ -403,31 +403,34 @@ namespace AssetStudio
m_NameIndex = reader.ReadInt32();
int numMatrixParams = reader.ReadInt32();
m_MatrixParams = new List<MatrixParameter>();
for (var i = 0; i < numMatrixParams; i++)
m_MatrixParams = new MatrixParameter[numMatrixParams];
for (int i = 0; i < numMatrixParams; i++)
{
m_MatrixParams.Add(new MatrixParameter(reader));
m_MatrixParams[i] = new MatrixParameter(reader);
}
int numVectorParams = reader.ReadInt32();
m_VectorParams = new List<VectorParameter>();
for (var i = 0; i < numVectorParams; i++)
m_VectorParams = new VectorParameter[numVectorParams];
for (int i = 0; i < numVectorParams; i++)
{
m_VectorParams.Add(new VectorParameter(reader));
m_VectorParams[i] = new VectorParameter(reader);
}
if (version >= (2017, 3)) //2017.3 and up
if (version[0] > 2017 || (version[0] == 2017 && version[1] >= 3)) //2017.3 and up
{
int numStructParams = reader.ReadInt32();
m_StructParams = new List<StructParameter>();
for (var i = 0; i < numStructParams; i++)
m_StructParams = new StructParameter[numStructParams];
for (int i = 0; i < numStructParams; i++)
{
m_StructParams.Add(new StructParameter(reader));
m_StructParams[i] = new StructParameter(reader);
}
}
m_Size = reader.ReadInt32();
if (version.IsInRange((2020, 3, 2), 2021) //2020.3.2f1 and up
|| version >= (2021, 1, 4)) //2021.1.4f1 and up
if ((version[0] == 2020 && version[1] > 3) ||
(version[0] == 2020 && version[1] == 3 && version[2] >= 2) || //2020.3.2f1 and up
(version[0] > 2021) ||
(version[0] == 2021 && version[1] > 1) ||
(version[0] == 2021 && version[1] == 1 && version[2] >= 4)) //2021.1.4f1 and up
{
m_IsPartialCB = reader.ReadBoolean();
reader.AlignStream();
@@ -488,74 +491,71 @@ namespace AssetStudio
public class SerializedProgramParameters
{
public List<VectorParameter> m_VectorParams;
public List<MatrixParameter> m_MatrixParams;
public List<TextureParameter> m_TextureParams;
public List<BufferBinding> m_BufferParams;
public List<ConstantBuffer> m_ConstantBuffers;
public List<BufferBinding> m_ConstantBufferBindings;
public List<UAVParameter> m_UAVParams;
public List<SamplerParameter> m_Samplers;
public VectorParameter[] m_VectorParams;
public MatrixParameter[] m_MatrixParams;
public TextureParameter[] m_TextureParams;
public BufferBinding[] m_BufferParams;
public ConstantBuffer[] m_ConstantBuffers;
public BufferBinding[] m_ConstantBufferBindings;
public UAVParameter[] m_UAVParams;
public SamplerParameter[] m_Samplers;
public SerializedProgramParameters(ObjectReader reader)
{
int numVectorParams = reader.ReadInt32();
m_VectorParams = new List<VectorParameter>();
for (var i = 0; i < numVectorParams; i++)
m_VectorParams = new VectorParameter[numVectorParams];
for (int i = 0; i < numVectorParams; i++)
{
m_VectorParams.Add(new VectorParameter(reader));
m_VectorParams[i] = new VectorParameter(reader);
}
int numMatrixParams = reader.ReadInt32();
m_MatrixParams = new List<MatrixParameter>();
for (var i = 0; i < numMatrixParams; i++)
m_MatrixParams = new MatrixParameter[numMatrixParams];
for (int i = 0; i < numMatrixParams; i++)
{
m_MatrixParams.Add(new MatrixParameter(reader));
m_MatrixParams[i] = new MatrixParameter(reader);
}
int numTextureParams = reader.ReadInt32();
m_TextureParams = new List<TextureParameter>();
for (var i = 0; i < numTextureParams; i++)
m_TextureParams = new TextureParameter[numTextureParams];
for (int i = 0; i < numTextureParams; i++)
{
m_TextureParams.Add(new TextureParameter(reader));
m_TextureParams[i] = new TextureParameter(reader);
}
int numBufferParams = reader.ReadInt32();
m_BufferParams = new List<BufferBinding>();
for (var i = 0; i < numBufferParams; i++)
m_BufferParams = new BufferBinding[numBufferParams];
for (int i = 0; i < numBufferParams; i++)
{
m_BufferParams.Add(new BufferBinding(reader));
m_BufferParams[i] = new BufferBinding(reader);
}
int numConstantBuffers = reader.ReadInt32();
m_ConstantBuffers = new List<ConstantBuffer>();
for (var i = 0; i < numConstantBuffers; i++)
m_ConstantBuffers = new ConstantBuffer[numConstantBuffers];
for (int i = 0; i < numConstantBuffers; i++)
{
m_ConstantBuffers.Add(new ConstantBuffer(reader));
m_ConstantBuffers[i] = new ConstantBuffer(reader);
}
int numConstantBufferBindings = reader.ReadInt32();
m_ConstantBufferBindings = new List<BufferBinding>();
for (var i = 0; i < numConstantBufferBindings; i++)
m_ConstantBufferBindings = new BufferBinding[numConstantBufferBindings];
for (int i = 0; i < numConstantBufferBindings; i++)
{
m_ConstantBufferBindings.Add(new BufferBinding(reader));
m_ConstantBufferBindings[i] = new BufferBinding(reader);
}
int numUAVParams = reader.ReadInt32();
m_UAVParams = new List<UAVParameter>();
for (var i = 0; i < numUAVParams; i++)
m_UAVParams = new UAVParameter[numUAVParams];
for (int i = 0; i < numUAVParams; i++)
{
m_UAVParams.Add(new UAVParameter(reader));
m_UAVParams[i] = new UAVParameter(reader);
}
if (reader.version >= 2017) //2017 and up
int numSamplers = reader.ReadInt32();
m_Samplers = new SamplerParameter[numSamplers];
for (int i = 0; i < numSamplers; i++)
{
int numSamplers = reader.ReadInt32();
m_Samplers = new List<SamplerParameter>();
for (var i = 0; i < numSamplers; i++)
{
m_Samplers.Add(new SamplerParameter(reader));
}
m_Samplers[i] = new SamplerParameter(reader);
}
}
}
@@ -567,7 +567,15 @@ namespace AssetStudio
public ushort[] m_KeywordIndices;
public sbyte m_ShaderHardwareTier;
public ShaderGpuProgramType m_GpuProgramType;
public SerializedProgramParameters m_Parameters; // nested since 2020.3.2f1 and up; 2021.1.1f1 and up
public SerializedProgramParameters m_Parameters;
public VectorParameter[] m_VectorParams;
public MatrixParameter[] m_MatrixParams;
public TextureParameter[] m_TextureParams;
public BufferBinding[] m_BufferParams;
public ConstantBuffer[] m_ConstantBuffers;
public BufferBinding[] m_ConstantBufferBindings;
public UAVParameter[] m_UAVParams;
public SamplerParameter[] m_Samplers;
public SerializedSubProgram(ObjectReader reader)
{
@@ -576,7 +584,7 @@ namespace AssetStudio
m_BlobIndex = reader.ReadUInt32();
m_Channels = new ParserBindChannels(reader);
if (version.IsInRange(2019, (2021, 2))) //2019 ~2021.1
if ((version[0] >= 2019 && version[0] < 2021) || (version[0] == 2021 && version[1] < 2)) //2019 ~2021.1
{
var m_GlobalKeywordIndices = reader.ReadUInt16Array();
reader.AlignStream();
@@ -586,7 +594,7 @@ namespace AssetStudio
else
{
m_KeywordIndices = reader.ReadUInt16Array();
if (version >= 2017) //2017 and up
if (version[0] >= 2017) //2017 and up
{
reader.AlignStream();
}
@@ -596,11 +604,79 @@ namespace AssetStudio
m_GpuProgramType = (ShaderGpuProgramType)reader.ReadSByte();
reader.AlignStream();
m_Parameters = new SerializedProgramParameters(reader);
if (version >= (2017, 2)) //2017.2 and up
if ((version[0] == 2020 && version[1] > 3) ||
(version[0] == 2020 && version[1] == 3 && version[2] >= 2) || //2020.3.2f1 and up
(version[0] > 2021) ||
(version[0] == 2021 && version[1] > 1) ||
(version[0] == 2021 && version[1] == 1 && version[2] >= 1)) //2021.1.1f1 and up
{
if (version >= 2021) //2021.1 and up
m_Parameters = new SerializedProgramParameters(reader);
}
else
{
int numVectorParams = reader.ReadInt32();
m_VectorParams = new VectorParameter[numVectorParams];
for (int i = 0; i < numVectorParams; i++)
{
m_VectorParams[i] = new VectorParameter(reader);
}
int numMatrixParams = reader.ReadInt32();
m_MatrixParams = new MatrixParameter[numMatrixParams];
for (int i = 0; i < numMatrixParams; i++)
{
m_MatrixParams[i] = new MatrixParameter(reader);
}
int numTextureParams = reader.ReadInt32();
m_TextureParams = new TextureParameter[numTextureParams];
for (int i = 0; i < numTextureParams; i++)
{
m_TextureParams[i] = new TextureParameter(reader);
}
int numBufferParams = reader.ReadInt32();
m_BufferParams = new BufferBinding[numBufferParams];
for (int i = 0; i < numBufferParams; i++)
{
m_BufferParams[i] = new BufferBinding(reader);
}
int numConstantBuffers = reader.ReadInt32();
m_ConstantBuffers = new ConstantBuffer[numConstantBuffers];
for (int i = 0; i < numConstantBuffers; i++)
{
m_ConstantBuffers[i] = new ConstantBuffer(reader);
}
int numConstantBufferBindings = reader.ReadInt32();
m_ConstantBufferBindings = new BufferBinding[numConstantBufferBindings];
for (int i = 0; i < numConstantBufferBindings; i++)
{
m_ConstantBufferBindings[i] = new BufferBinding(reader);
}
int numUAVParams = reader.ReadInt32();
m_UAVParams = new UAVParameter[numUAVParams];
for (int i = 0; i < numUAVParams; i++)
{
m_UAVParams[i] = new UAVParameter(reader);
}
if (version[0] >= 2017) //2017 and up
{
int numSamplers = reader.ReadInt32();
m_Samplers = new SamplerParameter[numSamplers];
for (int i = 0; i < numSamplers; i++)
{
m_Samplers[i] = new SamplerParameter(reader);
}
}
}
if (version[0] > 2017 || (version[0] == 2017 && version[1] >= 2)) //2017.2 and up
{
if (version[0] >= 2021) //2021.1 and up
{
var m_ShaderRequirements = reader.ReadInt64();
}
@@ -614,7 +690,7 @@ namespace AssetStudio
public class SerializedProgram
{
public List<SerializedSubProgram> m_SubPrograms;
public SerializedSubProgram[] m_SubPrograms;
public SerializedProgramParameters m_CommonParameters;
public ushort[] m_SerializedKeywordStateMask;
@@ -623,19 +699,22 @@ namespace AssetStudio
var version = reader.version;
int numSubPrograms = reader.ReadInt32();
m_SubPrograms = new List<SerializedSubProgram>();
for (var i = 0; i < numSubPrograms; i++)
m_SubPrograms = new SerializedSubProgram[numSubPrograms];
for (int i = 0; i < numSubPrograms; i++)
{
m_SubPrograms.Add(new SerializedSubProgram(reader));
m_SubPrograms[i] = new SerializedSubProgram(reader);
}
if (version.IsInRange((2020, 3, 2), 2021) //2020.3.2f1 and up
|| version >= (2021, 1, 1)) //2021.1.1f1 and up
if ((version[0] == 2020 && version[1] > 3) ||
(version[0] == 2020 && version[1] == 3 && version[2] >= 2) || //2020.3.2f1 and up
(version[0] > 2021) ||
(version[0] == 2021 && version[1] > 1) ||
(version[0] == 2021 && version[1] == 1 && version[2] >= 1)) //2021.1.1f1 and up
{
m_CommonParameters = new SerializedProgramParameters(reader);
}
if (version >= (2022, 1)) //2022.1 and up
if (version[0] > 2022 || (version[0] == 2022 && version[1] >= 1)) //2022.1 and up
{
m_SerializedKeywordStateMask = reader.ReadUInt16Array();
reader.AlignStream();
@@ -652,11 +731,11 @@ namespace AssetStudio
public class SerializedPass
{
public List<Hash128> m_EditorDataHash;
public Hash128[] m_EditorDataHash;
public byte[] m_Platforms;
public ushort[] m_LocalKeywordMask;
public ushort[] m_GlobalKeywordMask;
public List<KeyValuePair<string, int>> m_NameIndices;
public KeyValuePair<string, int>[] m_NameIndices;
public PassType m_Type;
public SerializedShaderState m_State;
public uint m_ProgramMask;
@@ -677,18 +756,18 @@ namespace AssetStudio
{
var version = reader.version;
if (version >= (2020, 2)) //2020.2 and up
if (version[0] > 2020 || (version[0] == 2020 && version[1] >= 2)) //2020.2 and up
{
int numEditorDataHash = reader.ReadInt32();
m_EditorDataHash = new List<Hash128>();
for (var i = 0; i < numEditorDataHash; i++)
m_EditorDataHash = new Hash128[numEditorDataHash];
for (int i = 0; i < numEditorDataHash; i++)
{
m_EditorDataHash.Add(new Hash128(reader));
m_EditorDataHash[i] = new Hash128(reader);
}
reader.AlignStream();
m_Platforms = reader.ReadUInt8Array();
reader.AlignStream();
if (version <= (2021, 1)) //2021.1 and down
if (version[0] < 2021 || (version[0] == 2021 && version[1] < 2)) //2021.1 and down
{
m_LocalKeywordMask = reader.ReadUInt16Array();
reader.AlignStream();
@@ -698,10 +777,10 @@ namespace AssetStudio
}
int numIndices = reader.ReadInt32();
m_NameIndices = new List<KeyValuePair<string, int>>();
for (var i = 0; i < numIndices; i++)
m_NameIndices = new KeyValuePair<string, int>[numIndices];
for (int i = 0; i < numIndices; i++)
{
m_NameIndices.Add(new KeyValuePair<string, int>(reader.ReadAlignedString(), reader.ReadInt32()));
m_NameIndices[i] = new KeyValuePair<string, int>(reader.ReadAlignedString(), reader.ReadInt32());
}
m_Type = (PassType)reader.ReadInt32();
@@ -712,12 +791,12 @@ namespace AssetStudio
progGeometry = new SerializedProgram(reader);
progHull = new SerializedProgram(reader);
progDomain = new SerializedProgram(reader);
if (version >= (2019, 3)) //2019.3 and up
if (version[0] > 2019 || (version[0] == 2019 && version[1] >= 3)) //2019.3 and up
{
progRayTracing = new SerializedProgram(reader);
}
m_HasInstancingVariant = reader.ReadBoolean();
if (version >= 2018) //2018 and up
if (version[0] >= 2018) //2018 and up
{
var m_HasProceduralInstancingVariant = reader.ReadBoolean();
}
@@ -726,7 +805,7 @@ namespace AssetStudio
m_Name = reader.ReadAlignedString();
m_TextureName = reader.ReadAlignedString();
m_Tags = new SerializedTagMap(reader);
if (version == 2021 && version.Minor >= 2) //2021.2 ~2021.x
if (version[0] == 2021 && version[1] >= 2) //2021.2 ~2021.x
{
m_SerializedKeywordStateMask = reader.ReadUInt16Array();
reader.AlignStream();
@@ -736,32 +815,32 @@ namespace AssetStudio
public class SerializedTagMap
{
public List<KeyValuePair<string, string>> tags;
public KeyValuePair<string, string>[] tags;
public SerializedTagMap(BinaryReader reader)
{
int numTags = reader.ReadInt32();
tags = new List<KeyValuePair<string, string>>();
for (var i = 0; i < numTags; i++)
tags = new KeyValuePair<string, string>[numTags];
for (int i = 0; i < numTags; i++)
{
tags.Add(new KeyValuePair<string, string>(reader.ReadAlignedString(), reader.ReadAlignedString()));
tags[i] = new KeyValuePair<string, string>(reader.ReadAlignedString(), reader.ReadAlignedString());
}
}
}
public class SerializedSubShader
{
public List<SerializedPass> m_Passes;
public SerializedPass[] m_Passes;
public SerializedTagMap m_Tags;
public int m_LOD;
public SerializedSubShader(ObjectReader reader)
{
int numPasses = reader.ReadInt32();
m_Passes = new List<SerializedPass>();
for (var i = 0; i < numPasses; i++)
m_Passes = new SerializedPass[numPasses];
for (int i = 0; i < numPasses; i++)
{
m_Passes.Add(new SerializedPass(reader));
m_Passes[i] = new SerializedPass(reader);
}
m_Tags = new SerializedTagMap(reader);
@@ -796,14 +875,14 @@ namespace AssetStudio
public class SerializedShader
{
public SerializedProperties m_PropInfo;
public List<SerializedSubShader> m_SubShaders;
public SerializedSubShader[] m_SubShaders;
public string[] m_KeywordNames;
public byte[] m_KeywordFlags;
public string m_Name;
public string m_CustomEditorName;
public string m_FallbackName;
public List<SerializedShaderDependency> m_Dependencies;
public List<SerializedCustomEditorForRenderPipeline> m_CustomEditorForRenderPipelines;
public SerializedShaderDependency[] m_Dependencies;
public SerializedCustomEditorForRenderPipeline[] m_CustomEditorForRenderPipelines;
public bool m_DisableNoSubshadersMessage;
public SerializedShader(ObjectReader reader)
@@ -813,13 +892,13 @@ namespace AssetStudio
m_PropInfo = new SerializedProperties(reader);
int numSubShaders = reader.ReadInt32();
m_SubShaders = new List<SerializedSubShader>();
for (var i = 0; i < numSubShaders; i++)
m_SubShaders = new SerializedSubShader[numSubShaders];
for (int i = 0; i < numSubShaders; i++)
{
m_SubShaders.Add(new SerializedSubShader(reader));
m_SubShaders[i] = new SerializedSubShader(reader);
}
if (version >= (2021, 2)) //2021.2 and up
if (version[0] > 2021 || (version[0] == 2021 && version[1] >= 2)) //2021.2 and up
{
m_KeywordNames = reader.ReadStringArray();
m_KeywordFlags = reader.ReadUInt8Array();
@@ -831,19 +910,19 @@ namespace AssetStudio
m_FallbackName = reader.ReadAlignedString();
int numDependencies = reader.ReadInt32();
m_Dependencies = new List<SerializedShaderDependency>();
for (var i = 0; i < numDependencies; i++)
m_Dependencies = new SerializedShaderDependency[numDependencies];
for (int i = 0; i < numDependencies; i++)
{
m_Dependencies.Add(new SerializedShaderDependency(reader));
m_Dependencies[i] = new SerializedShaderDependency(reader);
}
if (version >= 2021) //2021.1 and up
if (version[0] >= 2021) //2021.1 and up
{
int m_CustomEditorForRenderPipelinesSize = reader.ReadInt32();
m_CustomEditorForRenderPipelines = new List<SerializedCustomEditorForRenderPipeline>();
for (var i = 0; i < m_CustomEditorForRenderPipelinesSize; i++)
m_CustomEditorForRenderPipelines = new SerializedCustomEditorForRenderPipeline[m_CustomEditorForRenderPipelinesSize];
for (int i = 0; i < m_CustomEditorForRenderPipelinesSize; i++)
{
m_CustomEditorForRenderPipelines.Add(new SerializedCustomEditorForRenderPipeline(reader));
m_CustomEditorForRenderPipelines[i] = new SerializedCustomEditorForRenderPipeline(reader);
}
}
@@ -898,11 +977,11 @@ namespace AssetStudio
public Shader(ObjectReader reader) : base(reader)
{
if (version >= (5, 5)) //5.5 and up
if (version[0] == 5 && version[1] >= 5 || version[0] > 5) //5.5 and up
{
m_ParsedForm = new SerializedShader(reader);
platforms = reader.ReadUInt32Array().Select(x => (ShaderCompilerPlatform)x).ToArray();
if (version >= (2019, 3)) //2019.3 and up
if (version[0] > 2019 || (version[0] == 2019 && version[1] >= 3)) //2019.3 and up
{
offsets = reader.ReadUInt32ArrayArray();
compressedLengths = reader.ReadUInt32ArrayArray();
@@ -918,18 +997,18 @@ namespace AssetStudio
reader.AlignStream();
var m_DependenciesCount = reader.ReadInt32();
for (var i = 0; i < m_DependenciesCount; i++)
for (int i = 0; i < m_DependenciesCount; i++)
{
var m_Dependencies = new PPtr<Shader>(reader);
new PPtr<Shader>(reader);
}
if (version >= 2018)
if (version[0] >= 2018)
{
var m_NonModifiableTexturesCount = reader.ReadInt32();
for (var i = 0; i < m_NonModifiableTexturesCount; i++)
for (int i = 0; i < m_NonModifiableTexturesCount; i++)
{
var first = reader.ReadAlignedString();
var second = new PPtr<Texture>(reader);
new PPtr<Texture>(reader);
}
}
@@ -941,7 +1020,7 @@ namespace AssetStudio
m_Script = reader.ReadUInt8Array();
reader.AlignStream();
var m_PathName = reader.ReadAlignedString();
if (version == 5 && version.Minor >= 3) //5.3 - 5.4
if (version[0] == 5 && version[1] >= 3) //5.3 - 5.4
{
decompressedSize = reader.ReadUInt32();
m_SubProgramBlob = reader.ReadUInt8Array();

View File

@@ -1,11 +1,14 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AssetStudio
{
public sealed class SkinnedMeshRenderer : Renderer
{
public PPtr<Mesh> m_Mesh;
public List<PPtr<Transform>> m_Bones;
public PPtr<Transform>[] m_Bones;
public float[] m_BlendShapeWeights;
public SkinnedMeshRenderer(ObjectReader reader) : base(reader)
@@ -15,21 +18,20 @@ namespace AssetStudio
var m_SkinNormals = reader.ReadBoolean(); //3.1.0 and below
reader.AlignStream();
if (version < (2, 6)) //2.6 down
if (version[0] == 2 && version[1] < 6) //2.6 down
{
var m_DisableAnimationWhenOffscreen = new PPtr<Animation>(reader);
}
m_Mesh = new PPtr<Mesh>(reader);
var numBones = reader.ReadInt32();
m_Bones = new List<PPtr<Transform>>();
for (var b = 0; b < numBones; b++)
m_Bones = new PPtr<Transform>[reader.ReadInt32()];
for (int b = 0; b < m_Bones.Length; b++)
{
m_Bones.Add(new PPtr<Transform>(reader));
m_Bones[b] = new PPtr<Transform>(reader);
}
if (version >= (4, 3)) //4.3 and up
if (version[0] > 4 || (version[0] == 4 && version[1] >= 3)) //4.3 and up
{
m_BlendShapeWeights = reader.ReadSingleArray();
}

View File

@@ -68,7 +68,7 @@ namespace AssetStudio
var version = reader.version;
pos = reader.ReadVector3();
if (version <= (4, 3)) //4.3 and down
if (version[0] < 4 || (version[0] == 4 && version[1] <= 3)) //4.3 and down
{
uv = reader.ReadVector2();
}
@@ -79,11 +79,11 @@ namespace AssetStudio
{
public PPtr<Texture2D> texture;
public PPtr<Texture2D> alphaTexture;
public List<SecondarySpriteTexture> secondaryTextures;
public List<SubMesh> m_SubMeshes;
public SecondarySpriteTexture[] secondaryTextures;
public SubMesh[] m_SubMeshes;
public byte[] m_IndexBuffer;
public VertexData m_VertexData;
public List<SpriteVertex> vertices;
public SpriteVertex[] vertices;
public ushort[] indices;
public Matrix4x4[] m_Bindpose;
public BoneWeights4[] m_SourceSkin;
@@ -99,25 +99,28 @@ namespace AssetStudio
var version = reader.version;
texture = new PPtr<Texture2D>(reader);
alphaTexture = version >= (5, 2) ? new PPtr<Texture2D>(reader) : new PPtr<Texture2D>(); //5.2 and up
if (version[0] > 5 || (version[0] == 5 && version[1] >= 2)) //5.2 and up
{
alphaTexture = new PPtr<Texture2D>(reader);
}
if (version >= 2019) //2019 and up
if (version[0] >= 2019) //2019 and up
{
var secondaryTexturesSize = reader.ReadInt32();
secondaryTextures = new List<SecondarySpriteTexture>();
for (var i = 0; i < secondaryTexturesSize; i++)
secondaryTextures = new SecondarySpriteTexture[secondaryTexturesSize];
for (int i = 0; i < secondaryTexturesSize; i++)
{
secondaryTextures.Add(new SecondarySpriteTexture(reader));
secondaryTextures[i] = new SecondarySpriteTexture(reader);
}
}
if (version >= (5, 6)) //5.6 and up
if (version[0] > 5 || (version[0] == 5 && version[1] >= 6)) //5.6 and up
{
var m_SubMeshesSize = reader.ReadInt32();
m_SubMeshes = new List<SubMesh>();
for (var i = 0; i < m_SubMeshesSize; i++)
m_SubMeshes = new SubMesh[m_SubMeshesSize];
for (int i = 0; i < m_SubMeshesSize; i++)
{
m_SubMeshes.Add(new SubMesh(reader));
m_SubMeshes[i] = new SubMesh(reader);
}
m_IndexBuffer = reader.ReadUInt8Array();
@@ -128,26 +131,24 @@ namespace AssetStudio
else
{
var verticesSize = reader.ReadInt32();
vertices = new List<SpriteVertex>();
for (var i = 0; i < verticesSize; i++)
vertices = new SpriteVertex[verticesSize];
for (int i = 0; i < verticesSize; i++)
{
vertices.Add(new SpriteVertex(reader));
vertices[i] = new SpriteVertex(reader);
}
indices = reader.ReadUInt16Array();
reader.AlignStream();
}
if (version >= 2018) //2018 and up
if (version[0] >= 2018) //2018 and up
{
m_Bindpose = reader.ReadMatrixArray();
if (version < (2018, 2)) //2018.2 down
if (version[0] == 2018 && version[1] < 2) //2018.2 down
{
var m_SourceSkinSize = reader.ReadInt32();
reader.ThrowIfTooLarge(m_SourceSkinSize * 32f);
m_SourceSkin = new BoneWeights4[m_SourceSkinSize];
for (var i = 0; i < m_SourceSkinSize; i++)
for (int i = 0; i < m_SourceSkinSize; i++)
{
m_SourceSkin[i] = new BoneWeights4(reader);
}
@@ -156,18 +157,18 @@ namespace AssetStudio
textureRect = new Rectf(reader);
textureRectOffset = reader.ReadVector2();
if (version >= (5, 6)) //5.6 and up
if (version[0] > 5 || (version[0] == 5 && version[1] >= 6)) //5.6 and up
{
atlasRectOffset = reader.ReadVector2();
}
settingsRaw = new SpriteSettings(reader);
if (version >= (4, 5)) //4.5 and up
if (version[0] > 4 || (version[0] == 4 && version[1] >= 5)) //4.5 and up
{
uvTransform = reader.ReadVector4();
}
if (version >= 2017) //2017 and up
if (version[0] >= 2017) //2017 and up
{
downscaleMultiplier = reader.ReadSingle();
}
@@ -181,6 +182,13 @@ namespace AssetStudio
public float width;
public float height;
public Rectf(float x, float y, float w, float h) {
this.x = x;
this.y = y;
width = w;
height = h;
}
public Rectf(BinaryReader reader)
{
x = reader.ReadSingle();
@@ -203,32 +211,35 @@ namespace AssetStudio
public string[] m_AtlasTags;
public PPtr<SpriteAtlas> m_SpriteAtlas;
public SpriteRenderData m_RD;
//public Vector2[][] m_PhysicsShape;
public Vector2[][] m_PhysicsShape;
public bool akSplitAlpha;
public Sprite(ObjectReader reader) : base(reader)
{
m_Rect = new Rectf(reader);
m_Offset = reader.ReadVector2();
if (version >= (4, 5)) //4.5 and up
if (version[0] > 4 || (version[0] == 4 && version[1] >= 5)) //4.5 and up
{
m_Border = reader.ReadVector4();
}
m_PixelsToUnits = reader.ReadSingle();
if (version >= (5, 4, 2)
|| version == (5, 4, 1) && version.IsPatch && version.Build >= 3) //5.4.1p3 and up
if (version[0] > 5
|| (version[0] == 5 && version[1] > 4)
|| (version[0] == 5 && version[1] == 4 && version[2] >= 2)
|| (version[0] == 5 && version[1] == 4 && version[2] == 1 && buildType.IsPatch && version[3] >= 3)) //5.4.1p3 and up
{
m_Pivot = reader.ReadVector2();
}
m_Extrude = reader.ReadUInt32();
if (version >= (5, 3)) //5.3 and up
if (version[0] > 5 || (version[0] == 5 && version[1] >= 3)) //5.3 and up
{
m_IsPolygon = reader.ReadBoolean();
reader.AlignStream();
}
if (version >= 2017) //2017 and up
if (version[0] >= 2017) //2017 and up
{
var first = new Guid(reader.ReadBytes(16));
var second = reader.ReadInt64();
@@ -240,18 +251,19 @@ namespace AssetStudio
}
m_RD = new SpriteRenderData(reader);
/*
if (version >= 2017) //2017 and up
if (version[0] >= 2017) //2017 and up
{
var m_PhysicsShapeSize = reader.ReadInt32();
var physicsShapeList = new List<Vector2[]>();
for (var i = 0; i < m_PhysicsShapeSize; i++)
m_PhysicsShape = new Vector2[m_PhysicsShapeSize][];
for (int i = 0; i < m_PhysicsShapeSize; i++)
{
physicsShapeList.Add(reader.ReadVector2Array());
m_PhysicsShape[i] = reader.ReadVector2Array();
}
m_PhysicsShape = physicsShapeList.ToArray();
}
*/
akSplitAlpha = false;
//vector m_Bones 2018 and up
}
}

View File

@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
using System.Text.Json.Serialization;
namespace AssetStudio
{
@@ -14,7 +13,7 @@ namespace AssetStudio
public Vector4 uvTransform;
public float downscaleMultiplier;
public SpriteSettings settingsRaw;
public List<SecondarySpriteTexture> secondaryTextures;
public SecondarySpriteTexture[] secondaryTextures;
public SpriteAtlasData(ObjectReader reader)
{
@@ -23,20 +22,20 @@ namespace AssetStudio
alphaTexture = new PPtr<Texture2D>(reader);
textureRect = new Rectf(reader);
textureRectOffset = reader.ReadVector2();
if (version >= (2017, 2)) //2017.2 and up
if (version[0] > 2017 || (version[0] == 2017 && version[1] >= 2)) //2017.2 and up
{
atlasRectOffset = reader.ReadVector2();
}
uvTransform = reader.ReadVector4();
downscaleMultiplier = reader.ReadSingle();
settingsRaw = new SpriteSettings(reader);
if (version >= (2020, 2)) //2020.2 and up
if (version[0] > 2020 || (version[0] == 2020 && version[1] >= 2)) //2020.2 and up
{
var secondaryTexturesSize = reader.ReadInt32();
secondaryTextures = new List<SecondarySpriteTexture>();
for (var i = 0; i < secondaryTexturesSize; i++)
secondaryTextures = new SecondarySpriteTexture[secondaryTexturesSize];
for (int i = 0; i < secondaryTexturesSize; i++)
{
secondaryTextures.Add(new SecondarySpriteTexture(reader));
secondaryTextures[i] = new SecondarySpriteTexture(reader);
}
reader.AlignStream();
}
@@ -45,25 +44,24 @@ namespace AssetStudio
public sealed class SpriteAtlas : NamedObject
{
public List<PPtr<Sprite>> m_PackedSprites;
[JsonConverter(typeof(JsonConverterHelper.RenderDataMapConverter))]
public PPtr<Sprite>[] m_PackedSprites;
public Dictionary<KeyValuePair<Guid, long>, SpriteAtlasData> m_RenderDataMap;
public bool m_IsVariant;
public SpriteAtlas(ObjectReader reader) : base(reader)
{
var m_PackedSpritesSize = reader.ReadInt32();
m_PackedSprites = new List<PPtr<Sprite>>();
for (var i = 0; i < m_PackedSpritesSize; i++)
m_PackedSprites = new PPtr<Sprite>[m_PackedSpritesSize];
for (int i = 0; i < m_PackedSpritesSize; i++)
{
m_PackedSprites.Add(new PPtr<Sprite>(reader));
m_PackedSprites[i] = new PPtr<Sprite>(reader);
}
var m_PackedSpriteNamesToIndex = reader.ReadStringArray();
var m_RenderDataMapSize = reader.ReadInt32();
m_RenderDataMap = new Dictionary<KeyValuePair<Guid, long>, SpriteAtlasData>();
for (var i = 0; i < m_RenderDataMapSize; i++)
m_RenderDataMap = new Dictionary<KeyValuePair<Guid, long>, SpriteAtlasData>(m_RenderDataMapSize);
for (int i = 0; i < m_RenderDataMapSize; i++)
{
var first = new Guid(reader.ReadBytes(16));
var second = reader.ReadInt64();

View File

@@ -1,27 +0,0 @@
namespace AssetStudio
{
public class StreamingInfo
{
public long offset; //ulong
public uint size;
public string path;
public StreamingInfo() { }
public StreamingInfo(ObjectReader reader)
{
var version = reader.version;
if (version >= 2020) //2020.1 and up
{
offset = reader.ReadInt64();
}
else
{
offset = reader.ReadUInt32();
}
size = reader.ReadUInt32();
path = reader.ReadAlignedString();
}
}
}

View File

@@ -1,4 +1,10 @@
namespace AssetStudio
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
namespace AssetStudio
{
public sealed class TextAsset : NamedObject
{

View File

@@ -1,20 +1,19 @@
namespace AssetStudio
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AssetStudio
{
public abstract class Texture : NamedObject
{
protected Texture() { }
protected Texture(ObjectReader reader) : base(reader)
{
if (version >= (2017, 3)) //2017.3 and up
if (version[0] > 2017 || (version[0] == 2017 && version[1] >= 3)) //2017.3 and up
{
if (version < (2023, 2)) //2023.2 down
{
var m_ForcedFallbackFormat = reader.ReadInt32();
var m_DownscaleFallback = reader.ReadBoolean();
}
if (version >= (2020, 2)) //2020.2 and up
var m_ForcedFallbackFormat = reader.ReadInt32();
var m_DownscaleFallback = reader.ReadBoolean();
if (version[0] > 2020 || (version[0] == 2020 && version[1] >= 2)) //2020.2 and up
{
var m_IsAlphaChannelOptional = reader.ReadBoolean();
}

View File

@@ -1,109 +1,79 @@
using System;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace AssetStudio
{
public class StreamingInfo
{
public long offset; //ulong
public uint size;
public string path;
public StreamingInfo(ObjectReader reader)
{
var version = reader.version;
if (version[0] >= 2020) //2020.1 and up
{
offset = reader.ReadInt64();
}
else
{
offset = reader.ReadUInt32();
}
size = reader.ReadUInt32();
path = reader.ReadAlignedString();
}
}
public class GLTextureSettings
{
public int m_FilterMode;
public int m_Aniso;
public float m_MipBias;
public int m_WrapMode;
public GLTextureSettings(ObjectReader reader)
{
var version = reader.version;
m_FilterMode = reader.ReadInt32();
m_Aniso = reader.ReadInt32();
m_MipBias = reader.ReadSingle();
if (version[0] >= 2017)//2017.x and up
{
m_WrapMode = reader.ReadInt32(); //m_WrapU
int m_WrapV = reader.ReadInt32();
int m_WrapW = reader.ReadInt32();
}
else
{
m_WrapMode = reader.ReadInt32();
}
}
}
public sealed class Texture2D : Texture
{
public int m_Width;
public int m_Height;
public uint m_CompleteImageSize;
public TextureFormat m_TextureFormat;
public bool m_MipMap;
public int m_MipCount;
public GLTextureSettings m_TextureSettings;
public int m_ImageCount;
public byte[] m_PlatformBlob;
[JsonPropertyName("image data")]
public ResourceReader image_data;
public StreamingInfo m_StreamData;
public StreamingInfo m_DataStreamData; //Tuanjie
public Texture2D() { }
public Texture2D(Texture2DArray m_Texture2DArray, int layer) // Texture2DArrayImage
{
reader = m_Texture2DArray.reader;
assetsFile = m_Texture2DArray.assetsFile;
version = m_Texture2DArray.version;
platform = m_Texture2DArray.platform;
m_Name = $"{m_Texture2DArray.m_Name}_{layer + 1}";
type = ClassIDType.Texture2DArrayImage;
m_PathID = m_Texture2DArray.m_PathID;
m_Width = m_Texture2DArray.m_Width;
m_Height = m_Texture2DArray.m_Height;
m_TextureFormat = m_Texture2DArray.m_Format.ToTextureFormat();
m_MipCount = m_Texture2DArray.m_MipCount;
m_TextureSettings = m_Texture2DArray.m_TextureSettings;
m_StreamData = m_Texture2DArray.m_StreamData;
m_PlatformBlob = Array.Empty<byte>();
m_MipMap = m_MipCount > 1;
m_ImageCount = 1;
//var imgActualDataSize = GetImageDataSize(m_TextureFormat);
//var mipmapSize = (int)(m_Texture2DArray.m_DataSize / m_Texture2DArray.m_Depth - imgActualDataSize);
m_CompleteImageSize = (uint)(m_Texture2DArray.m_DataSize / m_Texture2DArray.m_Depth);
var offset = layer * m_CompleteImageSize + m_Texture2DArray.image_data.Offset;
image_data = !string.IsNullOrEmpty(m_StreamData?.path)
? new ResourceReader(m_StreamData.path, assetsFile, offset, m_CompleteImageSize)
: new ResourceReader(reader, offset, m_CompleteImageSize);
byteSize = (uint)(m_Width * m_Height) * 4;
}
public Texture2D(ObjectReader reader, byte[] type, JsonSerializerOptions jsonOptions) : base(reader)
{
var parsedTex2d = JsonSerializer.Deserialize<Texture2D>(type, jsonOptions);
m_Width = parsedTex2d.m_Width;
m_Height = parsedTex2d.m_Height;
m_CompleteImageSize = parsedTex2d.m_CompleteImageSize;
m_TextureFormat = parsedTex2d.m_TextureFormat;
m_MipMap = parsedTex2d.m_MipMap;
m_MipCount = parsedTex2d.m_MipCount;
m_ImageCount = parsedTex2d.m_ImageCount;
m_TextureSettings = parsedTex2d.m_TextureSettings;
m_StreamData = parsedTex2d.m_StreamData;
m_PlatformBlob = parsedTex2d.m_PlatformBlob ?? Array.Empty<byte>();
image_data = !string.IsNullOrEmpty(m_StreamData?.path)
? new ResourceReader(m_StreamData.path, assetsFile, m_StreamData.offset, m_StreamData.size)
: new ResourceReader(reader, parsedTex2d.image_data.Offset, parsedTex2d.image_data.Size);
}
public Texture2D(ObjectReader reader) : base(reader)
{
m_Width = reader.ReadInt32();
m_Height = reader.ReadInt32();
m_CompleteImageSize = reader.ReadUInt32();
if (version >= 2020) //2020.1 and up
var m_CompleteImageSize = reader.ReadInt32();
if (version[0] >= 2020) //2020.1 and up
{
var m_MipsStripped = reader.ReadInt32();
}
if (version.IsTuanjie && (version > (2022, 3, 2) || version.Build >= 8)) //2022.3.2t8(1.1.0) and up
{
var m_WebStreaming = reader.ReadBoolean();
reader.AlignStream();
var m_PriorityLevel = reader.ReadInt32();
var m_UploadedMode = reader.ReadInt32();
m_DataStreamData = new StreamingInfo //sample is needed
{
offset = 0,
size = reader.ReadUInt32(),
path = reader.ReadAlignedString()
};
}
m_TextureFormat = (TextureFormat)reader.ReadInt32();
if (version.IsTuanjie && version >= (2022, 3, 62)) //2022.3.62t1(1.7.0) and up
{
var m_TextureManagerMultiFormatSettingSize = reader.ReadInt32();
reader.Position += m_TextureManagerMultiFormatSettingSize; //skip byte[] m_TextureManagerMultiFormatSetting
reader.AlignStream();
}
if (version < (5, 2)) //5.2 down
if (version[0] < 5 || (version[0] == 5 && version[1] < 2)) //5.2 down
{
m_MipMap = reader.ReadBoolean();
}
@@ -111,132 +81,152 @@ namespace AssetStudio
{
m_MipCount = reader.ReadInt32();
}
if (version >= (2, 6)) //2.6.0 and up
if (version[0] > 2 || (version[0] == 2 && version[1] >= 6)) //2.6.0 and up
{
var m_IsReadable = reader.ReadBoolean();
}
if (version >= 2020) //2020.1 and up
if (version[0] >= 2020) //2020.1 and up
{
var m_IsPreProcessed = reader.ReadBoolean();
}
if (version >= (2019, 3)) //2019.3 and up
if (version[0] > 2019 || (version[0] == 2019 && version[1] >= 3)) //2019.3 and up
{
if (version >= (2022, 2)) //2022.2 and up
if (version[0] > 2022 || (version[0] == 2022 && version[1] >= 2)) //2022.2 and up
{
var m_IgnoreMipmapLimit = reader.ReadBoolean();
reader.AlignStream();
}
else
{
var m_IgnoreMasterTextureLimit = reader.ReadBoolean();
}
}
if (version.IsInRange(3, (5, 5))) //3.0.0 - 5.4
if (version[0] >= 3) //3.0.0 - 5.4
{
var m_ReadAllowed = reader.ReadBoolean();
if (version[0] < 5 || (version[0] == 5 && version[1] <= 4))
{
var m_ReadAllowed = reader.ReadBoolean();
}
}
if (version >= (2022, 2)) //2022.2 and up
if (version[0] > 2022 || (version[0] == 2022 && version[1] >= 2)) //2022.2 and up
{
var m_MipmapLimitGroupName = reader.ReadAlignedString();
reader.AlignStream();
}
if (version >= (2018, 2)) //2018.2 and up
if (version[0] > 2018 || (version[0] == 2018 && version[1] >= 2)) //2018.2 and up
{
var m_StreamingMipmaps = reader.ReadBoolean();
}
reader.AlignStream();
if (version >= (2018, 2)) //2018.2 and up
if (version[0] > 2018 || (version[0] == 2018 && version[1] >= 2)) //2018.2 and up
{
var m_StreamingMipmapsPriority = reader.ReadInt32();
}
m_ImageCount = reader.ReadInt32();
var m_ImageCount = reader.ReadInt32();
var m_TextureDimension = reader.ReadInt32();
m_TextureSettings = new GLTextureSettings(reader);
if (version >= 3) //3.0 and up
if (version[0] >= 3) //3.0 and up
{
var m_LightmapFormat = reader.ReadInt32();
}
if (version >= (3, 5)) //3.5.0 and up
if (version[0] > 3 || (version[0] == 3 && version[1] >= 5)) //3.5.0 and up
{
var m_ColorSpace = reader.ReadInt32();
}
if (version >= (2020, 2)) //2020.2 and up
if (version[0] > 2020 || (version[0] == 2020 && version[1] >= 2)) //2020.2 and up
{
m_PlatformBlob = reader.ReadUInt8Array();
var m_PlatformBlob = reader.ReadUInt8Array();
reader.AlignStream();
}
else
{
m_PlatformBlob = Array.Empty<byte>();
}
var image_data_size = reader.ReadInt32();
if (image_data_size == 0 && version >= (5, 3))//5.3.0 and up
if (image_data_size == 0 && ((version[0] == 5 && version[1] >= 3) || version[0] > 5))//5.3.0 and up
{
m_StreamData = new StreamingInfo(reader);
}
image_data = !string.IsNullOrEmpty(m_StreamData?.path)
? new ResourceReader(m_StreamData.path, assetsFile, m_StreamData.offset, m_StreamData.size)
: new ResourceReader(reader, reader.BaseStream.Position, image_data_size);
}
// https://docs.unity3d.com/2023.3/Documentation/Manual/class-TextureImporterOverride.html
private int GetImageDataSize(TextureFormat textureFormat)
{
var imgDataSize = m_Width * m_Height;
switch (textureFormat)
ResourceReader resourceReader;
if (!string.IsNullOrEmpty(m_StreamData?.path))
{
case TextureFormat.ASTC_RGBA_5x5:
// https://registry.khronos.org/webgl/extensions/WEBGL_compressed_texture_astc/
imgDataSize = (int)(MathF.Floor((m_Width + 4) / 5f) * MathF.Floor((m_Height + 4) / 5f) * 16);
break;
case TextureFormat.ASTC_RGBA_6x6:
imgDataSize = (int)(MathF.Floor((m_Width + 5) / 6f) * MathF.Floor((m_Height + 5) / 6f) * 16);
break;
case TextureFormat.ASTC_RGBA_8x8:
imgDataSize = (int)(MathF.Floor((m_Width + 7) / 8f) * MathF.Floor((m_Height + 7) / 8f) * 16);
break;
case TextureFormat.ASTC_RGBA_10x10:
imgDataSize = (int)(MathF.Floor((m_Width + 9) / 10f) * MathF.Floor((m_Height + 9) / 10f) * 16);
break;
case TextureFormat.ASTC_RGBA_12x12:
imgDataSize = (int)(MathF.Floor((m_Width + 11) / 12f) * MathF.Floor((m_Height + 11) / 12f) * 16);
break;
case TextureFormat.DXT1:
case TextureFormat.EAC_R:
case TextureFormat.EAC_R_SIGNED:
case TextureFormat.ATC_RGB4:
case TextureFormat.ETC_RGB4:
case TextureFormat.ETC2_RGB:
case TextureFormat.ETC2_RGBA1:
case TextureFormat.PVRTC_RGBA4:
imgDataSize /= 2;
break;
case TextureFormat.PVRTC_RGBA2:
imgDataSize /= 4;
break;
case TextureFormat.R16:
case TextureFormat.RGB565:
imgDataSize *= 2;
break;
case TextureFormat.RGB24:
imgDataSize *= 3;
break;
case TextureFormat.RG32:
case TextureFormat.RGBA32:
case TextureFormat.ARGB32:
case TextureFormat.BGRA32:
case TextureFormat.RGB9e5Float:
imgDataSize *= 4;
break;
case TextureFormat.RGB48:
imgDataSize *= 6;
break;
case TextureFormat.RGBAHalf:
case TextureFormat.RGBA64:
imgDataSize *= 8;
break;
resourceReader = new ResourceReader(m_StreamData.path, assetsFile, m_StreamData.offset, m_StreamData.size);
}
return imgDataSize;
else
{
resourceReader = new ResourceReader(reader, reader.BaseStream.Position, image_data_size);
}
image_data = resourceReader;
}
}
public enum TextureFormat
{
Alpha8 = 1,
ARGB4444,
RGB24,
RGBA32,
ARGB32,
ARGBFloat,
RGB565,
BGR24,
R16,
DXT1,
DXT3,
DXT5,
RGBA4444,
BGRA32,
RHalf,
RGHalf,
RGBAHalf,
RFloat,
RGFloat,
RGBAFloat,
YUY2,
RGB9e5Float,
RGBFloat,
BC6H,
BC7,
BC4,
BC5,
DXT1Crunched,
DXT5Crunched,
PVRTC_RGB2,
PVRTC_RGBA2,
PVRTC_RGB4,
PVRTC_RGBA4,
ETC_RGB4,
ATC_RGB4,
ATC_RGBA8,
EAC_R = 41,
EAC_R_SIGNED,
EAC_RG,
EAC_RG_SIGNED,
ETC2_RGB,
ETC2_RGBA1,
ETC2_RGBA8,
ASTC_RGB_4x4,
ASTC_RGB_5x5,
ASTC_RGB_6x6,
ASTC_RGB_8x8,
ASTC_RGB_10x10,
ASTC_RGB_12x12,
ASTC_RGBA_4x4,
ASTC_RGBA_5x5,
ASTC_RGBA_6x6,
ASTC_RGBA_8x8,
ASTC_RGBA_10x10,
ASTC_RGBA_12x12,
ETC_RGB4_3DS,
ETC_RGBA8_3DS,
RG16,
R8,
ETC_RGB4Crunched,
ETC2_RGBA8Crunched,
ASTC_HDR_4x4,
ASTC_HDR_5x5,
ASTC_HDR_6x6,
ASTC_HDR_8x8,
ASTC_HDR_10x10,
ASTC_HDR_12x12,
RG32,
RGB48,
RGBA64
}
}

View File

@@ -1,96 +0,0 @@
using System.Collections.Generic;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace AssetStudio
{
public sealed class Texture2DArray : Texture
{
public int m_Width;
public int m_Height;
public int m_Depth;
public GraphicsFormat m_Format;
public int m_MipCount;
public uint m_DataSize;
public GLTextureSettings m_TextureSettings;
public int m_ColorSpace;
[JsonPropertyName("image data")]
public ResourceReader image_data;
public StreamingInfo m_StreamData;
public List<Texture2D> TextureList;
public Texture2DArray() { }
public Texture2DArray(ObjectReader reader) : base(reader)
{
if (version >= 2019) //2019 and up
{
m_ColorSpace = reader.ReadInt32();
m_Format = (GraphicsFormat)reader.ReadInt32();
}
m_Width = reader.ReadInt32();
m_Height = reader.ReadInt32();
m_Depth = reader.ReadInt32();
if (version < 2019) //2019 down
{
m_Format = (GraphicsFormat)reader.ReadInt32();
}
m_MipCount = reader.ReadInt32();
if (version >= (2023, 2)) //2023.2 and up
{
var m_MipsStripped = reader.ReadInt32();
}
m_DataSize = reader.ReadUInt32();
m_TextureSettings = new GLTextureSettings(reader);
if (version < 2019) //2019 down
{
m_ColorSpace = reader.ReadInt32();
}
if (version >= (2020, 2)) //2020.2 and up
{
var m_UsageMode = reader.ReadInt32();
}
var m_IsReadable = reader.ReadBoolean();
if (version > (2023, 2)) //2023.2 and up
{
var m_IgnoreMipmapLimit = reader.ReadBoolean();
reader.AlignStream();
var m_MipmapLimitGroupName = reader.ReadAlignedString();
}
else
{
reader.AlignStream();
}
var image_data_size = reader.ReadInt32();
if (image_data_size == 0 && version >= (5, 6)) //5.6 and up
{
m_StreamData = new StreamingInfo(reader);
}
image_data = !string.IsNullOrEmpty(m_StreamData?.path)
? new ResourceReader(m_StreamData.path, assetsFile, m_StreamData.offset, (int)m_StreamData.size)
: new ResourceReader(reader, reader.BaseStream.Position, image_data_size);
TextureList = new List<Texture2D>();
}
public Texture2DArray(ObjectReader reader, byte[] type, JsonSerializerOptions jsonOptions) : base(reader)
{
var parsedTex2dArray = JsonSerializer.Deserialize<Texture2DArray>(type, jsonOptions);
m_Width = parsedTex2dArray.m_Width;
m_Height = parsedTex2dArray.m_Height;
m_Depth = parsedTex2dArray.m_Depth;
m_Format = parsedTex2dArray.m_Format;
m_MipCount = parsedTex2dArray.m_MipCount;
m_DataSize = parsedTex2dArray.m_DataSize;
m_TextureSettings = parsedTex2dArray.m_TextureSettings;
m_StreamData = parsedTex2dArray.m_StreamData;
image_data = !string.IsNullOrEmpty(m_StreamData?.path)
? new ResourceReader(m_StreamData.path, assetsFile, m_StreamData.offset, m_StreamData.size)
: new ResourceReader(reader, parsedTex2dArray.image_data.Offset, parsedTex2dArray.image_data.Size);
TextureList = new List<Texture2D>();
}
}
}

View File

@@ -1,282 +0,0 @@
namespace AssetStudio
{
public enum TextureFormat
{
/// <summary>
/// Alpha-only texture format, 8 bit integer.
/// </summary>
Alpha8 = 1,
/// <summary>
/// A 16 bits/pixel texture format. Texture stores color with an alpha channel.
/// </summary>
ARGB4444,
/// <summary>
/// Three channel (RGB) texture format, 8-bits unsigned integer per channel.
/// </summary>
RGB24,
/// <summary>
/// Four channel (RGBA) texture format, 8-bits unsigned integer per channel.
/// </summary>
RGBA32,
/// <summary>
/// Color with alpha texture format, 8-bits per channel.
/// </summary>
ARGB32,
/// <summary>
/// </summary>
ARGBFloat,
/// <summary>
/// A 16 bit color texture format.
/// </summary>
RGB565,
/// <summary>
/// </summary>
BGR24,
/// <summary>
/// Single channel (R) texture format, 16 bit integer.
/// </summary>
R16,
/// <summary>
/// Compressed color texture format.
/// </summary>
DXT1,
/// <summary>
/// </summary>
DXT3,
/// <summary>
/// Compressed color with alpha channel texture format.
/// </summary>
DXT5,
/// <summary>
/// Color and alpha texture format, 4 bit per channel.
/// </summary>
RGBA4444,
/// <summary>
/// Color with alpha texture format, 8-bits per channel.
/// </summary>
BGRA32,
/// <summary>
/// Scalar (R) texture format, 16 bit floating point.
/// </summary>
RHalf,
/// <summary>
/// Two color (RG) texture format, 16 bit floating point per channel.
/// </summary>
RGHalf,
/// <summary>
/// RGB color and alpha texture format, 16 bit floating point per channel.
/// </summary>
RGBAHalf,
/// <summary>
/// Scalar (R) texture format, 32 bit floating point.
/// </summary>
RFloat,
/// <summary>
/// Two color (RG) texture format, 32 bit floating point per channel.
/// </summary>
RGFloat,
/// <summary>
/// RGB color and alpha texture format, 32-bit floats per channel.
/// </summary>
RGBAFloat,
/// <summary>
/// A format that uses the YUV color space and is often used for video encoding or playback.
/// </summary>
YUY2,
/// <summary>
/// RGB HDR format, with 9 bit mantissa per channel and a 5 bit shared exponent.
/// </summary>
RGB9e5Float,
/// <summary>
/// </summary>
RGBFloat,
/// <summary>
/// HDR compressed color texture format.
/// </summary>
BC6H,
/// <summary>
/// High quality compressed color texture format.
/// </summary>
BC7,
/// <summary>
/// Compressed one channel (R) texture format.
/// </summary>
BC4,
/// <summary>
/// Compressed two-channel (RG) texture format.
/// </summary>
BC5,
/// <summary>
/// Compressed color texture format with Crunch compression for smaller storage sizes.
/// </summary>
DXT1Crunched,
/// <summary>
/// Compressed color with alpha channel texture format with Crunch compression for smaller storage sizes.
/// </summary>
DXT5Crunched,
/// <summary>
/// PowerVR (iOS) 2 bits/pixel compressed color texture format.
/// </summary>
PVRTC_RGB2,
/// <summary>
/// PowerVR (iOS) 2 bits/pixel compressed with alpha channel texture format.
/// </summary>
PVRTC_RGBA2,
/// <summary>
/// PowerVR (iOS) 4 bits/pixel compressed color texture format.
/// </summary>
PVRTC_RGB4,
/// <summary>
/// PowerVR (iOS) 4 bits/pixel compressed with alpha channel texture format.
/// </summary>
PVRTC_RGBA4,
/// <summary>
/// ETC (GLES2.0) 4 bits/pixel compressed RGB texture format.
/// </summary>
ETC_RGB4,
/// <summary>
/// ATC (ATITC) 4 bits/pixel compressed RGB texture format.
/// </summary>
ATC_RGB4,
/// <summary>
/// ATC (ATITC) 8 bits/pixel compressed RGB texture format.
/// </summary>
ATC_RGBA8,
/// <summary>
/// ETC2 / EAC (GL ES 3.0) 4 bits/pixel compressed unsigned single-channel texture format.
/// </summary>
EAC_R = 41,
/// <summary>
/// ETC2 / EAC (GL ES 3.0) 4 bits/pixel compressed signed single-channel texture format.
/// </summary>
EAC_R_SIGNED,
/// <summary>
/// ETC2 / EAC (GL ES 3.0) 8 bits/pixel compressed unsigned dual-channel (RG) texture format.
/// </summary>
EAC_RG,
/// <summary>
/// ETC2 / EAC (GL ES 3.0) 8 bits/pixel compressed signed dual-channel (RG) texture format.
/// </summary>
EAC_RG_SIGNED,
/// <summary>
/// ETC2 (GL ES 3.0) 4 bits/pixel compressed RGB texture format.
/// </summary>
ETC2_RGB,
/// <summary>
/// ETC2 (GL ES 3.0) 4 bits/pixel RGB+1-bit alpha texture format.
/// </summary>
ETC2_RGBA1,
/// <summary>
/// ETC2 (GL ES 3.0) 8 bits/pixel compressed RGBA texture format.
/// </summary>
ETC2_RGBA8,
/// <summary>
/// ASTC (4x4 pixel block in 128 bits) compressed RGB texture format.
/// </summary>
ASTC_RGB_4x4,
/// <summary>
/// ASTC (5x5 pixel block in 128 bits) compressed RGB texture format.
/// </summary>
ASTC_RGB_5x5,
/// <summary>
/// ASTC (6x6 pixel block in 128 bits) compressed RGB texture format.
/// </summary>
ASTC_RGB_6x6,
/// <summary>
/// ASTC (8x8 pixel block in 128 bits) compressed RGB texture format.
/// </summary>
ASTC_RGB_8x8,
/// <summary>
/// ASTC (10x10 pixel block in 128 bits) compressed RGB texture format.
/// </summary>
ASTC_RGB_10x10,
/// <summary>
/// ASTC (12x12 pixel block in 128 bits) compressed RGB texture format.
/// </summary>
ASTC_RGB_12x12,
/// <summary>
/// ASTC (4x4 pixel block in 128 bits) compressed RGBA texture format.
/// </summary>
ASTC_RGBA_4x4,
/// <summary>
/// ASTC (5x5 pixel block in 128 bits) compressed RGBA texture format.
/// </summary>
ASTC_RGBA_5x5,
/// <summary>
/// ASTC (6x6 pixel block in 128 bits) compressed RGBA texture format.
/// </summary>
ASTC_RGBA_6x6,
/// <summary>
/// ASTC (8x8 pixel block in 128 bits) compressed RGBA texture format.
/// </summary>
ASTC_RGBA_8x8,
/// <summary>
/// ASTC (10x10 pixel block in 128 bits) compressed RGBA texture format.
/// </summary>
ASTC_RGBA_10x10,
/// <summary>
/// ASTC (12x12 pixel block in 128 bits) compressed RGBA texture format.
/// </summary>
ASTC_RGBA_12x12,
/// <summary>
/// ETC 4 bits/pixel compressed RGB texture format.
/// </summary>
ETC_RGB4_3DS,
/// <summary>
/// ETC 4 bits/pixel RGB + 4 bits/pixel Alpha compressed texture format.
/// </summary>
ETC_RGBA8_3DS,
/// <summary>
/// Two color (RG) texture format, 8-bits per channel.
/// </summary>
RG16,
/// <summary>
/// Single channel (R) texture format, 8 bit integer.
/// </summary>
R8,
/// <summary>
/// Compressed color texture format with Crunch compression for smaller storage sizes.
/// </summary>
ETC_RGB4Crunched,
/// <summary>
/// Compressed color with alpha channel texture format using Crunch compression for smaller storage sizes.
/// </summary>
ETC2_RGBA8Crunched,
/// <summary>
/// ASTC (4x4 pixel block in 128 bits) compressed RGB(A) HDR texture format.
/// </summary>
ASTC_HDR_4x4,
/// <summary>
/// ASTC (5x5 pixel block in 128 bits) compressed RGB(A) HDR texture format.
/// </summary>
ASTC_HDR_5x5,
/// <summary>
/// ASTC (6x6 pixel block in 128 bits) compressed RGB(A) HDR texture format.
/// </summary>
ASTC_HDR_6x6,
/// <summary>
/// ASTC (8x8 pixel block in 128 bits) compressed RGB(A) texture format.
/// </summary>
ASTC_HDR_8x8,
/// <summary>
/// ASTC (10x10 pixel block in 128 bits) compressed RGB(A) HDR texture format.
/// </summary>
ASTC_HDR_10x10,
/// <summary>
/// ASTC (12x12 pixel block in 128 bits) compressed RGB(A) HDR texture format.
/// </summary>
ASTC_HDR_12x12,
/// <summary>
/// Two channel (RG) texture format, 16-bits unsigned integer per channel.
/// </summary>
RG32,
/// <summary>
/// Three channel (RGB) texture format, 16-bits unsigned integer per channel.
/// </summary>
RGB48,
/// <summary>
/// Four channel (RGBA) texture format, 16-bits unsigned integer per channel.
/// </summary>
RGBA64,
}
}

View File

@@ -1,4 +1,7 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AssetStudio
{
@@ -7,7 +10,7 @@ namespace AssetStudio
public Quaternion m_LocalRotation;
public Vector3 m_LocalPosition;
public Vector3 m_LocalScale;
public List<PPtr<Transform>> m_Children;
public PPtr<Transform>[] m_Children;
public PPtr<Transform> m_Father;
public Transform(ObjectReader reader) : base(reader)
@@ -17,10 +20,10 @@ namespace AssetStudio
m_LocalScale = reader.ReadVector3();
int m_ChildrenCount = reader.ReadInt32();
m_Children = new List<PPtr<Transform>>();
for (var i = 0; i < m_ChildrenCount; i++)
m_Children = new PPtr<Transform>[m_ChildrenCount];
for (int i = 0; i < m_ChildrenCount; i++)
{
m_Children.Add(new PPtr<Transform>(reader));
m_Children[i] = new PPtr<Transform>(reader);
}
m_Father = new PPtr<Transform>(reader);
}

View File

@@ -34,7 +34,7 @@ namespace AssetStudio
var m_ProxyHeight = reader.ReadUInt32();
Width = reader.ReadUInt32();
Height = reader.ReadUInt32();
if (version >= (2017, 2)) //2017.2 and up
if (version[0] > 2017 || (version[0] == 2017 && version[1] >= 2)) //2017.2 and up
{
var m_PixelAspecRatioNum = reader.ReadUInt32();
var m_PixelAspecRatioDen = reader.ReadUInt32();
@@ -46,17 +46,18 @@ namespace AssetStudio
reader.AlignStream();
var m_AudioSampleRate = reader.ReadUInt32Array();
var m_AudioLanguage = reader.ReadStringArray();
if (version >= 2020) //2020.1 and up
if (version[0] >= 2020) //2020.1 and up
{
var m_VideoShadersSize = reader.ReadInt32();
for (var i = 0; i < m_VideoShadersSize; i++)
var m_VideoShaders = new PPtr<Shader>[m_VideoShadersSize];
for (int i = 0; i < m_VideoShadersSize; i++)
{
var m_VideoShaders = new PPtr<Shader>(reader);
m_VideoShaders[i] = new PPtr<Shader>(reader);
}
}
m_ExternalResources = new StreamedResource(reader);
m_HasSplitAlpha = reader.ReadBoolean();
if (version >= 2020) //2020.1 and up
if (version[0] >= 2020) //2020.1 and up
{
var m_sRGB = reader.ReadBoolean();
}

View File

@@ -114,8 +114,7 @@ namespace AssetStudio
{1121, "m_PrefabInstance"},
{1138, "m_PrefabAsset"},
{1152, "FileSize"},
{1161, "Hash128"},
{1169, "RenderingLayerMask"},
{1161, "Hash128"}
};
}
}

View File

@@ -1,133 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
namespace AssetStudio
{
public enum CubismSDKVersion : byte
{
V30 = 1,
V33,
V40,
V42,
V50
}
public sealed class CubismMoc : IDisposable
{
public CubismSDKVersion Version { get; }
public string VersionDescription { get; }
public float CanvasWidth { get; }
public float CanvasHeight { get; }
public float CentralPosX { get; }
public float CentralPosY { get; }
public float PixelPerUnit { get; }
public uint PartCount { get; }
public uint ParamCount { get; }
public HashSet<string> PartNames { get; }
public HashSet<string> ParamNames { get; }
private byte[] modelData;
private int modelDataSize;
private bool isBigEndian;
public CubismMoc(MonoBehaviour moc)
{
var reader = moc.reader;
reader.Reset();
reader.Position += 28; //PPtr<GameObject> m_GameObject, m_Enabled, PPtr<MonoScript>
reader.ReadAlignedString(); //m_Name
modelDataSize = (int)reader.ReadUInt32();
modelData = BigArrayPool<byte>.Shared.Rent(modelDataSize);
_ = reader.Read(modelData, 0, modelDataSize);
var sdkVer = modelData[4];
if (Enum.IsDefined(typeof(CubismSDKVersion), sdkVer))
{
Version = (CubismSDKVersion)sdkVer;
VersionDescription = ParseVersion();
}
else
{
var msg = $"Unknown SDK version ({sdkVer})";
VersionDescription = msg;
Version = 0;
Logger.Warning($"Live2D model \"{moc.m_Name}\": " + msg);
return;
}
isBigEndian = BitConverter.ToBoolean(modelData, 5);
var modelDataSpan = new ReadOnlySpan<byte>(modelData, 0, modelDataSize);
//offsets
var countInfoTableOffset = (int)modelDataSpan.ReadUInt32(64, isBigEndian);
var canvasInfoOffset = (int)modelDataSpan.ReadUInt32(68, isBigEndian);
var partIdsOffset = modelDataSpan.ReadUInt32(76, isBigEndian);
var parameterIdsOffset = modelDataSpan.ReadUInt32(264, isBigEndian);
//canvas
PixelPerUnit = modelDataSpan.ReadSingle(canvasInfoOffset, isBigEndian);
CentralPosX = modelDataSpan.ReadSingle(canvasInfoOffset + 4, isBigEndian);
CentralPosY = modelDataSpan.ReadSingle(canvasInfoOffset + 8, isBigEndian);
CanvasWidth = modelDataSpan.ReadSingle(canvasInfoOffset + 12, isBigEndian);
CanvasHeight = modelDataSpan.ReadSingle(canvasInfoOffset + 16, isBigEndian);
//model
PartCount = modelDataSpan.ReadUInt32(countInfoTableOffset, isBigEndian);
ParamCount = modelDataSpan.ReadUInt32(countInfoTableOffset + 20, isBigEndian);
PartNames = ReadMocStrings(modelDataSpan, (int)partIdsOffset, (int)PartCount);
ParamNames = ReadMocStrings(modelDataSpan, (int)parameterIdsOffset, (int)ParamCount);
}
public void SaveMoc3(string savePath)
{
if (!savePath.EndsWith(".moc3"))
savePath += ".moc3";
using (var file = File.OpenWrite(savePath))
{
file.Write(modelData, 0, modelDataSize);
}
}
private string ParseVersion()
{
switch (Version)
{
case CubismSDKVersion.V30: return "SDK3.0/Cubism3.0(3.2)";
case CubismSDKVersion.V33: return "SDK3.3/Cubism3.3";
case CubismSDKVersion.V40: return "SDK4.0/Cubism4.0";
case CubismSDKVersion.V42: return "SDK4.2/Cubism4.2";
case CubismSDKVersion.V50: return "SDK5.0/Cubism5.0";
default: return "";
}
}
private static HashSet<string> ReadMocStrings(ReadOnlySpan<byte> data, int index, int count)
{
const int strLen = 64;
var strHashSet = new HashSet<string>();
for (var i = 0; i < count; i++)
{
if (index + i * strLen <= data.Length)
{
var str = data.Slice(index + i * strLen, strLen).ReadStringToNull();
strHashSet.Add(str);
}
}
return strHashSet;
}
private void Dispose(bool disposing)
{
if (disposing)
{
BigArrayPool<byte>.Shared.Return(modelData, clearArray: true);
}
}
public void Dispose()
{
Dispose(true);
}
}
}

View File

@@ -1,31 +0,0 @@
using System.Collections.Generic;
namespace AssetStudio
{
public class CubismModel
{
public string Name { get; set; }
public string Container { get; set; }
public MonoBehaviour CubismModelMono { get; set; }
public MonoBehaviour PhysicsController { get; set; }
public MonoBehaviour FadeController { get; set; }
public MonoBehaviour ExpressionController { get; set; }
public List<MonoBehaviour> RenderTextureList { get; set; }
public List<MonoBehaviour> ParamDisplayInfoList { get; set; }
public List<MonoBehaviour> PartDisplayInfoList { get; set; }
public List<MonoBehaviour> PosePartList { get; set; }
public List<AnimationClip> ClipMotionList { get; set; }
public GameObject ModelGameObject { get; set; }
public CubismModel(GameObject m_GameObject)
{
Name = m_GameObject.m_Name;
ModelGameObject = m_GameObject;
RenderTextureList = new List<MonoBehaviour>();
ParamDisplayInfoList = new List<MonoBehaviour>();
PartDisplayInfoList = new List<MonoBehaviour>();
PosePartList = new List<MonoBehaviour>();
ClipMotionList = new List<AnimationClip>();
}
}
}

View File

@@ -1,56 +0,0 @@
using System;
using System.Buffers.Binary;
namespace AssetStudio.CustomOptions.Asmo
{
public class OptionsFile
{
private static readonly byte[] OptionsFileSign = new byte[] { 0x41, 0x53, 0x4D, 0x4F }; //ASMO
public static readonly string Extension = ".asmo";
public byte[] Signature { get; private set; } = OptionsFileSign;
public short Version { get; private set; } = 1;
public short Reserved { get; set; }
public uint DataCrc { get; set; }
public int DataSize { get; set; }
public byte[] Data { get; set; }
public OptionsFile() { }
public OptionsFile(EndianBinaryReader reader)
{
Signature = reader.ReadBytes(4);
Version = reader.ReadInt16();
Reserved = reader.ReadInt16();
DataCrc = reader.ReadUInt32();
DataSize = reader.ReadInt32();
CheckHeader(reader.BaseStream.Length);
Data = reader.ReadBytes(DataSize);
}
public void CheckHeader(long fileLength)
{
if (!Signature.AsSpan().SequenceEqual(OptionsFileSign))
throw new NotSupportedException("Incorrect options file signature.");
if (Version != 1)
throw new NotSupportedException("Incorrect options file version.");
if (DataSize <= 0 || DataSize > fileLength)
throw new NotSupportedException("Incorrect data size.");
}
public byte[] ToByteArray()
{
var buffer = new byte[16 + DataSize];
OptionsFileSign.AsSpan().CopyTo(buffer);
BinaryPrimitives.WriteInt16BigEndian(buffer.AsSpan(4), Version);
BinaryPrimitives.WriteInt16BigEndian(buffer.AsSpan(6), Reserved);
BinaryPrimitives.WriteUInt32BigEndian(buffer.AsSpan(8), DataCrc);
BinaryPrimitives.WriteInt32BigEndian(buffer.AsSpan(12), DataSize);
Data.AsSpan().CopyTo(buffer.AsSpan(16));
return buffer;
}
}
}

View File

@@ -1,40 +0,0 @@
namespace AssetStudio.CustomOptions
{
public class CustomBundleOptions
{
private CompressionType _customBlockCompression = CompressionType.Auto;
private CompressionType _customBlockInfoCompression = CompressionType.Auto;
private bool _decompressToDisk;
public ImportOptions Options;
public CompressionType CustomBlockCompression
{
get => _customBlockCompression;
set => _customBlockCompression = SetOption(nameof(CustomBlockCompression), value);
}
public CompressionType CustomBlockInfoCompression
{
get => _customBlockInfoCompression;
set => _customBlockInfoCompression = SetOption(nameof(CustomBlockInfoCompression), value);
}
public bool DecompressToDisk
{
get => _decompressToDisk;
set => _decompressToDisk = SetOption(nameof(DecompressToDisk), value);
}
public CustomBundleOptions() { }
public CustomBundleOptions(ImportOptions importOptions)
{
Options = importOptions;
}
private static T SetOption<T>(string option, T value)
{
Logger.Info($"- {option}: {value}");
return value;
}
}
}

View File

@@ -1,94 +0,0 @@
using AssetStudio.CustomOptions.Asmo;
using SevenZip;
using System;
using System.IO;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace AssetStudio.CustomOptions
{
public class ImportOptions
{
private static JsonSerializerOptions jsonOptions;
private static string fileName = "ImportOptions";
private UnityVersion _customUnityVer;
public CustomBundleOptions BundleOptions { get; set; }
public UnityVersion CustomUnityVersion { get => _customUnityVer; set => SetUnityVersion(value); }
static ImportOptions()
{
jsonOptions = new JsonSerializerOptions
{
ReferenceHandler = ReferenceHandler.Preserve,
IncludeFields = true,
};
}
public ImportOptions()
{
BundleOptions = new CustomBundleOptions(this);
CustomUnityVersion = null;
}
public static ImportOptions FromOptionsFile(OptionsFile optionsFile)
{
if (optionsFile.Reserved != 0)
{
Logger.Debug("Skipped. Not an import options file.");
return null;
}
var utf8Bytes = Convert.FromBase64String(Encoding.ASCII.GetString(optionsFile.Data));
var dataCrc = CRC.CalculateDigest(utf8Bytes, 0, (uint)utf8Bytes.Length);
if (optionsFile.DataCrc != dataCrc)
throw new IOException("Options file data is corrupted.");
return JsonSerializer.Deserialize<ImportOptions>(utf8Bytes, jsonOptions);
}
public void SaveToFile(string outputFolder)
{
var utf8Bytes = JsonSerializer.SerializeToUtf8Bytes(this, jsonOptions);
var dataCrc = CRC.CalculateDigest(utf8Bytes, 0, (uint)utf8Bytes.Length);
var base64String = Convert.ToBase64String(utf8Bytes);
var optionsFile = new OptionsFile
{
DataCrc = dataCrc,
DataSize = base64String.Length,
Data = Encoding.ASCII.GetBytes(base64String),
};
var unityVer = _customUnityVer != null
? $"_{_customUnityVer}"
: "";
var path = Path.Combine(outputFolder, $"{fileName}{unityVer}{OptionsFile.Extension}");
File.WriteAllBytes(path, optionsFile.ToByteArray());
Logger.Info($"Options file saved to \"{path}\"");
}
private void SetUnityVersion(UnityVersion value)
{
if (_customUnityVer == value)
return;
if (value == null)
{
_customUnityVer = null;
Logger.Info("- Specified Unity version: None");
return;
}
if (string.IsNullOrEmpty(value.BuildType))
{
throw new NotSupportedException("Specified Unity version is not in a correct format.\n" +
"Specify full Unity version, including letters at the end.\n" +
"Example: 2017.4.39f1");
}
_customUnityVer = value;
Logger.Info($"- Specified Unity version: {_customUnityVer}");
}
}
}

View File

@@ -82,13 +82,12 @@ namespace AssetStudio
return base.ReadUInt64();
}
#if NETFRAMEWORK
public override float ReadSingle()
{
if (Endian == EndianType.BigEndian)
{
Read(buffer, 0, 4);
buffer.AsSpan(0, 4).Reverse();
Array.Reverse(buffer, 0, 4);
return BitConverter.ToSingle(buffer, 0);
}
return base.ReadSingle();
@@ -99,31 +98,10 @@ namespace AssetStudio
if (Endian == EndianType.BigEndian)
{
Read(buffer, 0, 8);
buffer.AsSpan().Reverse();
Array.Reverse(buffer);
return BitConverter.ToDouble(buffer, 0);
}
return base.ReadDouble();
}
#else
public override float ReadSingle()
{
if (Endian == EndianType.BigEndian)
{
Read(buffer, 0, 4);
return BinaryPrimitives.ReadSingleBigEndian(buffer);
}
return base.ReadSingle();
}
public override double ReadDouble()
{
if (Endian == EndianType.BigEndian)
{
Read(buffer, 0, 8);
return BinaryPrimitives.ReadDoubleBigEndian(buffer);
}
return base.ReadDouble();
}
#endif
}
}

View File

@@ -1,95 +0,0 @@
using System;
using System.Buffers.Binary;
using System.Text;
namespace AssetStudio
{
public static class EndianSpanReader
{
public static uint ReadUInt32(this Span<byte> data, int start, bool isBigEndian)
{
return ReadUInt32((ReadOnlySpan<byte>)data, start, isBigEndian);
}
public static uint ReadUInt32(this ReadOnlySpan<byte> data, int start, bool isBigEndian)
{
return isBigEndian
? BinaryPrimitives.ReadUInt32BigEndian(data.Slice(start))
: BinaryPrimitives.ReadUInt32LittleEndian(data.Slice(start));
}
public static long ReadUInt16(this Span<byte> data, int start, bool isBigEndian)
{
return ReadUInt16((ReadOnlySpan<byte>)data, start, isBigEndian);
}
public static uint ReadUInt16(this ReadOnlySpan<byte> data, int start, bool isBigEndian)
{
return isBigEndian
? BinaryPrimitives.ReadUInt16BigEndian(data.Slice(start))
: BinaryPrimitives.ReadUInt16LittleEndian(data.Slice(start));
}
public static long ReadInt64(this Span<byte> data, int start, bool isBigEndian)
{
return ReadInt64((ReadOnlySpan<byte>)data, start, isBigEndian);
}
public static long ReadInt64(this ReadOnlySpan<byte> data, int start, bool isBigEndian)
{
return isBigEndian
? BinaryPrimitives.ReadInt64BigEndian(data.Slice(start))
: BinaryPrimitives.ReadInt64LittleEndian(data.Slice(start));
}
public static float ReadSingle(this Span<byte> data, int start, bool isBigEndian)
{
return ReadSingle((ReadOnlySpan<byte>)data, start, isBigEndian);
}
#if NETFRAMEWORK
public static float ReadSingle(this ReadOnlySpan<byte> data, int start, bool isBigEndian)
{
var bytes = data.Slice(start, 4).ToArray();
if ((isBigEndian && BitConverter.IsLittleEndian) || (!isBigEndian && !BitConverter.IsLittleEndian))
bytes.AsSpan().Reverse();
return BitConverter.ToSingle(bytes, 0);
}
#else
public static float ReadSingle(this ReadOnlySpan<byte> data, int start, bool isBigEndian)
{
return isBigEndian
? BinaryPrimitives.ReadSingleBigEndian(data[start..])
: BinaryPrimitives.ReadSingleLittleEndian(data[start..]);
}
#endif
public static string ReadStringToNull(this Span<byte> data, int maxLength = 32767)
{
return ReadStringToNull((ReadOnlySpan<byte>)data, maxLength);
}
public static string ReadStringToNull(this ReadOnlySpan<byte> data, int maxLength = 32767)
{
Span<byte> bytes = stackalloc byte[maxLength];
var count = 0;
while (count != data.Length && count < maxLength)
{
var b = data[count];
if (b == 0)
{
break;
}
bytes[count] = b;
count++;
}
bytes = bytes.Slice(0, count);
#if NETFRAMEWORK
return Encoding.UTF8.GetString(bytes.ToArray());
#else
return Encoding.UTF8.GetString(bytes);
#endif
}
}
}

View File

@@ -1,14 +1,18 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
namespace AssetStudio
{
public static class BinaryReaderExtensions
{
public static void AlignStream(this BinaryReader reader, int alignment = 4)
public static void AlignStream(this BinaryReader reader)
{
reader.AlignStream(4);
}
public static void AlignStream(this BinaryReader reader, int alignment)
{
var pos = reader.BaseStream.Position;
var mod = pos % alignment;
@@ -21,13 +25,11 @@ namespace AssetStudio
public static string ReadAlignedString(this BinaryReader reader)
{
var length = reader.ReadInt32();
if (length > reader.BaseStream.Length - reader.BaseStream.Position)
throw new EndOfStreamException();
if (length > 0)
if (length > 0 && length <= reader.BaseStream.Length - reader.BaseStream.Position)
{
var stringData = reader.ReadBytes(length);
var result = Encoding.UTF8.GetString(stringData);
reader.AlignStream();
reader.AlignStream(4);
return result;
}
return "";
@@ -38,7 +40,7 @@ namespace AssetStudio
if (encoding?.CodePage == 1200) //Unicode (UTF-16LE)
return reader.ReadUnicodeStringToNull(maxLength * 2);
Span<byte> bytes = stackalloc byte[maxLength];
var bytes = new List<byte>();
var count = 0;
while (reader.BaseStream.Position != reader.BaseStream.Length && count < maxLength)
{
@@ -47,15 +49,10 @@ namespace AssetStudio
{
break;
}
bytes[count] = b;
bytes.Add(b);
count++;
}
bytes = bytes.Slice(0, count);
#if NETFRAMEWORK
return encoding?.GetString(bytes.ToArray()) ?? Encoding.UTF8.GetString(bytes.ToArray());
#else
return encoding?.GetString(bytes) ?? Encoding.UTF8.GetString(bytes);
#endif
}
private static string ReadUnicodeStringToNull(this BinaryReader reader, int maxLength)
@@ -100,22 +97,24 @@ namespace AssetStudio
return new Color(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
}
private static T[] ReadArray<T>(BinaryReader reader, int byteLen) where T : struct
public static Matrix4x4 ReadMatrix(this BinaryReader reader)
{
if (byteLen < 0)
throw new ArgumentOutOfRangeException(nameof(byteLen));
if (reader.BaseStream.Position + byteLen > reader.BaseStream.Length)
throw new EndOfStreamException();
var bytes = reader.ReadBytes(byteLen);
return new Matrix4x4(reader.ReadSingleArray(16));
}
var span = MemoryMarshal.Cast<byte, T>(bytes);
return span.ToArray();
private static T[] ReadArray<T>(Func<T> del, int length)
{
var array = new T[length];
for (int i = 0; i < length; i++)
{
array[i] = del();
}
return array;
}
public static bool[] ReadBooleanArray(this BinaryReader reader)
{
return ReadArray<bool>(reader, reader.ReadInt32());
return ReadArray(reader.ReadBoolean, reader.ReadInt32());
}
public static byte[] ReadUInt8Array(this BinaryReader reader)
@@ -125,65 +124,62 @@ namespace AssetStudio
public static ushort[] ReadUInt16Array(this BinaryReader reader)
{
return ReadArray<ushort>(reader, reader.ReadInt32() * 2);
return ReadArray(reader.ReadUInt16, reader.ReadInt32());
}
public static int[] ReadInt32Array(this BinaryReader reader, int length = -1)
public static int[] ReadInt32Array(this BinaryReader reader)
{
if (length == -1)
length = reader.ReadInt32();
return ReadArray<int>(reader, length * 4);
return ReadArray(reader.ReadInt32, reader.ReadInt32());
}
public static uint[] ReadUInt32Array(this BinaryReader reader, int length = -1)
public static int[] ReadInt32Array(this BinaryReader reader, int length)
{
if (length == -1)
length = reader.ReadInt32();
return ReadArray<uint>(reader, length * 4);
return ReadArray(reader.ReadInt32, length);
}
public static uint[] ReadUInt32Array(this BinaryReader reader)
{
return ReadArray(reader.ReadUInt32, reader.ReadInt32());
}
public static uint[][] ReadUInt32ArrayArray(this BinaryReader reader)
{
var length = reader.ReadInt32();
var list = new List<uint[]>();
for (var i = 0; i < length; i++)
{
list.Add(ReadArray<uint>(reader, reader.ReadInt32() * 4));
}
return list.ToArray();
return ReadArray(reader.ReadUInt32Array, reader.ReadInt32());
}
public static float[] ReadSingleArray(this BinaryReader reader, int length = -1)
public static uint[] ReadUInt32Array(this BinaryReader reader, int length)
{
if (length == -1)
length = reader.ReadInt32();
return ReadArray<float>(reader, length * 4);
return ReadArray(reader.ReadUInt32, length);
}
public static float[] ReadSingleArray(this BinaryReader reader)
{
return ReadArray(reader.ReadSingle, reader.ReadInt32());
}
public static float[] ReadSingleArray(this BinaryReader reader, int length)
{
return ReadArray(reader.ReadSingle, length);
}
public static string[] ReadStringArray(this BinaryReader reader)
{
var length = reader.ReadInt32();
var list = new List<string>();
for (var i = 0; i < length; i++)
{
list.Add(reader.ReadAlignedString());
}
return list.ToArray();
return ReadArray(reader.ReadAlignedString, reader.ReadInt32());
}
public static Vector2[] ReadVector2Array(this BinaryReader reader)
{
return ReadArray<Vector2>(reader, reader.ReadInt32() * 8);
return ReadArray(reader.ReadVector2, reader.ReadInt32());
}
public static Vector4[] ReadVector4Array(this BinaryReader reader)
{
return ReadArray<Vector4>(reader, reader.ReadInt32() * 16);
return ReadArray(reader.ReadVector4, reader.ReadInt32());
}
public static Matrix4x4[] ReadMatrixArray(this BinaryReader reader)
{
return ReadArray<Matrix4x4>(reader, reader.ReadInt32() * 64);
return ReadArray(reader.ReadMatrix, reader.ReadInt32());
}
}
}

View File

@@ -1,5 +1,5 @@
using System;
using System.IO;
using System.IO;
using System.Linq;
namespace AssetStudio
{
@@ -13,9 +13,6 @@ namespace AssetStudio
private static readonly byte[] brotliMagic = { 0x62, 0x72, 0x6F, 0x74, 0x6C, 0x69 };
private static readonly byte[] zipMagic = { 0x50, 0x4B, 0x03, 0x04 };
private static readonly byte[] zipSpannedMagic = { 0x50, 0x4B, 0x07, 0x08 };
private static readonly byte[] unityFsMagic = {0x55, 0x6E, 0x69, 0x74, 0x79, 0x46, 0x53, 0x00};
private static readonly int headerBuffLen = 1152;
private static byte[] headerBuff = new byte[headerBuffLen];
public FileReader(string path) : this(path, File.Open(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { }
@@ -28,117 +25,78 @@ namespace AssetStudio
private FileType CheckFileType()
{
var buff = headerBuff.AsSpan();
buff.Clear();
var dataLen = Read(headerBuff, 0, headerBuffLen);
var signature = this.ReadStringToNull(20);
Position = 0;
var signature = buff.ReadStringToNull(20);
switch (signature)
{
case "UnityWeb":
case "UnityRaw":
case "UnityArchive":
case "UnityFS":
CheckBundleDataOffset(buff);
return FileType.BundleFile;
case "UnityWebData1.0":
case "TuanjieWebData1.0":
return FileType.WebFile;
default:
{
var magic = Span<byte>.Empty;
magic = dataLen > 2 ? buff.Slice(0, 2) : magic;
if (magic.SequenceEqual(gzipMagic))
{
return FileType.GZipFile;
byte[] magic = ReadBytes(2);
Position = 0;
if (gzipMagic.SequenceEqual(magic))
{
return FileType.GZipFile;
}
Position = 0x20;
magic = ReadBytes(6);
Position = 0;
if (brotliMagic.SequenceEqual(magic))
{
return FileType.BrotliFile;
}
if (IsSerializedFile())
{
return FileType.AssetsFile;
}
magic = ReadBytes(4);
Position = 0;
if (zipMagic.SequenceEqual(magic) || zipSpannedMagic.SequenceEqual(magic))
return FileType.ZipFile;
return FileType.ResourceFile;
}
magic = dataLen > 38 ? buff.Slice(32, 6) : magic;
if (magic.SequenceEqual(brotliMagic))
{
return FileType.BrotliFile;
}
if (IsSerializedFile(buff))
{
return FileType.AssetsFile;
}
magic = dataLen > 4 ? buff.Slice(0, 4): magic;
if (magic.SequenceEqual(zipMagic) || magic.SequenceEqual(zipSpannedMagic))
{
return FileType.ZipFile;
}
if (CheckBundleDataOffset(buff))
{
return FileType.BundleFile;
}
return FileType.ResourceFile;
}
}
}
private bool IsSerializedFile(ReadOnlySpan<byte> buff)
private bool IsSerializedFile()
{
var fileSize = BaseStream.Length;
if (fileSize < 20)
{
return false;
}
var isBigEndian = Endian == EndianType.BigEndian;
//var m_MetadataSize = buff.ReadUInt32(0, isBigEndian);
long m_FileSize = buff.ReadUInt32(4, isBigEndian);
var m_Version = buff.ReadUInt32(8, isBigEndian);
long m_DataOffset = buff.ReadUInt32(12, isBigEndian);
//var m_Endianess = buff[16];
//var m_Reserved = buff.Slice(17, 3);
var m_MetadataSize = ReadUInt32();
long m_FileSize = ReadUInt32();
var m_Version = ReadUInt32();
long m_DataOffset = ReadUInt32();
var m_Endianess = ReadByte();
var m_Reserved = ReadBytes(3);
if (m_Version >= 22)
{
if (fileSize < 48)
{
Position = 0;
return false;
}
//m_MetadataSize = buff.ReadUInt32(20, isBigEndian);
m_FileSize = buff.ReadInt64(24, isBigEndian);
m_DataOffset = buff.ReadInt64(32, isBigEndian);
m_MetadataSize = ReadUInt32();
m_FileSize = ReadInt64();
m_DataOffset = ReadInt64();
}
if (m_FileSize != fileSize || m_DataOffset > fileSize)
Position = 0;
if (m_FileSize != fileSize)
{
return false;
}
return true;
}
private bool CheckBundleDataOffset(ReadOnlySpan<byte> buff)
{
var lastOffset = buff.LastIndexOf(unityFsMagic);
if (lastOffset <= 0)
if (m_DataOffset > fileSize)
{
return false;
var firstOffset = buff.IndexOf(unityFsMagic);
if (firstOffset == lastOffset || lastOffset - firstOffset < 200)
{
Position = lastOffset;
return true;
}
var pos = firstOffset + 12;
pos += buff.Slice(pos).ReadStringToNull().Length + 1;
pos += buff.Slice(pos).ReadStringToNull().Length + 1;
var bundleSize = buff.ReadInt64(pos, Endian == EndianType.BigEndian);
if (bundleSize > 200 && firstOffset + bundleSize < lastOffset)
{
Position = firstOffset;
return true;
}
Position = lastOffset;
return true;
}
}

View File

@@ -1,4 +1,10 @@
namespace AssetStudio
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AssetStudio
{
public enum FileType
{

View File

@@ -68,7 +68,7 @@ namespace AssetStudio
}
catch (System.Exception e)
{
Logger.Warning($"Error while decompressing Gzip file {reader.FullPath}\n{e}");
Logger.Warning($"Error while decompressing gzip file {reader.FullPath}\r\n{e}");
reader.Dispose();
return null;
}
@@ -76,24 +76,15 @@ namespace AssetStudio
public static FileReader DecompressBrotli(FileReader reader)
{
try
using (reader)
{
using (reader)
var stream = new MemoryStream();
using (var brotliStream = new BrotliInputStream(reader.BaseStream))
{
var stream = new MemoryStream();
using (var brotliStream = new BrotliInputStream(reader.BaseStream))
{
brotliStream.CopyTo(stream);
}
stream.Position = 0;
return new FileReader(reader.FullPath, stream);
brotliStream.CopyTo(stream);
}
}
catch (System.Exception e)
{
Logger.Warning($"Error while decompressing Brotli file {reader.FullPath}\n{e}");
reader.Dispose();
return null;
stream.Position = 0;
return new FileReader(reader.FullPath, stream);
}
}
}

View File

@@ -1,25 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace AssetStudio
{
public static partial class JsonConverterHelper
{
public class ByteArrayConverter : JsonConverter<byte[]>
{
public override byte[] Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
return reader.TokenType == JsonTokenType.StartArray
? JsonSerializer.Deserialize<List<byte>>(ref reader).ToArray() //JsonArray to ByteArray
: JsonSerializer.Deserialize<byte[]>(ref reader);
}
public override void Write(Utf8JsonWriter writer, byte[] value, JsonSerializerOptions options)
{
writer.WriteBase64StringValue(value);
}
}
}
}

View File

@@ -1,40 +0,0 @@
using System;
using System.Globalization;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace AssetStudio
{
public static partial class JsonConverterHelper
{
public class FloatConverter : JsonConverter<float>
{
public override float Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
return JsonSerializer.Deserialize<float>(ref reader, new JsonSerializerOptions
{
NumberHandling = options.NumberHandling
});
}
public override void Write(Utf8JsonWriter writer, float value, JsonSerializerOptions options)
{
if (float.IsNaN(value) || float.IsInfinity(value))
{
if (options.NumberHandling == JsonNumberHandling.AllowNamedFloatingPointLiterals)
{
writer.WriteStringValue($"{value.ToString(CultureInfo.InvariantCulture)}");
}
else
{
writer.WriteStringValue(JsonSerializer.Serialize(value));
}
}
else
{
writer.WriteNumberValue((decimal)value + 0.0m);
}
}
}
}
}

View File

@@ -1,53 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace AssetStudio
{
public static partial class JsonConverterHelper
{
public class KVPConverter : JsonConverterFactory
{
public override bool CanConvert(Type typeToConvert)
{
if (!typeToConvert.IsGenericType)
return false;
var generic = typeToConvert.GetGenericTypeDefinition();
return generic == typeof(KeyValuePair<,>);
}
public override JsonConverter CreateConverter(Type type, JsonSerializerOptions options)
{
var kvpArgs = type.GetGenericArguments();
return (JsonConverter)Activator.CreateInstance(typeof(KVPConverter<,>).MakeGenericType(kvpArgs));
}
}
private class KVPConverter<TKey, TValue> : JsonConverter<KeyValuePair<TKey, TValue>>
{
public override KeyValuePair<TKey, TValue> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
//startKvpObject
reader.Read(); //propName
reader.Read(); //keyType
var key = reader.TokenType == JsonTokenType.StartObject
? JsonSerializer.Deserialize<Dictionary<string, TKey>>(ref reader).Values.First()
: JsonSerializer.Deserialize<TKey>(ref reader);
reader.Read(); //propName
reader.Read(); //startObject
var value = JsonSerializer.Deserialize<TValue>(ref reader, options);
reader.Read(); //endKvpObject
return new KeyValuePair<TKey, TValue>(key, value);
}
public override void Write(Utf8JsonWriter writer, KeyValuePair<TKey, TValue> value, JsonSerializerOptions options)
{
throw new NotImplementedException();
}
}
}
}

View File

@@ -1,45 +0,0 @@
using System;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace AssetStudio
{
public static partial class JsonConverterHelper
{
public static SerializedFile AssetsFile { get; set; }
public class PPtrConverter : JsonConverterFactory
{
public override bool CanConvert(Type typeToConvert)
{
if (!typeToConvert.IsGenericType)
return false;
var generic = typeToConvert.GetGenericTypeDefinition();
return generic == typeof(PPtr<>);
}
public override JsonConverter CreateConverter(Type type, JsonSerializerOptions options)
{
var elementType = type.GetGenericArguments()[0];
var converter = (JsonConverter)Activator.CreateInstance(typeof(PPtrConverter<>).MakeGenericType(elementType));
return converter;
}
}
private class PPtrConverter<T> : JsonConverter<PPtr<T>> where T : Object
{
public override PPtr<T> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
var pptrObj = JsonSerializer.Deserialize<PPtr<T>>(ref reader, new JsonSerializerOptions { IncludeFields = true });
pptrObj.AssetsFile = AssetsFile;
return pptrObj;
}
public override void Write(Utf8JsonWriter writer, PPtr<T> value, JsonSerializerOptions options)
{
throw new NotImplementedException();
}
}
}
}

View File

@@ -1,58 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Text.Json.Serialization;
namespace AssetStudio
{
public static partial class JsonConverterHelper
{
public class RenderDataMapConverter : JsonConverter<Dictionary<KeyValuePair<Guid, long>, SpriteAtlasData>>
{
public override Dictionary<KeyValuePair<Guid, long>, SpriteAtlasData> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
var dataArray = JsonSerializer.Deserialize<KeyValuePair<JsonObject, SpriteAtlasData>[]>(ref reader, options);
var renderDataMap = new Dictionary<KeyValuePair<Guid, long>, SpriteAtlasData>(dataArray.Length);
foreach (var kvp in dataArray)
{
var jsonFirst = kvp.Key["first"];
var first = jsonFirst.Deserialize<GUID>(options).Convert();
var second = (long) kvp.Key["second"];
renderDataMap.Add(new KeyValuePair<Guid, long>(first, second), kvp.Value);
}
return renderDataMap;
}
public override void Write(Utf8JsonWriter writer, Dictionary<KeyValuePair<Guid, long>, SpriteAtlasData> value, JsonSerializerOptions options)
{
var jsonDict = new Dictionary<string, SpriteAtlasData>();
foreach (var kv in value)
{
var strKey = $"{kv.Key.Key}, {kv.Key.Value}";
jsonDict.Add(strKey, kv.Value);
}
var strValue = JsonSerializer.SerializeToUtf8Bytes(jsonDict, options);
writer.WriteRawValue(strValue);
}
}
private class GUID
{
[JsonPropertyName("data[0]")] public uint data0 { get; set; }
[JsonPropertyName("data[1]")] public uint data1 { get; set; }
[JsonPropertyName("data[2]")] public uint data2 { get; set; }
[JsonPropertyName("data[3]")] public uint data3 { get; set; }
public Guid Convert()
{
var guidBytes = new byte[16];
BitConverter.GetBytes(data0).CopyTo(guidBytes, 0);
BitConverter.GetBytes(data1).CopyTo(guidBytes, 4);
BitConverter.GetBytes(data2).CopyTo(guidBytes, 8);
BitConverter.GetBytes(data3).CopyTo(guidBytes, 12);
return new Guid(guidBytes);
}
}
}
}

75
AssetStudio/LZ4/LZ4.cs Normal file
View File

@@ -0,0 +1,75 @@
using System;
namespace AssetStudio
{
public class LZ4
{
public static LZ4 Instance => new LZ4();
public virtual int Decompress(ReadOnlySpan<byte> cmp, Span<byte> dec)
{
int cmpPos = 0;
int decPos = 0;
do
{
var (encCount, litCount) = GetLiteralToken(cmp, ref cmpPos);
//Copy literal chunk
litCount = GetLength(litCount, cmp, ref cmpPos);
cmp.Slice(cmpPos, litCount).CopyTo(dec.Slice(decPos));
cmpPos += litCount;
decPos += litCount;
if (cmpPos >= cmp.Length)
{
break;
}
//Copy compressed chunk
int back = GetChunkEnd(cmp, ref cmpPos);
encCount = GetLength(encCount, cmp, ref cmpPos) + 4;
int encPos = decPos - back;
if (encCount <= back)
{
dec.Slice(encPos, encCount).CopyTo(dec.Slice(decPos));
decPos += encCount;
}
else
{
while (encCount-- > 0)
{
dec[decPos++] = dec[encPos++];
}
}
} while (cmpPos < cmp.Length && decPos < dec.Length);
return decPos;
}
protected virtual (int encCount, int litCount) GetLiteralToken(ReadOnlySpan<byte> cmp, ref int cmpPos) =>
((cmp[cmpPos] >> 0) & 0xf, (cmp[cmpPos++] >> 4) & 0xf);
protected virtual int GetChunkEnd(ReadOnlySpan<byte> cmp, ref int cmpPos) =>
cmp[cmpPos++] << 0 | cmp[cmpPos++] << 8;
protected virtual int GetLength(int length, ReadOnlySpan<byte> cmp, ref int cmpPos)
{
byte sum;
if (length == 0xf)
{
do
{
length += sum = cmp[cmpPos++];
} while (sum == 0xff);
}
return length;
}
}
}

15
AssetStudio/LZ4/LZ4Inv.cs Normal file
View File

@@ -0,0 +1,15 @@
using System;
namespace AssetStudio
{
public class LZ4Inv : LZ4
{
public new static LZ4Inv Instance => new LZ4Inv();
protected override (int encCount, int litCount) GetLiteralToken(ReadOnlySpan<byte> cmp, ref int cmpPos) =>
((cmp[cmpPos] >> 4) & 0xf, (cmp[cmpPos++] >> 0) & 0xf);
protected override int GetChunkEnd(ReadOnlySpan<byte> cmp, ref int cmpPos) =>
cmp[cmpPos++] << 8 | cmp[cmpPos++] << 0;
}
}

View File

@@ -1,18 +0,0 @@
using System;
using System.Runtime.CompilerServices;
namespace AssetStudio
{
public static partial class MathHelper
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float Clamp(float value, float minValue, float maxValue)
{
#if NETFRAMEWORK
return Math.Max(minValue, Math.Min(value, maxValue));
#else
return Math.Clamp(value, minValue, maxValue);
#endif
}
}
}

View File

@@ -2,7 +2,6 @@
using System.Diagnostics;
using System.Globalization;
#if NETFRAMEWORK
namespace AssetStudio
{
/// <summary>
@@ -36,27 +35,27 @@ namespace AssetStudio
/// <summary>
/// Represents the smallest positive System.Half value greater than zero. This field is constant.
/// </summary>
public static readonly Half Epsilon = HalfHelper.ToHalf(0x0001);
public static readonly Half Epsilon = Half.ToHalf(0x0001);
/// <summary>
/// Represents the largest possible value of System.Half. This field is constant.
/// </summary>
public static readonly Half MaxValue = HalfHelper.ToHalf(0x7bff);
public static readonly Half MaxValue = Half.ToHalf(0x7bff);
/// <summary>
/// Represents the smallest possible value of System.Half. This field is constant.
/// </summary>
public static readonly Half MinValue = HalfHelper.ToHalf(0xfbff);
public static readonly Half MinValue = Half.ToHalf(0xfbff);
/// <summary>
/// Represents not a number (NaN). This field is constant.
/// </summary>
public static readonly Half NaN = HalfHelper.ToHalf(0xfe00);
public static readonly Half NaN = Half.ToHalf(0xfe00);
/// <summary>
/// Represents negative infinity. This field is constant.
/// </summary>
public static readonly Half NegativeInfinity = HalfHelper.ToHalf(0xfc00);
public static readonly Half NegativeInfinity = Half.ToHalf(0xfc00);
/// <summary>
/// Represents positive infinity. This field is constant.
/// </summary>
public static readonly Half PositiveInfinity = HalfHelper.ToHalf(0x7c00);
public static readonly Half PositiveInfinity = Half.ToHalf(0x7c00);
#endregion
#region Constructors
@@ -64,7 +63,7 @@ namespace AssetStudio
/// Initializes a new instance of System.Half to the value of the specified single-precision floating-point number.
/// </summary>
/// <param name="value">The value to represent as a System.Half.</param>
public Half(float value) { this = HalfHelper.ToHalf(value); }
public Half(float value) { this = HalfHelper.SingleToHalf(value); }
/// <summary>
/// Initializes a new instance of System.Half to the value of the specified 32-bit signed integer.
/// </summary>
@@ -315,7 +314,7 @@ namespace AssetStudio
/// </summary>
/// <param name="value">A System.Half to convert.</param>
/// <returns>A single-precision floating-point number that represents the converted System.Half.</returns>
public static implicit operator float(Half value) { return value.ToSingle(); }
public static implicit operator float(Half value) { return (float)HalfHelper.HalfToSingle(value); }
/// <summary>
/// Converts a System.Half to a double-precision floating-point number.
/// </summary>
@@ -509,6 +508,32 @@ namespace AssetStudio
{
return value.value;
}
/// <summary>
/// Returns a half-precision floating point number converted from two bytes
/// at a specified position in a byte array.
/// </summary>
/// <param name="value">An array of bytes.</param>
/// <param name="startIndex">The starting position within value.</param>
/// <returns>A half-precision floating point number formed by two bytes beginning at startIndex.</returns>
/// <exception cref="System.ArgumentException">
/// startIndex is greater than or equal to the length of value minus 1, and is
/// less than or equal to the length of value minus 1.
/// </exception>
/// <exception cref="System.ArgumentNullException">value is null.</exception>
/// <exception cref="System.ArgumentOutOfRangeException">startIndex is less than zero or greater than the length of value minus 1.</exception>
public static Half ToHalf(byte[] value, int startIndex)
{
return Half.ToHalf((ushort)BitConverter.ToInt16(value, startIndex));
}
/// <summary>
/// Returns a half-precision floating point number converted from its binary representation.
/// </summary>
/// <param name="bits">Binary representation of System.Half value</param>
/// <returns>A half-precision floating point number formed by its binary representation.</returns>
public static Half ToHalf(ushort bits)
{
return new Half { value = bits };
}
/// <summary>
/// Returns a value indicating the sign of a half-precision floating-point number.
@@ -861,4 +886,3 @@ namespace AssetStudio
#endregion
}
}
#endif

View File

@@ -1,32 +1,18 @@
using System;
using System.Buffers.Binary;
using System.Runtime.InteropServices;
namespace AssetStudio
{
#if NET
public static class HalfHelper
{
public static Half ToHalf(ushort bits)
{
return (Half)bits;
}
public static Half ToHalf(ReadOnlySpan<byte> bytes, int startIndex)
{
return BinaryPrimitives.ReadHalfLittleEndian(bytes[startIndex..]);
}
}
#else
/// <summary>
/// Helper class for Half conversions and some low level operations.
/// This class is internally used in the Half class.
/// </summary>
/// <remarks>
/// References:
/// - Fast Half Float Conversions, Jeroen van der Zijp, link: http://www.fox-toolkit.org/ftp/fasthalffloatconversion.pdf
/// </remarks>
[ComVisible(false)]
public static class HalfHelper
internal static class HalfHelper
{
private static uint[] mantissaTable = GenerateMantissaTable();
private static uint[] exponentTable = GenerateExponentTable();
@@ -183,54 +169,27 @@ namespace AssetStudio
ushort result = (ushort)(baseTable[(value >> 23) & 0x1ff] + ((value & 0x007fffff) >> shiftTable[value >> 23]));
return Half.ToHalf(result);
}*/
/// <summary>
/// Returns a half-precision floating point number converted from two bytes
/// at a specified position in a byte array.
/// </summary>
/// <param name="value">An array of bytes.</param>
/// <param name="startIndex">The starting position within value.</param>
/// <returns>A half-precision floating point number formed by two bytes beginning at startIndex.</returns>
/// <exception cref="System.ArgumentException">
/// startIndex is greater than or equal to the length of value minus 1, and is
/// less than or equal to the length of value minus 1.
/// </exception>
/// <exception cref="System.ArgumentNullException">value is null.</exception>
/// <exception cref="System.ArgumentOutOfRangeException">startIndex is less than zero or greater than the length of value minus 1.</exception>
public static Half ToHalf(ReadOnlySpan<byte> value, int startIndex)
{
return ToHalf((ushort)BinaryPrimitives.ReadInt16LittleEndian(value.Slice(startIndex)));
}
/// <summary>
/// Returns a half-precision floating point number converted from its binary representation.
/// </summary>
/// <param name="bits">Binary representation of System.Half value</param>
/// <returns>A half-precision floating point number formed by its binary representation.</returns>
public static Half ToHalf(ushort bits)
{
return new Half { value = bits };
}
public static Half ToHalf(float single)
{
byte[] singleBytes = BitConverter.GetBytes(single);
uint value = BitConverter.ToUInt32(singleBytes, 0);
ushort result = (ushort)(baseTable[(value >> 23) & 0x1ff] + ((value & 0x007fffff) >> shiftTable[value >> 23]));
return ToHalf(result);
}
public static float ToSingle(this Half half)
public static float HalfToSingle(Half half)
{
uint result = mantissaTable[offsetTable[half.value >> 10] + (half.value & 0x3ff)] + exponentTable[half.value >> 10];
byte[] uintBytes = BitConverter.GetBytes(result);
return BitConverter.ToSingle(uintBytes, 0);
}
public static Half SingleToHalf(float single)
{
byte[] singleBytes = BitConverter.GetBytes(single);
uint value = BitConverter.ToUInt32(singleBytes, 0);
ushort result = (ushort)(baseTable[(value >> 23) & 0x1ff] + ((value & 0x007fffff) >> shiftTable[value >> 23]));
return Half.ToHalf(result);
}
public static Half Negate(Half half)
{
return ToHalf((ushort)(half.value ^ 0x8000));
return Half.ToHalf((ushort)(half.value ^ 0x8000));
}
public static Half Abs(Half half)
{
return ToHalf((ushort)(half.value & 0x7fff));
return Half.ToHalf((ushort)(half.value & 0x7fff));
}
public static bool IsNaN(Half half)
@@ -250,5 +209,4 @@ namespace AssetStudio
return (half.value == 0xfc00);
}
}
#endif
}

View File

@@ -26,9 +26,9 @@ namespace AssetStudio
public float M23;
public float M33;
public Matrix4x4(Span<float> values)
public Matrix4x4(float[] values)
{
if (values.IsEmpty)
if (values == null)
throw new ArgumentNullException(nameof(values));
if (values.Length != 16)
throw new ArgumentOutOfRangeException(nameof(values), "There must be sixteen and only sixteen input values for Matrix.");

View File

@@ -45,9 +45,9 @@ namespace AssetStudio
public override bool Equals(object other)
{
if (!(other is Vector2 vector2))
if (!(other is Vector2))
return false;
return Equals(vector2);
return Equals((Vector2)other);
}
public bool Equals(Vector2 other)
@@ -73,7 +73,7 @@ namespace AssetStudio
public float Length()
{
return MathF.Sqrt(LengthSquared());
return (float)Math.Sqrt(LengthSquared());
}
public float LengthSquared()

View File

@@ -49,9 +49,9 @@ namespace AssetStudio
public override bool Equals(object other)
{
if (!(other is Vector3 vector3))
if (!(other is Vector3))
return false;
return Equals(vector3);
return Equals((Vector3)other);
}
public bool Equals(Vector3 other)
@@ -79,7 +79,7 @@ namespace AssetStudio
public float Length()
{
return MathF.Sqrt(LengthSquared());
return (float)Math.Sqrt(LengthSquared());
}
public float LengthSquared()

View File

@@ -61,9 +61,9 @@ namespace AssetStudio
public override bool Equals(object other)
{
if (!(other is Vector4 vector4))
if (!(other is Vector4))
return false;
return Equals(vector4);
return Equals((Vector4)other);
}
public bool Equals(Vector4 other)
@@ -93,7 +93,7 @@ namespace AssetStudio
public float Length()
{
return MathF.Sqrt(LengthSquared());
return (float)Math.Sqrt(LengthSquared());
}
public float LengthSquared()

View File

@@ -1,5 +1,8 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
namespace AssetStudio
{
@@ -9,15 +12,13 @@ namespace AssetStudio
public long m_PathID;
public long byteStart;
public uint byteSize;
public int classID;
public ClassIDType type;
public SerializedType serializedType;
public BuildTarget platform;
public SerializedFileFormatVersion m_Version;
public UnityVersion version => assetsFile.version;
public long Remaining => byteStart + byteSize - Position;
public int[] version => assetsFile.version;
public BuildType buildType => assetsFile.buildType;
public ObjectReader(EndianBinaryReader reader, SerializedFile assetsFile, ObjectInfo objectInfo) : base(reader.BaseStream, reader.Endian)
{
@@ -25,7 +26,6 @@ namespace AssetStudio
m_PathID = objectInfo.m_PathID;
byteStart = objectInfo.byteStart;
byteSize = objectInfo.byteSize;
classID = objectInfo.classID;
if (Enum.IsDefined(typeof(ClassIDType), objectInfo.classID))
{
type = (ClassIDType)objectInfo.classID;
@@ -39,12 +39,6 @@ namespace AssetStudio
m_Version = assetsFile.header.m_Version;
}
public void ThrowIfTooLarge(float val)
{
if (val < 0 || val > Remaining)
throw new EndOfStreamException();
}
public void Reset()
{
Position = byteStart;

View File

@@ -1,102 +0,0 @@
using System.IO;
namespace AssetStudio
{
public class OffsetStream : Stream
{
private readonly Stream _baseStream;
private readonly long _length;
private long _offset;
public override bool CanRead => _baseStream.CanRead;
public override bool CanSeek => _baseStream.CanSeek;
public override bool CanWrite => false;
public override long Length => _length > 0
? _length
: _baseStream.Length - _offset;
public override long Position
{
get => _baseStream.Position - _offset;
set => Seek(value, SeekOrigin.Begin);
}
public long BasePosition => _baseStream.Position;
public long Offset
{
get => _offset;
set
{
if (value < 0 || value > _baseStream.Length)
{
throw new IOException($"{nameof(Offset)} is out of stream bound");
}
_offset = value;
Seek(0, SeekOrigin.Begin);
}
}
public OffsetStream(FileReader reader)
{
_baseStream = reader.BaseStream;
Offset = reader.Position;
}
public OffsetStream(Stream stream, long offset, long length)
{
_baseStream = stream;
_length = length;
Offset = offset;
}
public override void Flush() { }
public override int Read(byte[] buffer, int offset, int count)
{
return _baseStream.Read(buffer, offset, count);
}
public override long Seek(long offset, SeekOrigin origin)
{
if (offset > _baseStream.Length)
{
throw new IOException("Unable to seek beyond stream bound");
}
switch (origin)
{
case SeekOrigin.Begin:
_baseStream.Seek(offset + _offset, SeekOrigin.Begin);
break;
case SeekOrigin.Current:
_baseStream.Seek(offset + Position, SeekOrigin.Begin);
break;
case SeekOrigin.End:
_baseStream.Seek(offset + _baseStream.Length, SeekOrigin.Begin);
break;
}
return Position;
}
public override void SetLength(long value)
{
throw new System.NotImplementedException();
}
public override void Write(byte[] buffer, int offset, int count)
{
throw new System.NotImplementedException();
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
_baseStream.Dispose();
}
base.Dispose(disposing);
}
}
}

View File

@@ -7,31 +7,25 @@ namespace AssetStudio
private bool needSearch;
private string path;
private SerializedFile assetsFile;
private long offset;
private long size;
private BinaryReader reader;
public int Size
{
get => (int)size;
set => size = value;
}
public long Offset { get; set; }
public ResourceReader() { }
public int Size { get => (int)size; }
public ResourceReader(string path, SerializedFile assetsFile, long offset, long size)
{
needSearch = true;
this.path = path;
this.assetsFile = assetsFile;
this.Offset = offset;
this.offset = offset;
this.size = size;
}
public ResourceReader(BinaryReader reader, long offset, long size)
{
this.reader = reader;
this.Offset = offset;
this.offset = offset;
this.size = size;
}
@@ -58,12 +52,8 @@ namespace AssetStudio
if (File.Exists(resourceFilePath))
{
needSearch = false;
if (assetsFile.assetsManager.resourceFileReaders.TryGetValue(resourceFileName, out reader))
{
return reader;
}
reader = new BinaryReader(File.OpenRead(resourceFilePath));
assetsFile.assetsManager.resourceFileReaders.TryAdd(resourceFileName, reader);
assetsFile.assetsManager.resourceFileReaders.Add(resourceFileName, reader);
return reader;
}
throw new FileNotFoundException($"Can't find the resource file {resourceFileName}");
@@ -77,29 +67,21 @@ namespace AssetStudio
public byte[] GetData()
{
var binaryReader = GetReader();
lock (binaryReader)
{
binaryReader.BaseStream.Position = Offset;
return binaryReader.ReadBytes((int)size);
}
binaryReader.BaseStream.Position = offset;
return binaryReader.ReadBytes((int)size);
}
public int GetData(byte[] buff, int startIndex = 0)
public void GetData(byte[] buff)
{
int dataLen;
var binaryReader = GetReader();
lock (binaryReader)
{
binaryReader.BaseStream.Position = Offset;
dataLen = binaryReader.Read(buff, startIndex, (int)size);
}
return dataLen;
binaryReader.BaseStream.Position = offset;
binaryReader.Read(buff, 0, (int)size);
}
public void WriteData(string path)
{
var binaryReader = GetReader();
binaryReader.BaseStream.Position = Offset;
binaryReader.BaseStream.Position = offset;
using (var writer = File.OpenWrite(path))
{
binaryReader.BaseStream.CopyTo(writer, size);

View File

@@ -1,6 +1,8 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
namespace AssetStudio
{
@@ -11,14 +13,15 @@ namespace AssetStudio
public string fullName;
public string originalPath;
public string fileName;
public UnityVersion version = new UnityVersion();
public int[] version = { 0, 0, 0, 0 };
public BuildType buildType;
public List<Object> Objects;
public Dictionary<long, Object> ObjectsDic;
public SerializedFileHeader header;
private byte m_FileEndianess;
public string unityVersion = "2.5.0f5";
public BuildTarget m_TargetPlatform = BuildTarget.UnknownPlatform;
public string targetPlatformString;
private bool m_EnableTypeTree = true;
public List<SerializedType> m_Types;
public int bigIDEnabled = 0;
@@ -69,39 +72,16 @@ namespace AssetStudio
}
if (header.m_Version >= SerializedFileFormatVersion.Unknown_7)
{
var versionPos = reader.Position;
var verStr = reader.ReadStringToNull();
if (!UnityVersion.TryParse(verStr, out version))
{
if (assetsManager.Options.CustomUnityVersion == null)
{
Logger.Warning($"Failed to parse Unity version: \"{verStr}\"");
version = new UnityVersion();
return;
}
version = assetsManager.Options.CustomUnityVersion;
reader.Position = versionPos;
reader.ReadBytes(version.ToString().Length + 1);
}
}
else
{
version = new UnityVersion(2, 5, 0);
unityVersion = reader.ReadStringToNull();
SetVersion(unityVersion);
}
if (header.m_Version >= SerializedFileFormatVersion.Unknown_8)
{
var target = reader.ReadInt32();
m_TargetPlatform = (BuildTarget)target;
m_TargetPlatform = (BuildTarget)reader.ReadInt32();
if (!Enum.IsDefined(typeof(BuildTarget), m_TargetPlatform))
{
m_TargetPlatform = BuildTarget.UnknownPlatform;
}
targetPlatformString = version.IsTuanjie && Enum.IsDefined(typeof(TuanjieBuildTarget), target)
? ((TuanjieBuildTarget)target).ToString()
: m_TargetPlatform.ToString();
}
if (header.m_Version >= SerializedFileFormatVersion.HasTypeTreeHashes)
{
@@ -110,8 +90,8 @@ namespace AssetStudio
// Read Types
int typeCount = reader.ReadInt32();
m_Types = new List<SerializedType>();
for (var i = 0; i < typeCount; i++)
m_Types = new List<SerializedType>(typeCount);
for (int i = 0; i < typeCount; i++)
{
m_Types.Add(ReadSerializedType(false));
}
@@ -123,10 +103,10 @@ namespace AssetStudio
// Read Objects
int objectCount = reader.ReadInt32();
m_Objects = new List<ObjectInfo>();
Objects = new List<Object>();
ObjectsDic = new Dictionary<long, Object>();
for (var i = 0; i < objectCount; i++)
m_Objects = new List<ObjectInfo>(objectCount);
Objects = new List<Object>(objectCount);
ObjectsDic = new Dictionary<long, Object>(objectCount);
for (int i = 0; i < objectCount; i++)
{
var objectInfo = new ObjectInfo();
if (bigIDEnabled != 0)
@@ -182,8 +162,8 @@ namespace AssetStudio
if (header.m_Version >= SerializedFileFormatVersion.HasScriptTypeIndex)
{
int scriptCount = reader.ReadInt32();
m_ScriptTypes = new List<LocalSerializedObjectIdentifier>();
for (var i = 0; i < scriptCount; i++)
m_ScriptTypes = new List<LocalSerializedObjectIdentifier>(scriptCount);
for (int i = 0; i < scriptCount; i++)
{
var m_ScriptType = new LocalSerializedObjectIdentifier();
m_ScriptType.localSerializedFileIndex = reader.ReadInt32();
@@ -201,8 +181,8 @@ namespace AssetStudio
}
int externalsCount = reader.ReadInt32();
m_Externals = new List<FileIdentifier>();
for (var i = 0; i < externalsCount; i++)
m_Externals = new List<FileIdentifier>(externalsCount);
for (int i = 0; i < externalsCount; i++)
{
var m_External = new FileIdentifier();
if (header.m_Version >= SerializedFileFormatVersion.Unknown_6)
@@ -222,8 +202,8 @@ namespace AssetStudio
if (header.m_Version >= SerializedFileFormatVersion.SupportsRefObject)
{
int refTypesCount = reader.ReadInt32();
m_RefTypes = new List<SerializedType>();
for (var i = 0; i < refTypesCount; i++)
m_RefTypes = new List<SerializedType>(refTypesCount);
for (int i = 0; i < refTypesCount; i++)
{
m_RefTypes.Add(ReadSerializedType(true));
}
@@ -237,6 +217,22 @@ namespace AssetStudio
//reader.AlignStream(16);
}
public void SetVersion(string stringVersion)
{
if (stringVersion != strippedVersion)
{
unityVersion = stringVersion;
var buildSplit = Regex.Replace(stringVersion, @"\d", "").Split(new[] { "." }, StringSplitOptions.RemoveEmptyEntries);
if (buildSplit.Length == 0)
throw new NotSupportedException("Specified Unity version is not in a correct format.\n" +
"Specify full Unity version, including letters at the end.\n" +
"Example: 2017.4.39f1");
buildType = new BuildType(buildSplit[0]);
var versionSplit = Regex.Replace(stringVersion, @"\D", ".").Split(new[] { "." }, StringSplitOptions.RemoveEmptyEntries);
version = versionSplit.Select(int.Parse).ToArray();
}
}
private SerializedType ReadSerializedType(bool isRefType)
{
var type = new SerializedType();
@@ -320,7 +316,7 @@ namespace AssetStudio
}
int childrenCount = reader.ReadInt32();
for (var i = 0; i < childrenCount; i++)
for (int i = 0; i < childrenCount; i++)
{
ReadTypeTree(m_Type, level + 1);
}
@@ -330,7 +326,7 @@ namespace AssetStudio
{
int numberOfNodes = reader.ReadInt32();
int stringBufferSize = reader.ReadInt32();
for (var i = 0; i < numberOfNodes; i++)
for (int i = 0; i < numberOfNodes; i++)
{
var typeTreeNode = new TypeTreeNode();
m_Type.m_Nodes.Add(typeTreeNode);
@@ -351,7 +347,7 @@ namespace AssetStudio
using (var stringBufferReader = new BinaryReader(new MemoryStream(m_Type.m_StringBuffer)))
{
for (var i = 0; i < numberOfNodes; i++)
for (int i = 0; i < numberOfNodes; i++)
{
var m_Node = m_Type.m_Nodes[i];
m_Node.m_Type = ReadString(stringBufferReader, m_Node.m_TypeStrOffset);
@@ -381,5 +377,9 @@ namespace AssetStudio
Objects.Add(obj);
ObjectsDic.Add(obj.m_PathID, obj);
}
public bool IsVersionStripped => unityVersion == strippedVersion;
private const string strippedVersion = "0.0.0";
}
}

Some files were not shown because too many files have changed in this diff Show More